F5 is upgrading its customer support chat feature on My.F5.com. Chat support will be unavailable from 6am-10am PST on 1/20/26. Refer to K000159584 for details.

Forum Discussion

Mahantesh_Bisur's avatar
Mahantesh_Bisur
Icon for Nimbostratus rankNimbostratus
Aug 05, 2015

SNAT iRule based on client IP address

Hi All,

 

I am looking for an Irule on a virtual server to use a different snatpool based on the actual client ip address and this has to scale up to multiple different clients(around 50 to 100) using the same virtual server.

 

If client ip matches

 

A -->Use SNATPOOLX

 

B --> Use SNATPOOLY

 

C --> Use SNATPOOLZ.

 

Could anyone please help me in scripting iRule for above requirement?

 

Regards, Mahantesh

 

5 Replies

  • I'd use data group lists for easier administration.

    You need to create the data group lists (type address) SNATPOOLXCLIENTS, SNATPOOLYCLIENTS and SNATPOOLZCLIENTS first, and populate them with the ips/networks of the clients.

    when CLIENT_ACCEPTED {
        if { [class match [IP::client_addr] equals SNATPOOLXCLIENTS] } {
            snatpool SNATPOOLX 
        } elseif { [class match [IP::client_addr] equals SNATPOOLYCLIENTS] } }{
            snatpool SNATPOOLY
        } elseif { [class match [IP::client_addr] equals SNATPOOLZCLIENTS] } }{
            snatpool SNATPOOLZ
        }
    }
    

    May I ask if you're using different data group lists because of firewall reasons (what's being allowed where) or for network topology reasons?

    Otherwise you could just add all the addresses in SNATPOOLX, SNATPOOLY and SNATPOOLZ into one snatpool and configure that on the virtual server. Then the LTM would automatically choose an IP matching the LAN it sends out the packet to.

    /Patrik

  • Thanks Patrick for the update. Here we basically need all the client ip addresses to be visible on the back end servers.Our back end servers are sftp servers & there are external customers who accesses this sftp services. so there is a requirement for us to check & validate each & every request at the back end servers to see from where the requests are coming & who is accessing this sftp services.Since the way our network has been setup, We are using SNAT automap on our VS,So back end servers are currently seeing only F5 Ip address. As you said, If I use all addresses in single Data group then all requests will hit the back end servers with single snatpool ip which again will become similar to snat automap..

     

    I tried to configure n-path routing for this issue, but that also didn't worked for me. So basicallly what I am thinking is if we use natting on the F5 for example if customer A accesses this VS then it shuld nat to ip address X. so that whenever request hits back end pool members with this ip address(X) they will be able to identify the customer details.

     

    I hope you got my requirement. Please let us know if you need further clarification on this.

     

  • Hi!

    I think I understand now.

    If the ration between customer IP and NAT pool is 1:1 I'd use something like this:

    when CLIENT_ACCEPTED {
        if { [IP::addr [IP::client_addr] equals 10.0.0.1] {
            snatpool SNATPOOLX 
        } elseif { [IP::addr [IP::client_addr] equals 10.0.0.,2] } }{
            snatpool SNATPOOLY
        } elseif { [IP::addr [IP::client_addr] equals 10.0.0.3] } }{
            snatpool SNATPOOLZ
        }
    }
    

    If you expect the ration to be more than one and changing I'd use the first rule I wrote.

    /Patrik

  • Hi Patrick,

     

    Thanks for the update. Yes, we need the ratio to be 1:1. In above iRule, We need to edit the iRule everytime, whenever new customer tries to access sftp services rite? Also for above iRule we should not configure snat for that specific VS rite ..? or It will also works If we configure something like snat automap for that VS.. correct me If I am wrong..

     

    Thanks, Mahantesh

     

  • Yes, when new customers comes in you'd have to update the rule. There isn't another way to get a 1:1 ratio between the snat addresses that I can think of. I wrote the rule with snatpools since that's what you asked for, but it might actually be easier and more clean to use the snat command instead of the pools.

    when CLIENT_ACCEPTED {
        if { [IP::addr [IP::client_addr] equals 10.0.0.1] {
            snat 172.18.1.1
        } elseif { [IP::addr [IP::client_addr] equals 10.0.0.2] } }{
            snat 172.18.1.2
        } elseif { [IP::addr [IP::client_addr] equals 10.0.0.3] } }{
            snat 172.18.1.3
        }
    }
    

    Another possibility could be to use a key value pair in a data group list. You then create a data grouplist called ie snatlist (or some other name) with key/value pairs of client-ip = snat-ip. This would minimize the irule editing and focus on data group lists instead.

    With the example above the list would be:

    10.0.0.1 = 172.18.1.1
    10.0.0.2 = 172.18.1.2
    10.0.0.3 = 172.18.1.3
    

    And the rule would look something like this (untested by me though):

    when CLIENT_ACCEPTED {
        Check if there's an entry for the client ip in the snatlist data group list
        if { [class match [IP::remote_addr] equals snatlist] } {
            If there is check the value for the ip in question
            snat [class lookup [IP::remote_addr] snatlist]
        } else {
            Default action drop
            drop
        }
    }
    

    Hope that's somewhat clear.

    /Patrik