Forum Discussion
Casa_Henry_1360
Nimbostratus
Feb 26, 2009Snat for mail servers
I am new to Irules and TCL. I have a need to create SNATs for my mail servers. What I am looking for is the syntax for parsing a field. So if I have a series of addresses defined as hosts
class hosts {
192.168.16.112 198.212.10.112
192.168.16.108 198.212.10.108
}
I would like to inspect it and if the address is the 1st field then the SNAT will be the second field.
Any help would be greatly appreciated.
16 Replies
- hoolio
Cirrostratus
You can use the findclass (Click here) command to return the matching field. The first example on the wiki page is pretty close to what you're trying to do.
Aaron - Deb_Allen_18Historic F5 Accounthmmm, I'm gonna go out on a limb here & suggest an iRule is not the answer here. Unless you need the iRule to do something else, I'd just create one-to-one SNATs in the GUI instead & enable them on the server vlan...
/d - Casa_Henry_1360
Nimbostratus
I agree, except that because of some other configuration issues that wont work for me. Basically I will be using forwarding servers to my firewall. The concern is that there would be leakage using the 1 to 1 SNATS - Deb_Allen_18Historic F5 AccountWhether you use a simple iRule as mentioned in your original post to map the origin to the SNAT addr, or define 1-1 SNATs, the end result (src addr of the egress packet based on src addr of ingress packet) will be the same.
You might need the iRule to only SNAT under certain conditions, such as traffic bound for internal destinations only. In that case, you can condition the SNAT & use a class like the one you've created. The class would be type String, and an iRule to be applied to a wildcard forwarding VS would have the following logic:
The direction is outbound from the servers, so the server in this case is the client, and remote_addr is the server address. Because it's a wildcard virtual server, local_addr is the endpoint destination address. So in this comparison you would replace the 192.168 addr with the subnet your servers that should be SNAT'd is on.when CLIENT_ACCEPTED { if {[IP::addr [IP::local_addr] equals 192.168.1.0/24] }{ set snat_addr [findclass [IP::remote_addr] $::hosts " "] if {!($snat_addr eq "") }{ snat $snat_addr } } }
If more than one dest subnet requires SNAT, or if you want to specify only certain addresses, you could do the comparison to more destinations by using another class with matchclass in the first condition.
HTH
/d - Deb_Allen_18Historic F5 AccountThe direction is outbound from the servers, so the server in this case is the client, and remote_addr is the server address. Because it's a wildcard virtual server, local_addr is the endpoint destination address. So in this comparison you would replace the 192.168 addr with the subnet your servers that should be SNAT'd is on.
whoops, I so didn't say that right -- see, it can be confusing! This instead:So in this comparison you would replace the 192.168 addr with the destination subnet to which the traffic should be SNAT.
/d - Casa_Henry_1360
Nimbostratus
Thanks for the help so far. I dont want to nat everything on that network, just specific hosts. I found the "findclass" example and was going to use that. So I have
class dest_pairs {
"192.168.16.112 198.212.10.112"
"192.168.16.108 198.212.10.108"
"192.168.16.109 198.212.10.109"
"192.168.16.117 198.212.10.117"
"192.168.16.118 198.212.10.118"
}
when CLIENT_ACCEPTED {
set my_snat [findclass [IP::client_addr] $::dest_pairs " "]
if { $my_snat ne "" } {
snat $my_snat
}
}
However when I try to compile it I get an error
"[undefined procedure class][class dest_pairs]" - Ian_SmithRet. EmployeeIt sounds like you need to get your mail servers to send mail from addresses that match your published MX records but maybe don't want them to use those IPs for other (perhapse internal) traffic.
If that is the case, you can use an irule to snat all the traffic from the server IP (the 10.10.x.x in the example) to a given IP (the 172.16.x.x in the example.
If you apply the rule to an existing IP forwarding virtual and you need to have snat automap for non-mail server traffic, make automap the default.when CLIENT_ACCEPTED { switch [ IP::client_addr ] { 10.10.1.1 { snat 172.16.1.1 } 10.10.1.2 { snat 172.16.1.2 } default { snat automap } } }
If you just want to change the address of traffic from the mail servers destined to port 25 (i.e. outbound mail) then you can check the tcp port, then apply the snat only to the mail servers, and forward everything else (with or without a snat).when CLIENT_ACCEPTED { if [ [TCP::local_port] == 25 ] { switch [ IP::client_addr ] { 10.10.1.1 { snat 172.16.1.1 } 10.10.1.2 { snat 172.16.1.2 } default { forward } } } else { forward } } - Deb_Allen_18Historic F5 Accountcasaman:
However when I try to compile it I get an error
"[undefined procedure class][class dest_pairs]"
The class must be defined separately from the iRule. To do so, click on the Data Group Lists tab on the iRules config screen, and create a new class of type String. Enter each address pair separated by space, first the origin address, then the SNAT address.
Then create the iRule that references the class.
In other news, I noticed you removed the destination address condition from my example. If you truly don't need to filter by destination, there is no functional difference whatsoever between this iRule and 1 to 1 SNATs that are enabled on only the server facing VLAN.
I still say unless you need the iRule to do something else, you should use the more efficient and fully supported SNAT configuration instead of the iRule. If you are seeing LTM SNAT traffic that doesn't match the conditions of the SNAT definition, and this iRule does not exhibit the same behaviour, please open a Support case so we can look into that & get it fixed.
HTH
/d - Casa_Henry_1360
Nimbostratus
Again, I apologize for my naivete. Here is the situation. I have the need to have 2 separate networks, lets say 192.168.16 and 192.168.246. Because of PCI compliance these 2 networks cannot speak directly together but all requests need to go to the firewall then back to big ip. Simply creating 1 to 1 snats may cause big ip to respond to the request without it going to the firewall. However I still have the need for outgoing mail to have a natted external address The use of an iRule was the recommended course by F5 support.
To that end I created a virtual server 0.0.0.0:25 to which I would like to apply this iRule.
class dest_pairs {
"192.168.246.150 198.212.12.150"
"192.168.246.151 198.212.12.151"
}
when CLIENT_ACCEPTED {
set my_spool [findclass [IP::client_addr] $::dest_pairs " "]
if { $my_spool ne "" } {
log local0. "$my_spool"}{
snat $my_spool}
}
Based on the info being logged ($my_spool) i do see the external address, but when I check the firewall logs I see the internal address attempting to go out, which suggests that the snat is not being applied.
Again, any help would be appreciated - Casa_Henry_1360
Nimbostratus
I also tried the ismith suggestion using the following:
when CLIENT_ACCEPTED {
if { [TCP::local_port] == 25} {
switch [ IP::client_addr ] {
192.168.246.151 { snat 198.212.12.151 }
192.168.246.150 { snat 198.212.12.150 }
default { forward } {
log local0. "[ IP::client_addr ] snatted"}
}
}
}
This generates the following error:
Mar 16 12:45:55 tmm tmm[1615]: 01220001:3: TCL error: snat_mail - extra switch pattern with no body while executing "switch [ IP::client_addr ] { 192.168.246.151 { snat 198.212.12.151 } 192.168.246.150 { snat 198.212.12.150 } default { forward } { l..."
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
