Forum Discussion
Combine IF and SWITCH to apply SNAT based on destination IP and/or TCP port
I use an irule applied to a L4 performance forwarding virtual server to serve as a sort of selective NAT based on a couple different criteria (in most cases just the TCP port for which I use a switch statement). I have an edge use case for a specific host that I need to match via IP however I am concerned that matches lower in the rule will override.(and also just looking for a more elegant way to perform this function).
My switch statement is matching TCP ports because I don't always know the destination network but I do know the sending port.
My irule :
if destination IP is 10.10.10.10 SNAT to .15 regardless of TCP port
when CLIENT_ACCEPTED {if { [IP::addr [IP::local_addr] equals 10.10.10.10/32] }
{log local0. "Export Server [IP::client_addr] sending outbound connection to [IP::local_addr]:[TCP::local_port], applying SNAT 10.10.70.15"
snat 10.10.70.15 }
if tcp port matches anything in the switch list use .70 snat
switch [TCP::local_port] {
"104" -
"4000" -
"12000" -
"7400" {
snat 10.10.70.70
log local0. “Host with IP address [IP::client_addr] sending outbound connection to [IP::remote_addr]:[TCP::local_port], applying SNAT 10.10.70.70”
}
otherwise don't do anything...
default {
}
}
}
So in this case if a connection hits my L4 VS/Irule with a destination of 10.10.10.10 and tcp port 104 will I get the first SNAT from within the IF statement, or will it continue to match and apply the second SNAT from withing the SWITCH statement?
The above irule does pass syntax check but unfortunately I do not have a lab environment to test with. Alas!
Any input and guidance is very much appreciated.
-Noah
when CLIENT_ACCEPTED { if { [IP::addr [IP::local_addr] equals 10.10.10.10/32] } { switch [TCP::local_port] { "104" - "4000" - "7400" - "12000" { snat 10.10.70.70 } default { snat 10.10.70.15 } } } }
At this point, though, you're getting close to wanting to use a datagroup instead of switch.
- Vijay_ECirrus
So in this case if a connection hits my L4 VS/Irule with a destination of 10.10.10.10 and tcp port 104 will I get the first SNAT from within the IF statement, or will it continue to match and apply the second SNAT from withing the SWITCH statement?
2nd SNAT - 10.10.70.70
You can try using some kind of "return" statement if you want to stop processing after 1st match or you can change the order of matching depending on your requirements.
If you want the port to take precedence, you can use it above the IP address check. For example: 10.10.10.10:104 - which SNAT do you want to use ?
- AJ_01_135899Cirrostratus
Both of the statements would run. The return would end processing at that point.
If you want the switch statement to run, but not if the IP address matches 10.10.10.10, why not add an if statement to your switch statement? There are probably more elegant ways to accomplish this:
if destination IP is 10.10.10.10 SNAT to .15 regardless of TCP port when CLIENT_ACCEPTED {if { [IP::addr [IP::local_addr] equals 10.10.10.10/32] } {log local0. "Export Server [IP::client_addr] sending outbound connection to [IP::local_addr]:[TCP::local_port], applying SNAT 10.10.70.15" snat 10.10.70.15 } if tcp port matches anything in the switch list use .70 snat switch [TCP::local_port] { "104" - "4000" - "12000" - "7400" { if {[IP::addr [IP::local_addr] not 10.10.10.10/32] }{ snat 10.10.70.70 log local0. “Host with IP address [IP::client_addr] sending outbound connection to [IP::remote_addr]:[TCP::local_port], applying SNAT 10.10.70.70” } } otherwise don't do anything... default { } } }
- noahshelton_237Nimbostratus
This makes more sense, I'll test it.
I always forget about checking for a negative match in my logic.
- noahshelton_237Nimbostratus
Ugh... the only operand for IP:addr looks to be 'equals'....
- AJ_01_135899Cirrostratus
Hmm, that's unfortunate. Mabye ne, not equals or != ? If none of those work I'd just flip the logic around.
if destination IP is 10.10.10.10 SNAT to .15 regardless of TCP port when CLIENT_ACCEPTED {if { [IP::addr [IP::local_addr] equals 10.10.10.10/32] } {log local0. "Export Server [IP::client_addr] sending outbound connection to [IP::local_addr]:[TCP::local_port], applying SNAT 10.10.70.15" snat 10.10.70.15 } if tcp port matches anything in the switch list use .70 snat switch [TCP::local_port] { "104" - "4000" - "12000" - "7400" { if {[IP::addr [IP::local_addr] equals 10.10.10.10/32] }{ do nothing } else{ snat 10.10.70.70 log local0. “Host with IP address [IP::client_addr] sending outbound connection to [IP::remote_addr]:[TCP::local_port], applying SNAT 10.10.70.70” } } otherwise don't do anything... default { } } }
- ekaleidoCirrus
when CLIENT_ACCEPTED { if { [IP::addr [IP::local_addr] equals 10.10.10.10/32] } { switch [TCP::local_port] { "104" - "4000" - "7400" - "12000" { snat 10.10.70.70 } default { snat 10.10.70.15 } } } }
At this point, though, you're getting close to wanting to use a datagroup instead of switch.
- noahshelton_237Nimbostratus
Yes just setup a data group to match ip:tcp port with a snat.... I'm waiting on a window to test with so I'll report back what I finally get working.
- ekaleido_26616Cirrocumulus
when CLIENT_ACCEPTED { if { [IP::addr [IP::local_addr] equals 10.10.10.10/32] } { switch [TCP::local_port] { "104" - "4000" - "7400" - "12000" { snat 10.10.70.70 } default { snat 10.10.70.15 } } } }
At this point, though, you're getting close to wanting to use a datagroup instead of switch.
- noahshelton_237Nimbostratus
Yes just setup a data group to match ip:tcp port with a snat.... I'm waiting on a window to test with so I'll report back what I finally get working.
Recent Discussions
Related Content
* 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