Forum Discussion

Logan_Ramirez_5's avatar
Logan_Ramirez_5
Icon for Nimbostratus rankNimbostratus
Dec 08, 2005

conditional SNAT

We have a relatively simple environment: two data centers, one web server in each, one bigip in each. Basic pool in each office for web servers consists of (a) local web server and (b) other data center virtual server containing the other web server.

 

 

So, if local web down --> send to BIGIP in other DC to get serviced.

 

 

Recently, however, deployed an MPLS network with a couple of additional routers which has stopped this functionality from working (because I cannot, or do not know, how to get all of those routers to change their default gateway based on a web server failure).

 

 

While I could solve this by SNATTING all requests to the web server (the issue is the return path to the customer does not make it out because of incorrect default gateways in all intermediate routers), we use the IP logs for security auditing, etc.

 

 

What would be great is if when a external web request gets serviced by BIGIP, if it send the packet to the local web server, it does not SNAT, however, if it needs to send it to the other web server in the 2nd DC, it SNATS.

 

 

Being fairly new to iRules, I have no idea how to write this...would love some help...

14 Replies

  • I believe that did it!

    Assuming you have a pool setup with some servers you want to SNAT on and others you do NOT, and your virtual server is setup to SNAT ALL (in my case, autosnat is setup), then, here is the new iRule:

    
    when LB_SELECTED {
       if {[IP::addr [LB::server addr] equals "[insert server in pool you do not want to SNAT for here]"]} {
          snat none
       }
    }

    From my initial testing, that seems to do the trick!!

    Thank you, f5, specifically unRuleY.
  • G__Wesley_Rober's avatar
    G__Wesley_Rober
    Historic F5 Account
    Hi,

    I spent a bit of time thrashing about trying to apply this iRule to a forwarding virtual, so I thought it might be worth pointing out some subtle differences in events based on the type of virtual server. The LB_SELECTED event works fine if you need to test a node address before the connection to the node is established, as in the case with a standard virtual server, or other types that actually load balance such as Performance L4. However, this event DOES NOT FIRE on virtual servers of type forwarding (ip).

    Since with a forwarding virtual the destination address doesn't change, you can use the CLIENT_ACCEPTED event and the [IP::local_addr]. For those used to v4.5.x and "forwarding pools" which allowed you to disable SNAT/NAT, the following iRule will help in the transition to v9.

    Given a SNAT that translates everything internal-->external, but you want to disable SNAT to certain destination networks:

    
    class NoNATNets {
        network 10.30.1.0 mask 255.255.255.0
        network 10.30.100.0 mask 255.255.255.0
    }
    pool gateway {
       member 10.30.1.254:any
       member 10.30.1.253:any
    }
    snat SNATInternal {
       automap
       origin 0.0.0.0 mask 0.0.0.0
       vlan internal enable
    }
    rule DisableSnatWithClass {
       when CLIENT_ACCEPTED {
          if {[matchclass [IP::local_addr] eq $::NoNATNets]} {
             log "Matching NoNAT List, disabling SNAT: [IP::local_addr]"
             snat none
             forward
          } else {
             log "No Match in NoNAT List, allowing SNAT: [IP::local_addr]"
             pool gateway
          }
       }
    }
    virtual Outbound {
       destination any:any
       profile myfastl4
       pool gateway
       rule DisableSnatWithClass
       vlans internal enable
    }

    It is also worth noting that if you DO use the LB_SELECTED event for load balancing "transparent devices" such as routers or Firewalls, the address values are similar to CLIENT_ACCEPTED, with the addition of LB::selected. Here they are for review:

    IP::remote == the client IP

    IP::local == The destination IP of the packet (out in the cloud)

    LB::server addr == The node selected (the router or firewall)

    Hope this helps!
  • G__Wesley_Rober's avatar
    G__Wesley_Rober
    Historic F5 Account
    You are most welcome. I ran out of gas last night, but here are the other (simpler) versions I came up with that may be useful for someone who has forwarding virtuals.

    The problem I was actually trying to solve was simply to disable SNAT for a single forwarding Virtual that passed traffic from the internal to external VLAN. The iRule in the previous post allowed me to eliminate the network forwarding virtual altogether and just do it in the wildcard virtual. Anyhow, if you have a network virtual of type forwarding (ip), you can disable SNAT with any of these iRules. The Virtual:

    virtual ToExternalVLAN {
       destination 10.30.1.0:any
       ip forward
       mask 255.255.255.0
       profile myfastl4
       vlans external enable
    }

    Use either of these iRules to disable SNAT:

    rule DisableSnat2NET {
       when CLIENT_ACCEPTED {
       if {[IP::addr [IP::local_addr] equals "10.30.1.0/24"]} {
          log "Not going to SNAT to destination: [IP::local_addr]"
          snat none
       }
       else {
          log "SNAT to destination: [IP::local_addr]"
       }
    }
    
    rule JustDisableSNAT {  The winner 
       when CLIENT_ACCEPTED {
        log "Disabling SNAT"
        snat none
    }