Forum Discussion
nitass
Feb 20, 2015Employee
Is there any simple way to do this or do I need to create an Irule that will create SNAT entries on the fly and keep track of which ones are already set up?
the simplest way is to use cgnat persistence.
sol14823: Overview of CGNAT Persistence
https://support.f5.com/kb/en-us/solutions/public/14000/800/sol14823.htmlanyway, you can use irule to assign snat ip on the fly and keep track it. i think you need at least 3 tables to track it; one stores client ip (key) and snat ip (value), next keeps snat ip which is in use and the last one records all incoming client ports (snat ip can be released after all connections from client are closed). also, you have to refresh (touch) table entry to make sure it is not timeout.
here is my testing. please be noted that it may not be fully correct.
e.g.
configuration
root@(ve11b)(cfg-sync In Sync)(Active)(/Common)(tmos) list ltm virtual bar
ltm virtual bar {
destination 172.28.24.10:23
ip-protocol tcp
mask 255.255.255.255
pool foo
profiles {
fastL4 { }
}
rules {
qux
}
source 0.0.0.0/0
vs-index 6
}
root@(ve11b)(cfg-sync In Sync)(Active)(/Common)(tmos) list ltm snatpool mysnat_pool
ltm snatpool mysnat_pool {
members {
200.200.200.22
200.200.200.33
200.200.200.44
}
}
root@(ve11b)(cfg-sync In Sync)(Active)(/Common)(tmos) list ltm rule qux
ltm rule qux {
when RULE_INIT {
set static::snatpool "mysnat_pool"
set static::snatpool_list [eval members -list $static::snatpool]
set static::snatip_inuse "snatip_inuse"
set static::client_inuse "client_inuse"
set static::table_timeout 30
}
when CLIENT_ACCEPTED {
set snatip [table lookup [IP::client_addr]]
if { $snatip eq "" } {
foreach snatpool_mbr $static::snatpool_list {
set snatip [lindex $snatpool_mbr 0]
if { [table lookup -subtable $static::snatip_inuse $snatip] eq "" } {
table set [IP::client_addr] $snatip $static::table_timeout
table set -subtable ${static::client_inuse}_[IP::client_addr] [TCP::client_port] 1 $static::table_timeout
table set -subtable $static::snatip_inuse $snatip 1 $static::table_timeout
set monitor_id [\
after [expr {($static::table_timeout * 1000) / 2}] -periodic {
log local0. "[IP::client_addr]:[TCP::client_port]: touch"
table lookup [IP::client_addr]
table lookup -subtable ${static::client_inuse}_[IP::client_addr] [TCP::client_port]
table lookup -subtable $static::snatip_inuse $snatip
}\
]
log local0. "[IP::client_addr]:[TCP::client_port]: new client [IP::client_addr]. snat ip $snatip is used."
snat $snatip
return
}
}
event CLIENT_CLOSED disable
log local0. "[IP::client_addr]:[TCP::client_port]: no snat ip is available for [IP::client_addr]. connection is rejected."
reject
} else {
log local0. "[IP::client_addr]:[TCP::client_port]: existing client [IP::client_addr]. snat ip $snatip is used."
table set -subtable ${static::client_inuse}_[IP::client_addr] [TCP::client_port] 1 $static::table_timeout
table lookup -subtable $static::snatip_inuse $snatip
set monitor_id [\
after [expr {($static::table_timeout * 1000) / 2}] -periodic {
log local0. "[IP::client_addr]:[TCP::client_port]: touch"
table lookup [IP::client_addr]
table lookup -subtable ${static::client_inuse}_[IP::client_addr] [TCP::client_port]
table lookup -subtable $static::snatip_inuse $snatip
}\
]
snat $snatip
}
}
when CLIENT_CLOSED {
if { [table keys -subtable ${static::client_inuse}_[IP::client_addr] -count] == 1 } {
log local0. "[IP::client_addr]:[TCP::client_port]: [IP::client_addr] is closed. snat ip [table lookup [IP::client_addr]] is released."
table delete -subtable ${static::client_inuse}_[IP::client_addr] -all
table delete -subtable $static::snatip_inuse $snatip
table delete [IP::client_addr]
} else {
log local0. "[IP::client_addr]:[TCP::client_port]: [IP::client_addr]:[TCP::client_port] is closed."
after cancel $monitor_id
table delete -subtable ${static::client_inuse}_[IP::client_addr] [TCP::client_port]
}
}
}
/var/log/ltm
[root@ve11b:Active:In Sync] config tail -f /var/log/ltm
Feb 20 15:20:31 ve11b info tmm1[14140]: Rule /Common/qux : 172.28.24.1:38318: new client 172.28.24.1. snat ip 200.200.200.44 is used.
Feb 20 15:20:46 ve11b info tmm1[14140]: Rule /Common/qux : 172.28.24.1:38318: touch
Feb 20 15:21:01 ve11b info tmm1[14140]: Rule /Common/qux : 172.28.24.1:38318: touch
Feb 20 15:21:03 ve11b info tmm[14140]: Rule /Common/qux : 172.28.24.1:38319: existing client 172.28.24.1. snat ip 200.200.200.44 is used.
Feb 20 15:21:16 ve11b info tmm1[14140]: Rule /Common/qux : 172.28.24.1:38318: touch
Feb 20 15:21:18 ve11b info tmm[14140]: Rule /Common/qux : 172.28.24.1:38319: touch
Feb 20 15:21:24 ve11b info tmm1[14140]: Rule /Common/qux : 172.28.24.15:39032: new client 172.28.24.15. snat ip 200.200.200.33 is used.
Feb 20 15:21:31 ve11b info tmm1[14140]: Rule /Common/qux : 172.28.24.1:38318: touch
Feb 20 15:21:33 ve11b info tmm[14140]: Rule /Common/qux : 172.28.24.1:38319: touch
Feb 20 15:21:39 ve11b info tmm1[14140]: Rule /Common/qux : 172.28.24.15:39032: touch
Feb 20 15:21:44 ve11b info tmm1[14140]: Rule /Common/qux : 172.28.24.1:38318: 172.28.24.1:38318 is closed.
Feb 20 15:21:48 ve11b info tmm[14140]: Rule /Common/qux : 172.28.24.1:38319: touch
Feb 20 15:21:50 ve11b info tmm1[14140]: Rule /Common/qux : 172.28.24.15:39032: 172.28.24.15 is closed. snat ip 200.200.200.33 is released.
Feb 20 15:21:52 ve11b info tmm[14140]: Rule /Common/qux : 172.28.24.1:38319: 172.28.24.1 is closed. snat ip 200.200.200.44 is released.