Forum Discussion

Fabrizio_Gerard's avatar
Fabrizio_Gerard
Icon for Nimbostratus rankNimbostratus
May 14, 2015

network to network selective snat

Hi,

 

In my organization I have the need to source nat a subset of clients. But I need to do this without loosing the option to trace specific client requests in the application server log.

 

So I thought it would be useful to apply a network to network selective source nat leaving the last three octets of the original client ip address unchanged.

 

For example, I want the client ip 10.1.2.3 to be source natted with the address 12.1.2.3 (the first octet changed from 10 to 12). This should be applied respectively to all clients included in the original network 10.0.0.0/8

 

So I wrote an irule that seems to do the job:

 

when CLIENT_ACCEPTED { checks to see if client_addr = any in the class if { [class match [IP::client_addr] equals SNAT_GROUP_A] } { scan [IP::client_addr] %d.%d.%d.%d ip1 ip2 ip3 ip4 set newip [IP::addr 12.$ip2.$ip3.$ip4 mask 255.255.255.255] snat $newip log local0. "Snatting client [IP::client_addr] Client Port:[TCP::client_port] - Server Port:[TCP::local_port clientside] to new source ip $newip" } }

 

My question is: Is this the right way to obtain what we need? Is there some more efficient ways to do the same thing? In your opinion, how much thi irule should impact on ltm performance considering the traffic generated by several thousands clients?

 

Thanks in advance for your comments

 

Bye

 

5 Replies

  • I would look at this code snippet (and adjust accordingly) Selective SNAT

     

    As far as performance based on a few 1000 connections I think you shouldn't notice too much.

     

  • Also, is this the way the iRule you submitted looks like?

    when CLIENT_ACCEPTED {
         checks to see if client_addr = any in the class 
        if { [class match [IP::client_addr] equals SNAT_GROUP_A] } {
        scan [IP::client_addr] %d.%d.%d.%d ip1 ip2 ip3 ip4 
        set newip [IP::addr 12.$ip2.$ip3.$ip4 mask 255.255.255.255]
        snat $newip 
        log local0. "Snatting client [IP::client_addr] Client Port:[TCP::client_port] - Server Port:[TCP::local_port clientside] to new source ip $newip"
        }
    }
    
  • Hi, sorry for the formatting issue...the rule I wrote looks like this:

     

    when CLIENT_ACCEPTED { 
     checks to see if client_addr = any in the class 
    if { [class match [IP::client_addr] equals SNAT_GROUP_A] } { 
        scan [IP::client_addr] %d.%d.%d.%d ip1 ip2 ip3 ip4
        set newip [IP::addr 12.$ip2.$ip3.$ip4 mask 255.255.255.255]
        snat $newip
        log local0. "Snatting client [IP::client_addr] Client Port:[TCP::client_port] - Server Port:[TCP::local_port clientside] to new source ip $newip"
        } 
    }

    I took a look to the code you mentioned: it is ok but it lacks one feature, that the snat ip should be dynamic (based on the client original address, preserving last three octets)... That's why in my code I extract the four original octets to rebuild the new snatted address

     

  • Fair enough. I think the main things to consider here is how optimized is the iRule then. Here are a few articles, one that talks about general iRule optimization as well as one that is a comparison of the optimization of different ways to do IP comparison. They might not be exactly what you are looking for but they have helped guide me in iRule optimizations.

     

    Ten Steps to iRules Optimization

     

    iRules IP Comparison Considerations with IP::addr Command