Forum Discussion

Richard_Schmit_'s avatar
Richard_Schmit_
Icon for Nimbostratus rankNimbostratus
Jun 21, 2011

Snat automap and pool selection based on source and destination Ip

Trying to figure out an I-rule that will work for the follwing:

 

I have 3 ISP’s I’m load balancing to for outbound traffic. I have specific Virtual servers set up for specific outbound traffic.

 

 

For instance, a separate one for each outbound IPSEC lan-to-lan connection based on the remote IP peer address.

 

Each of these is further broken down as separate VS such as one for IPSEC (ALL Protocols) one for UDP 500, and one for UDP 4500...etc.

 

 

I also have an outbound catchall virtual server…basically if none of the other virtual servers are a more specific match, it will use this vs.

 

This particular vs has a pool with two addresses…One is the gateway router for the "ISP 'A' router” with a priority of 2, and the other with an IP of the "ISP 'B' router” with a priority of 1. So basically all 'other' traffic goes out ISP 'A' unless it is down, then it goes out ISP 'B'.

 

This VS also uses Snat Automap….which allows the return traffic to come back on the appropriate ISP link because the source IP is snat'd to whatever the next hop router is.

 

 

The problem I’m having, is that I have an internal router that needs to be able to ping 8 different remote servers (all with public ip’s). Those 8 external servers need to see the source address of the internal router so I cannot use SNAT AutoMap for these 8 remote IP's.

 

 

I could create 8 separate virtual servers each with it’s own destination IP and no SNAT and be done, but I’m trying to figure out if there is another way?

 

 

I started an I-Rule, but this is my first and I keep getting errors, so not sure what is wrong or even if it will work.

 

 

rule snat.rule

 

 

when CLIENT_ACCEPTED {

 

if {([IP::addr [IP::remote_addr] equals "11.12.20.10/32"] or ([IP::addr "[IP::remote_addr]" equals "63.24.13.1/32"] or

 

[IP::addr "[IP::remote_addr]" equals "63.21.24.23/32"] or [IP::addr "[IP::remote_addr]" equals "24.16.66.107/32"] or

 

[IP::addr "[IP::remote_addr]" equals "204.14.17.23/32"] or [IP::addr "[IP::remote_addr]" equals "20.14.172.23/32"] or

 

[IP::addr "[IP::remote_addr]" equals "4.14.21.12/32"] or [IP::addr "[IP::remote_addr]" equals "206.1.23.21/32"] and

 

[IP::addr "[IP::local_addr]" equals "6.10.1.26/32"]))}

 

{

 

snat none pool windstream_router_pool

 

else

 

{

 

snat automap pool Pool-Outbound_EverythingElse

 

}

 

}

 

}

 

 

 

Basically if the internal router (6.10.1.26) inside the Link Controller is trying to ping any of the 8 external addresses, then the source IP needs to stay as 6.10.1.26 and use existing pool called windstream_router_pool otherwise for all other traffic that doesn't match a more specific Virtual server, use snat automap and use an existing pool that loadbalances between the ISP routers.....I'm also getting confused on all the brackets, so not 100% sure these are all correct.
  • Colin_Walker_12's avatar
    Colin_Walker_12
    Historic F5 Account
    I think what you really want to do is create a class (Data Group) and store the info there. What version are you running?

    If you create a Data Group with the "address" type you'll be able to input each of those networks into the list. Once you have that, the iRule becomes very simple.

    v10 or later:

    
    when CLIENT_ACCEPTED {
      if {[class match [IP::addr [IP::client_addr]] equals NameOfYourClassHere]} {
        snat none
        pool windstream_router_pool
      } else {
        snat automap
        pool Pool-Outbound_EverythingElse
      }
    }
    

    If you're on v9 let me know and I'll modify it a bit. 😉

    Colin
  • Awesome, I'm running version 10, so I will give that a try in the morning and let you know.
  • It's a day of typos for us :)

     

     

    You can remove the IP::addr command from this [IP::addr [IP::client_addr]] as class match will do a bit comparison of the address with the address type datagroup entries.

     

     

    if {[class match [IP::client_addr] equals NameOfYourClassHere]} {

     

     

    Aaron
  • I have the data class and Irule built.

     

     

    Currently I have this for my configuration on the WildCard Outbound VS.

     

     

    }

     

    virtual vs-Outbound_WildCard {

     

    snat automap

     

    pool Pool-Outbound_EverythingElse

     

    destination any:any

     

    mask 0.0.0.0

     

    persist dest_addr

     

    vlans internal enable

     

    }

     

     

    Do I just turn snat automap off, and get rid of the pool, and call up the I-Rule instead? Leave everything else the same?
  • The iRule will turn SNAT on and off based on the qualifying conditions in the iRule (overriding the Virtual Server Configuration), so you should not need it to be applied the the Virtual Server.

     

     

    Same applies to the Pool.

     

     

    The Virtual Server status will be based on the availability of the pool status in the iRule if you do remove the pool from the Virtual Server (which is probably desirable).
  • Colin_Walker_12's avatar
    Colin_Walker_12
    Historic F5 Account
    Hah, thanks Aaron, good catch. Redundant code ftl. Ahh well, I guess we're even. ;)

     

     

    Colin
  • Arie's avatar
    Arie
    Icon for Altostratus rankAltostratus
    When I use Colin's syntax:

    if {[class match [IP::addr [IP::client_addr]] equals NameOfYourClassHere]} {

    I get "wrong args".

    It works fine when I omit IP::addr, but I don't think that's an option since I'm using netmasks (/x).

    Ideas?

  • It works fine when I omit IP::addr, but I don't think that's an option since I'm using netmasks (/x).i think so. i don't think IP::addr is needed when using matchclass/class match as Aaron mentioned as well.
  • Arie's avatar
    Arie
    Icon for Altostratus rankAltostratus
    I've tried a number of different things, but the only time the parser will use the subnet mask is if I use [IP::addr] - which I can't get to work with a class...
  • Not only is it not needed, but IP::addr will not work with the class match or matchclass commands.

     

     

    Aaron