Forum Discussion

Kevin_Nail's avatar
Kevin_Nail
Icon for Nimbostratus rankNimbostratus
Mar 04, 2010

SNAT based on incoming IP

I have a need to snat based on the incoming IP. It should be relatively straight forward but I can't seem to make my mind wrap around this.. or what's the best way to do it.

 

 

I have a private subnet that is divided into 3 ranges (prod/dev/test) and I need to SNAT based on which IP is connecting... For example if server in the DEV range connects then it should get SNAT A, test should get SNAT B and production should get SNAT C.

 

 

So I need the iRule to evaluate something similiar

 

 

10.9.9.0/26 gets SNAT A

 

10.9.9.65/26 gets SNAT B and

 

10.9.9.128/26 gets SNAT C

 

 

Also, do you know what the load would be of implementing such a rule on the CPU? I would guess that there would be less than 50 connections per minute.

 

 

Any help would be greatly appreciated.

9 Replies

  • Kevin: you can definitely do this. Here's a good starting point that may work with minimal modification on your part:

     

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

     

     

    Give this a look and post back if you've got any questions. Regarding the load, this is a very lean-and-mean operation. I wouldn't be concerned here at all.

     

     

    -Matt
  • This looks good but I was really hoping for a solution that would examine all 3 choices at once. This would have to be 3 separate rules if I read this right. Would it be possible to examine the incoming IP and make one of 3 choices od SNAT IPs?

     

     

  • I've not tested this (don't have the time at the moment), but maybe something like this? Obviously change the IPs to suit your environment.

     
      when CLIENT_ACCEPTED { 
     switch [IP::client_addr] { 
      
     10.9.9.0/26 { snat 10.9.9.16 } 
     10.9.9.65/26 {snat 10.9.9.99} 
     10.9.9.128/26 {snat 10.9.9.24} 
     default { snat 10.10.10.99 } 
     } 
     } 
     

    -Matt
  • I think you're limited to string comparisons with switch.

     

     

    If you're on 10.1, you could use a new feature for address type datagroups described in this post (Click here) and reference the datagroup with the class command (Click here).

     

     

    Else, for older versions, I think you're stuck doing three checks in an if/elseif/elseif block. Though, this could be done in a single iRule.

     

     

    Aaron
  • Gah - what was I thinking? Sorry about that, try this one instead. Obviously change your snat IPs to something sensible, and be sure and change the last "else" to something if you don't want to simply forward the traffic on.

     
      when CLIENT_ACCEPTED { 
     if { [IP::addr [IP::client_addr] equals 10.9.9.0/26] }{ 
     snat 1.1.1.1 
     } 
     elseif { [IP::addr [IP::client_addr] equals 10.9.9.65/26] }{ 
     snat 2.2.2.2 
     } 
     elseif { [IP::addr [IP::client_addr] equals 10.9.9.128/26] }{ 
     snat 3.3.3.3 
     } 
     else {  
     forward 
     } 
     } 
     

    -Matt

  • Posted By L4L7 on 03/07/2010 01:43 PM

    Gah - what was I thinking? Sorry about that, try this one instead. Obviously change your snat IPs to something sensible, and be sure and change the last "else" to something if you don't want to simply forward the traffic on.

    
      when CLIENT_ACCEPTED { 
     if { [IP::addr [IP::client_addr] equals 10.9.9.0/26] }{ 
     snat 1.1.1.1 
     } 
     elseif { [IP::addr [IP::client_addr] equals 10.9.9.65/26] }{ 
     snat 2.2.2.2 
     } 
     elseif { [IP::addr [IP::client_addr] equals 10.9.9.128/26] }{ 
     snat 3.3.3.3 
     } 
     else {  
     forward 
     } 
     } 

    -Matt

    This works great in version 9, but is there a way to do this this if you 7 subnets total? The elseif statement argument is limited to three. That plus the initial statement only gets you 4 total subnets.

  • Hi Valentine,

     

     

    You can put them all into a Data Group at that point. If a match is found then you can SNAT to the value of the match.
  • e.g.

    [root@iris:Active] config  b rule myrule list
    rule myrule {
       when CLIENT_ACCEPTED {
            if {[class match [IP::client_addr] equals client_ips]} {
                    snat [class match -value [IP::client_addr] equals client_ips]
            } else {
                    forward
            }
    }
    }
    [root@iris:Active] config  b class client_ips list
    class client_ips {
       {
          network 10.9.9.0/26 { "1.1.1.1" }
          network 10.9.9.64/26 { "2.2.2.2" }
          network 10.9.9.128/26 { "3.3.3.3" }
       }
    }
    
    

    hope this hleps.