Technical Forum
Ask questions. Discover Answers.
cancel
Showing results for 
Search instead for 
Did you mean: 

SNAT pool and persistence

swiss2000_13853
Nimbostratus
Nimbostratus
Hi all!

 

 

I have a LTM-setup (10.0.1) with a SNAT Pool containing 5 ip addresses. So each connection uses the next SNAT address (round robin).

 

 

But for persistent connections (source persistence), i'd like the LTM to use always the same SNAT address, and not to change it during the session. Otherwise some of my applications have problems with session management...

 

 

Is there a way to configure the SNAT pool in a way that persistent connection always keep their SNAT address?

 

 

Thanking you in anticipation, regards

 

Marc

 

12 REPLIES 12

hooleylist
Cirrostratus
Cirrostratus
Hi Marc,

 

 

Here is a related post:

 

 

http://devcentral.f5.com/Default.aspx?tabid=53&view=topic&postid=86374&ptarget=86389

 

 

Aaron

hooleylist
Cirrostratus
Cirrostratus
Hi Mark,

 

 

Do you think mapping the source IP address to a SNAT IP would work for you (assign 1/x IP addresses to one SNAT IP)? If so, I can put together an example. Else, the UIE session persistence method would take a bit longer to give an example for.

 

 

Aaron

hooleylist
Cirrostratus
Cirrostratus
Something like this maybe...

  
  when CLIENT_ACCEPTED {  
      Create some snat name to IP variables  
     set snat0_ip 1.1.1.1  
     set snat1_ip 2.2.2.2  
     set snat2_ip 3.3.3.3  
     set snat3_ip 4.4.4.4  
     set snat4_ip 5.5.5.5  
    
      Test with a dummy client IP address  
     set client_ip "10.11.12.13"  
     log local0. "\$client_ip: $client_ip"  
    
      Scan the dummy IP address for each octet  
     scan $client_ip {%[0-9].%[0-9].%[0-9].%[0-9]} a b c d  
     log local0. "result: \[expr {$c % 5}\]: [expr {$c % 5}]"  
    
      Use modulus 5 on the third octet  
     log local0. "Snat command: snat [set "snat[expr {$c % 5}]_ip"]"  
    
      Apply the SNAT IP to this connection  
     snat [set "snat[expr {$c % 5}]_ip"]  
  }  
  

Once you're done testing, you can replace the $client_ip variable with [IP::client_addr]. You could also experiment with using a datagroup to store the SNAT addresses or maybe an array.

Aaron

hooleylist
Cirrostratus
Cirrostratus
Actually, it looks like getfield is a lot more efficient for this compared with scan. So you could replace the scan command with getfield:

  
  when CLIENT_ACCEPTED {  
    
      Use a local array to configure the 5 SNAT addresses  
     set snat_ips(0) 1.1.1.1  
     set snat_ips(1) 2.2.2.2  
     set snat_ips(2) 3.3.3.3  
     set snat_ips(3) 4.4.4.4  
     set snat_ips(4) 5.5.5.5  
    
      Use getfield to parse the third octet from the client IP address  
      Get the modulus of the third octet against the number of the SNAT IPs in the array  
     set snat_number [expr {[getfield [IP::client_addr] "." 3] % [array size snat_ips]}]  
     log local0. "Client IP: [IP::client_addr], SNAT number $snat_number, SNAT IP: $snat_ips($snat_number)"  
    
      Apply the SNAT  
     snat $snat_ips($snat_number)  
  }  
  

Aaron

swiss2000_13853
Nimbostratus
Nimbostratus
Hi Aaron

 

 

Thank you very much for this proposal!

 

I currently use a general SNAT for all origin adresses to my SNAT pool.

 

So now, i have to disable this SNAT and add the iRule to all my VS?

 

 

Regards

 

Marc

hooleylist
Cirrostratus
Cirrostratus
Hi Marc,

 

 

You could use this specific SNAT rule on any VIP where you want to "persist" clients with the same SNAT IP over multiple connections. The more general default SNAT would take lower precedence than SNAT called from an iRule. So you could leave the default SNAT enabled for any other VIP which you don't need to use the same SNAT pool IP for each client.

 

 

Aaron

hooleylist
Cirrostratus
Cirrostratus
dupe...

hooleylist
Cirrostratus
Cirrostratus
I figured out that using a hash on the full client IP should give a better distribution across the SNAT addresses compared with using getfield to parse a single octet. The CPU usage is virtually the same as getfield. The rule is here:

 

 

http://devcentral.f5.com/wiki/default.aspx/iRules/snat_pool_persistence

 

 

Aaron

Joel_Moses
Nimbostratus
Nimbostratus
Just FYI, this iRule does pretty much the same thing; give you two options to get there.

 

 

http://devcentral.f5.com/wiki/default.aspx/iRules/Exchange2010_SNATPool_Persist.html

hooleylist
Cirrostratus
Cirrostratus
I thought crc32 might give better distribution but be lighter weight than the binary and format commands. But I haven't compared to see which is more efficient. Anyhow, more options are better than less 🙂

 

 

Aaron

Joel_Moses
Nimbostratus
Nimbostratus
iRules give you a million different ways to do the same thing. 😆

ZANOOB
Cirrus
Cirrus

Hi,

I know this post is very old , but i got into the same issue but the internet search for the irule has landed over here.

My goal is to match client IP to SNAT (one to one mapping). I found an irule, but that is very long (manual typing and for bigger subnet cannot apply since that will be longer than 65536 characters which irule can take).

when CLIENT_ACCEPTED {
if { [IP::addr [IP::client_addr] equals 172.16.56.10/32] }{
snat 172.16.56.10
}
if { [IP::addr [IP::client_addr] equals 172.16.56.11/32] }{
snat 172.16.56.11
}
if { [IP::addr [IP::client_addr] equals 172.16.56.12/32] }{
snat 172.16.56.12
}
.
.
.
.
"and till all the one to one mapping"
}

However, this is not useful for longer subnets.
Is there a way to match the third and last octect of the IP of the client to SNAT IP.
The above irule shows about the thrid octect only , is there a way to match 3rd and 4th octect?

Zanoob