Forum Discussion
Manuel_Gabaldon
Nimbostratus
Apr 29, 2008Outbound SNAT matching inbound Virtual Servers
Hi,
Our customers are always asking us for a load balancing solution that provides bi-directional correspondence between a virtual server address (inbound) and the SNAT address being applied to the real servers belonging to its pool when going outside through our wildcard outgoing virtual server.
We've been configuring two objects for every virtual server that our customer asks us to define:
- A virtual server listening on the public interface (i.e. 4.4.4.4:80) with a virtual server pool (i.e 2.2.2.10:80 and 2.2.2.11:80)
- An SNAT that translates traffic coming from the pool (2.2.2.10 and 2.2.2.11) and replaces source IP with the virtual server address (4.4.4.4)
I'm trying to figure out a dynamic way of implementing the SNAT with an iRule, by querying the configuration, but I consider it unelegant. I think it could be done by querying if which pool belongs the source IP to, and then querying which virtual server belongs to, and then apply the SNAT, but I can't find a way of doing it.
Has anybody tried to address this issue with an iRule?
Thanks in advance.
11 Replies
- The_Bhattman
Nimbostratus
You could create a simple irule applied to the virtual that is handling your outbound connections.
First declare a class. You can do this on the GUI but the following is the code representationclass dg_internal { 2.2.2.10/32 2.2.2.11/32 }
The following is the irule that calls up the class objectwhen CLIENT_ACCEPTED { if { [matchclass [IP::client_addr] equals $::dg_internal]} { snat automap } }
You would apply this is on the virtual server that handles the outbound connection for the pool members. The autosnat is something you can use based on the floatinging address of the outbound facing interface. However you could replace it with something more specific like "snat 4.4.4.4"
Here is a similiar article Click here - Manuel_Gabaldon
Nimbostratus
Yeah, I've already thought about that solution, but it's not exactly what I'm looking for.
I want the SNAT configuration to be automatic, so there isn't any need for our customer to define SNAT rules or classes, just the virtual servers.
The least horrible way of doing it would be something like this:
when CLIENT_ACCEPTED {
for each pool in the list {
for each pool member in the pool {
if {client IP address equals pool member}{
set variable found_pool pool}
}
}
for each virtual server in the list {
if {virtual server pool equals found_pool} {
set variable found_vs virtual server
snat found_vs}
}
}
I've seen that iControl does support queries that return the pools referring a node, and the virtual servers referring a pool, but I suppose that this isn't that easy with iRules, and it can be quite CPU-intensive.
Any other thoughts about it? Maybe by using the Universal persistence table, but it wouldn't work exactly as expected.
Regards. - Deb_Allen_18Historic F5 AccountThere really is no way in iRules to enumerate all pools and their members. You can get the list of members of a known pool name using the "active_members" command with the "-list" parameter. (Click here)
As cmbhatt mentions, you would need to create some relationship in the configuration between the source and the desired address translation for an outbound flow. The most reliable way is the class list he mentioned. You can alternatively build origin SNATs containing all the servers associated with each VS address, but they would have to be deleted & re-added if the list changes.
The simplest way would be if each customer has their own VLAN - you can apply a SNAT to only a specific VLAN, and it will translate all traffic arriving on that VLAN to the SNAT address.
HTH
/deb - Manuel_Gabaldon
Nimbostratus
Yeah, certainly there isn't a good way. I've thought of another way, however. What about using the Universal Persistence Table as a way of creating these entries dynamically?
I mean, we need outgoing traffic to behave just like it was coming out from the virtual server the node belongs to. If we use the UP table (or a modifiable class) to create entries like "node address:virtual server address" whenever an incoming connection occurs and we let it there, the BIG-IP will "learn" how to do the correspondent SNAT properly.
I know that this can fail sometimes, but it seems elegant, doesn't it? - Deb_Allen_18Historic F5 AccountWell, I did write a rule that did something like that for pool member selection to push outbound connections over the same proxy the client is already using for an inbound connection.
That might work. Let me see if I can find it.
/deb - Deb_Allen_18Historic F5 AccountOK, give this a shot. (code is untested, but I think the concept will work)
Apply this rule to your inbound virtual server -- inbound requests set & update the persistence entry with 24 hr timeout keyed on server IP:
Apply this rule to your outbound virtual server -- outbound requests read & update an existing persistence entry, and apply the appropriate SNAT:when CLIENT_ACCEPTED { set vip [IP::local_addr] } when SERVER_CONNECTED { session add uie {[IP::server_addr] any virtual} $vip 86400 log local0. "Session table record added for [IP::server_addr] via VS $vip" }when CLIENT_ACCEPTED { set snat_ip "[session lookup uie {[IP::client_addr] any virtual}]" if { $snat_ip != 0 }{ If session table entry exists, use it & refresh to update timeout log local0. "Session table record found for server [IP::client_addr]. SNAT address will be $snat_ip" snat $snat_ip session add uie {[IP::client_addr] any virtual} $snat_ip 86400 } else { log local0. "No session table record found for server [IP::client_addr]." snat ... } }
You would need to take some default SNAT action if the lookup against the session table doesn't return anything. This code assumes you will define a "default" value for the SNAT address if there is no session table entry, and that you wouldn't want to create a long-lived persistence record reflecting that "decision". Using that logic, if the "default" SNAT value is chosen, it may later SNAT new connections (mid-session) to the "correct" address if the session table is updated by another connection. - Daniel_55334
Altostratus
I can configure the VS IP address (like 4.4.4.4 as in your case) as the SNAT address of the real servers for outbound connections, without using irule. And seems that everything is working fine. Must I need an irule? Or do I miss something? - Deb_Allen_18Historic F5 AccountThat's definitely the easiest way for most deployments, but mgabaldon was looking for a solution that didn't require any configuration as servers and virtuals come & go:I want the SNAT configuration to be automatic, so there isn't any need for our customer to define SNAT rules or classes, just the virtual servers.
/deb - Daniel_55334
Altostratus
I see. Thanks. - Bilal_9919
Nimbostratus
Is there any way of creating a SNAT that will use source IP address as the VIP used for external connection?
BH
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