Forum Discussion
Roark_Fisher_29
Nimbostratus
May 01, 2006Outbound routing based upon source IP
I hope the intellects here may be able to help me with a confusing setup. I worked for 3 days with F5 tech support on this and they finally sent me here.
I have about a dozen T1 lines that come into a switch and the switch connects to my "external" VLAN port.
On the "internal" side my systems use SNAT to start an outbound connection.
The problem is that the outbound connections always use the default route. But I need them to route through the T1 that matches their SNAT address.
As an example. I have a system with an address of 10.10.10.10. It starts an outbound connection and gets a SNAT address of 62.2.2.10. I need to create an iRule that will look at this the SNAT address and route the traffic down the 62.x.x.x T1 and not through the default address.
Again, I am not trying to route based upon the destination address. Rather, I need to choose the correct router based upon the source address. Otherwise, if the wrong router is chosen, the packets get dropped.
If any of you F5 guru's know how to create an iRule to do this, I would greatly appreciate the help.
Thanks.
-Roark Fisher
15 Replies
- JRahm
Admin
I am doing this in the lab currently:when CLIENT_ACCEPTED { if { [IP::addr [IP::client_addr] equals 192.168.1.100/255.255.255.255] } { node 10.10.1.5 Firewall 1 } elseif { [IP::addr [IP::client_addr] equals 192.168.2.100/255.255.255.255] } { node 10.10.2.5 Firewall 2 } }
The virtual server should be network, address and mask 0.0.0.0. Service port should be all ports. Make sure you disable port and address translation, and associate the above rule. - JRahm
Admin
With a dozen T1's, I'd recommend using a class instead of 12 if statements:class snat_gw { "snat_IP1 gw_IP1" "snat_IP2 gw_IP2" "snat_IP3 gw_IP3" "........ ......" "snat_IP12 gw_IP12" } when CLIENT_ACCEPTED { set my_gw [findclass [IP::client_addr] $::snat_gw " "] if { $my_gw ne "" } { node $my_gw } else { discard } } - Roark_Fisher_29
Nimbostratus
Wow! I appreciate your testing this as this is very big to a very big project. And I was amazed to get such a good response so quickly. Sadly, I have to claim being dumb with iRules. I tried to setup the second example you gave as it was (to me) the clearest and easiest to understand.
I created a new iRule and went for a basic test of one translation (if the SNAT address is 62.2.2.10, then use 62.2.2.1 as the gateway):
class snat_gw {
"62.2.2.10 62.2.2.1"
}
when CLIENT_ACCEPTED {
set my_gw [findclass [IP::client_addr] $::snat_gw " "]
if { $my_gw ne "" } {
node $my_gw
} else { discard }
}
When I clicked on "Finished", it gave me the error:
01070151:3: Rule [Test_SMTP_SNAT] error:
line 1: [undefined procedure: class] [class snat_gw {
"62.2.2.0 62.2.2.1"
}
Sorry for not understanding the basics of iRules yet. This is my first experience with F5s and this issue came up quickly.
Do I need to add something else to get it to understand the reference to the "class" procedure? Can I add a subnet to my entry (i.e. "62.2.2.0/255.255.255.0 62.2.2.1) so that the entire network will use this default gateway.
Again, thank you for your help. This is huge for us if we can get it working.
-Roark Fisher - JRahm
Admin
The class isn't part of the iRule, it needs to be added either to the bigip.conf file (don't forget to do a bigpipe load after editing the file)at the CLI or under the datagroups tab on the irules tab.
Also, I'd edit your post and pull out your real IP addresses if they are in fact real. This site is freely available to anyone, so you never know who's watching... - Roark_Fisher_29
Nimbostratus
Thank you. I think this is close to working.
I added the following to the /config/bigip.conf file (fake IPs given):
class snat_gw {
"62.2.2.10 62.2.2.1"
}
I did a "bigpipe load" and then verified that the new class showed up in the datagroups portion of the iRules.
I then created the following iRule (Test_SNAT):
when CLIENT_ACCEPTED {
set my_gw [findclass [IP::client_addr] $::snat_gw " "]
if { $my_gw ne "" } {
node $my_gw
} else { discard }
}
and it created successfully. So far so good.
Things broke as I tried to associate the iRule.
Here is some further clarification of what I have.
I have a Host Virtual Server that redirects traffic on port 80 to 62.2.2.10 to the internal system (10.10.10.10).
I have a SNAT rule that converts 10.10.10.10 to 62.2.2.10.
Now the Host Virtual Server on port 80 works great and the web pages serve up properly.
The problem is if I want to send email out from 10.10.10.10. Since the email originates from 10.10.10.10, I need it to SNAT to a real address and then route through the correct gateway. Right now it is using the default gateway and the packets get dropped.
I did not find a place where I could associate the iRule with the SNAT. I tried to associate the iRule to the Host Virtual Server but then it stopped serving web pages so I had to take it out.
Can you tell me how to associate the iRule with the SNAT? Or do I have to create a different type of virtual server?
Thanks again for your help. - JRahm
Admin
The iRule should be associated to the 0.0.0.0/0 network forwarding virtual you created. Also, I'd like to note that I lock down this virtual to only the internal VLAN's, so external traffic won't be forwarded to internal networks. I'd be curious if the iRule is being triggered before/after the nat occurs? Might add some logging to find out:when CLIENT_ACCEPTED { set my_gw [findclass [IP::client_addr] $::snat_gw " "] if { $my_gw ne "" } { log "My gateway is $my_gw and my client IP is [IP::client_addr]" node $my_gw } else { log "My client IP is [IP::client_addr]" discard } }
The logs are in /var/log/ltm - Roark_Fisher_29
Nimbostratus
Fantastic! Starting to see some things working. I still have a few follow-up questions to get some last parts working. (for those following along at home and who may, like me, not be fully F5 literate, I will put what I have done at the end of this post).
I am now able to get an outbound connection and have it route properly.
I first had to create the Virtual Server you mentioned. I then had to change the class from "snat_address snat_gateway" to "pre_snat_address snat_gateway":
class snat_gw {
"10.10.10.10 62.2.2.1"
}
It then worked!!!!!!!!!!!!!!!!!!!!!
My questions are 3. I am overjoyed that this is working. My questions are on ways to simplify things as we have hundreds of these types of situations. The last admin never noticed that half our routing was broken and I am trying to clean it up after-the-fact.
1. Is there a way I can change this to trigger off of networks instead of just host IPs? (i.e. "10.10.10.0/255.255.255.0 62.2.2.1)?
2. Is there a way to get it to trigger after the SNAT instead of before?
3. All of the systems that used the default router broke when I applied the rule as I did not have all of my sytems and routers defined (we have a lot). Is there a way to define a default gateway in the iRule?
As for the logs, it looks as if the iRule is triggering before NAT. A sample from the logs is (IP addresses modified to protect the innocent):
May 2 14:37:16 tmm tmm[3038]: 01220002:6: Rule Test_SNAT :
My client IP is 10.10.30.10
May 2 14:37:21 tmm tmm[3038]: 01220002:6: Rule Test_SNAT :
My client IP is 10.0.0.90
May 2 14:37:21 tmm tmm[3038]: 01220002:6: Rule Test_SNAT :
My gateway is 62.2.2.1 and my client IP is 10.10.10.10
For those following along, a fuller description of the steps I took is:
1. I created a Pool that contained the T1 router I wanted to use. I figure I will expand this pool to include all of my T1 routers (and my default router), but for now I only put in one.
2. I created a Network Forwarding Virtual Server:
o Virtual Servers -> Create
Type: Network
Address: 0.0.0.0
Mask: 0.0.0.0
Service Port: 0 (* All ports)
VLAN Traffic: enables on (internal only)
Address Translation: unchecked
Port Translation: unchecked
Default Pool: The T1 router pool I created in step 1
iRules: set to use my Test_SNAT irule
3. I setup a SNAT rule to translate 10.10.10.10 to 62.2.2.10
4. I then watched the logs and saw that my gateway was never being set. So, I changed the class and put in my pre-SNAT address of 10.10.10.10. At this point, the outbound routing started to work. - JRahm
Admin
1. [IP::addr [IP::remote_addr] equals "x.x.x.0/24"] will match your client IP to anything in the specified network and mask. It might be good to assign snat based on client network, then assign gw based on snat, but the developers could have better ideas.
2. A good question for the developers
3. Instead of discard in the else { } statement, add a default gw
....
else {
node default_gw_IP
}
} - Roark_Fisher_29
Nimbostratus
Thank you for your excellent help on this!!!! This is now working as expected. I really appreciate your help in getting through this. -Roark - Rodrigo_EV_7869
Nimbostratus
I'd like to propose another scenario we got in a customer:
Suppose we have the Wildcard Virtual Server (0.0.0.0:0) pointed to a Default Gateway Pool with my two ISP routers (200.1.0.1 and 200.2.0.1).
I want the outbound connection for specific internal servers to use another IP other than SelfIP/SNAT Automap (let's say Static SNAT Addresses 200.1.0.10 and 200.2.0.10).
With the iRule described above I can get this result, but the destination router will be selected by the SNAT, not leveraging the router/link status in a Link Controller Box.
The best would be to let the pool select the better router based on its metrics and then execute the iRule to SNAT to the proper static address.class class_static_snat_servers { host 10.0.0.10 host 10.0.0.11 } class class_static_snat_gateways { "200.1.0.1 200.1.0.10" "200.2.0.1 200.2.0.10" } when CLIENT_ACCEPTED { set static_snat_server [IP::client_addr] } when LB_SELECTED { if {$::static_snat_server eq $::class_static_snat_servers]} { set selected_gateway [findclass [LB::server addr] $::class_static_snat_gateways " "] if { $selected_gateway ne "" } { snat $selected_gateway } } }
Or, in a short way:when LB_SELECTED { if {[matchclass [IP::client_addr] eq $::class_static_snat_servers]} { set my_gw [findclass [LB::server addr] $::class_static_snat_gateways " "] if { $my_gw ne "" } { snat $my_gw } } }
I didn't tested this iRules, but this second could result in an error: the [IP::client_addr] variable could have already being translated by the SNAP Automap, not fetching the $::class_static_snat_servers correctly.
Then we can start mapping single internal servers to single snat addresses with little modifications in this iRule.
Am I right in my logic?
Thanks,
-Rodrigo
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects
