Forum Discussion
Exchange 2010 SNAT Persistence iRule on Multiple VLANs
My BIGIP 11000s on V11.2.1 is fronting 16 Exchange 2010 CAS servers for Outlook Anywhere. The virtual server is using SNAT iRule to ensure SNAT IP persistence similar to this:
********
when RULE_INIT {
Use a local array to configure SNAT addresses.
These addresses must be defined in a SNAT pool to ensure TMM
sends gratuitous ARPs during a failover.
In this example, we use three addresses. Replace
these with the IP addresses used in your SNAT Pool.
Follow the pattern of the existing addresses to add more than three.
set static::snat_ips(0) 10.0.0.1
set static::snat_ips(1) 10.0.0.2
set static::snat_ips(2) 10.0.0.3
}
when HTTP_REQUEST {
Calculate the crc32 checksum of the client IP.
Use the modulo of the checksum and the number of SNAT IPs in the array
to select a SNAT IP address.
snat $static::snat_ips([expr {[crc32 [IP::client_addr]] % [array size static::snat_ips]}])
}
********
(These SNAT IPs are also in the SNAT Pool assigned to the VS)
We are now introducing more CAS servers on a different subnet that will be in a different VLAN which will also connect to the BIGIPs. So I will need SNAT IPs for the new subnet to talk to the new CAS servers. The iRule is NOT intelligent enough to choose a SNAT from the same subnet as the chosen pool member. So I edited the above iRule to add new SNATs to a different static variable (NEW_snat_ips) and then an "if" conditional statement to assign a SNAT IP based on the load balanced server's network it belongs to.
Does this look correct? valid? Will it work? (oh, and can the set static commands be consolidated with some type of range command?)
********
when RULE_INIT {
set static::snat_ips(0) 10.1.1.138
set static::snat_ips(1) 10.1.1.139
set static::snat_ips(2) 10.1.1.140
set static::snat_ips(3) 10.1.1.141
set static::snat_ips(4) 10.1.1.142
set static::snat_ips(5) 10.1.1.143
set static::NEW_snat_ips(0) 10.2.2.225
set static::NEW_snat_ips(1) 10.2.2.226
set static::NEW_snat_ips(2) 10.2.2.227
set static::NEW_snat_ips(3) 10.2.2.228
set static::NEW_snat_ips(4) 10.2.2.229
set static::NEW_snat_ips(5) 10.2.2.230
}
when HTTP_REQUEST {
if {
IP::addr [LB::server addr] starts_with "10.1.1" }
{
snat $static::snat_ips([expr {[crc32 [IP::client_addr]] % [array size static::snat_ips]}])
}
else {
snat $static::NEW_snat_ips([expr {[crc32 [IP::client_addr]] % [array size static::snat_ips]}])
}
}
********
3 Replies
- nitass
Employee
when HTTP_REQUEST {i understand this should be LB_SELECTED event because pool member has not yet been selected in HTTP_REQUEST event.
- Brad_OtlinRet. Employee
actually, nitass, the iRule in the v4.4 deployment guide http://www.f5.com/pdf/deployment-gu...010-dg.pdf says to use "when CLIENT_ACCEPTED". However, devcentral article https://devcentral.f5.com/wiki/iRul...tence.ashx states "For instance, if using HTTP and OneConnect, you could change CLIENT_ACCEPTED to HTTP_REQUEST" We've had to change ours to HTTP_REQUEST due to some OneConnect issues we were having that has since beeen resolved. This was recommeneded by F5 Support.
But, my main concern is how to assign different SNAT IPs based on the pool member selected. So I am hoping this modified iRule works?
********
when RULE_INIT {
set static::snat_ips(0) 10.1.1.138
set static::snat_ips(1) 10.1.1.139
set static::snat_ips(2) 10.1.1.140
set static::snat_ips(3) 10.1.1.141
set static::snat_ips(4) 10.1.1.142
set static::snat_ips(5) 10.1.1.143
set static::NEW_snat_ips(0) 10.2.2.225
set static::NEW_snat_ips(1) 10.2.2.226
set static::NEW_snat_ips(2) 10.2.2.227
set static::NEW_snat_ips(3) 10.2.2.228
set static::NEW_snat_ips(4) 10.2.2.229
set static::NEW_snat_ips(5) 10.2.2.230
}when HTTP_REQUEST {
if {
[$IP::addr [LB::server addr] starts_with '10.1.1']}
{
snat $static::snat_ips(expr {[crc32 [IP::client_addr]] % [array size static::snat_ips]})
}
else {
snat $static::NEW_snat_ips(expr {[crc32 [IP::client_addr]] % [array size static::snat_ips]})
}
}********
- nitass
Employee
sorry i did not say clearly. actually, what i meant is LB::server addr commamnd. i understand it may return null in HTTP_REQUEST event because pool member has not yet been determined in that event.
e.g.[root@ve10:Active] config b rule myrule list rule myrule { when HTTP_REQUEST { log local0. "" log local0. "client [IP::client_addr]:[TCP::client_port] server [LB::server addr]" } when LB_SELECTED { log local0. "client [IP::client_addr]:[TCP::client_port] server [LB::server addr]" } when HTTP_RESPONSE { log local0. "conn [IP::client_addr]:[TCP::client_port] > [clientside {IP::local_addr}]:[clientside {TCP::local_port}] > [IP::remote_addr]:[TCP::remote_port]" } } [root@ve10:Active] config tail -f /var/log/ltm Mar 8 08:39:13 local/tmm info tmm[22185]: Rule myrule : Mar 8 08:39:13 local/tmm info tmm[22185]: Rule myrule : client 172.28.19.251:42612 server Mar 8 08:39:13 local/tmm info tmm[22185]: Rule myrule : client 172.28.19.251:42612 server 200.200.200.111 Mar 8 08:39:13 local/tmm info tmm[22185]: Rule myrule : conn 172.28.19.251:42612 > 172.28.19.252:80 > 200.200.200.111:80 Mar 8 08:39:14 local/tmm info tmm[22185]: Rule myrule : Mar 8 08:39:14 local/tmm info tmm[22185]: Rule myrule : client 172.28.19.251:42613 server Mar 8 08:39:14 local/tmm info tmm[22185]: Rule myrule : client 172.28.19.251:42613 server 200.200.200.101 Mar 8 08:39:14 local/tmm info tmm[22185]: Rule myrule : conn 172.28.19.251:42613 > 172.28.19.252:80 > 200.200.200.101:80
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)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