Forum Discussion

Joe_Frost_43072's avatar
Joe_Frost_43072
Icon for Nimbostratus rankNimbostratus
May 08, 2007

Single host SNAT iRule

Hello all-

 

 

I have a simple apache pool with 3 internal hosts and 1 host that lives outside of my network in which i want to SNAT exclusively in order to bypass the asymetrical routing issue. How would i write an iRule to only SNAT my one external pool node?

 

 

 

Thanks

 

 

 

7 Replies

  • This is what i tried but when i apply it, i get connection reset on my Virtual. Any suggestions?

     

     

    Class Hosts {

     

    1.2.3.4 (where this is my real public ip)

     

    }

     

     

    when LB_SELECTED {

     

    if { [matchclass [LB::server] equals $::Hosts]} {

     

    snat automap

     

    }

     

    }
  • Do you see an error in /var/log/ltm?

    Also, you should create a class with type of Address and put the IP address(es):

    class address_class_test {

    host 1.2.3.4

    }

    Also, LB::server will return the IP address of the selected node. I assume the node is the client in the scenario you're testing now?

    Can you add a log statement to see what values you're getting?

    
    when LB_SELECTED {
       log local0. "\[LB::server\]: [LB::server], \[IP::client_addr\]: [IP::client_addr]"
       if { [matchclass [LB::server] equals $::Hosts]} {
          snat automap
       }
    }

    Aaron
  •  

     

    Do you see an error in /var/log/ltm?

     

     

     

    May 9 08:10:04 tmm tmm[862]: 01220001:3: TCL error: Rule single_snat - missing "mask"Invalid class element live_resin 10.120.136.53 80 for class Hosts invoked from within "matchclass [LB::server] equals $::Hosts"

     

     

    Also, you should create a class with type of Address and put the IP address(es):

     

     

    class address_class_test {

     

    host 1.2.3.4

     

    }

     

     

     

     

    Did this.

     

     

    Also, LB::server will return the IP address of the selected node. I assume the node is the client in the scenario you're testing now?

     

     

     

    Basically what i want to do is only snat one pool node if its selected by any client, where the pool node is = to class Hosts

     

     

     

  • It looks like there might be something else in your class, other than just the IP address, which is being interpreted as a netmask.

    If you want to apply a SNAT for specific clients, you can use IP::client_addr instead of LB::server and you can do it in the CLIENT_ACCEPTED event instead:

    
    when CLIENT_ACCEPTED {
        SNAT requests if client_addr is defined in the class
       if { [matchclass [IP::client_addr] equals $::Hosts]} {
          snat automap
       }
    }

    If this doesn't work, can you run the following commands from the command line or the GUI's console page to list the configuration for the class and rule?

    b class Host list all

    b rule single_snat list all

    Thanks,

    Aaron
  • I would like to use client_accepted but i need to do it for every client instance when my Hosts class is matched.

     

     

    Here is what i get for the commands:

     

     

    [root@abel:Active] log b class Hosts list all

     

    class Hosts {

     

    host 1.2.3.4

     

    }

     

     

    [root@abel:Active] log b rule single_snat list all

     

    rule single_snat {

     

    when LB_SELECTED {

     

    if { [matchclass [LB::server] equals $::Hosts]} {

     

    snat automap

     

    }

     

    }

     

    }

     

     

     

  • The CLIENT_ACCEPTED event is triggered every time a client makes a TCP connection. The SNAT would be performed throughout the life of the connection.

    Also, if you want to apply the SNAT based on the what the client IP address is, you would need to use IP::client_addr instead of LB::server. LB::server will return the node IP address in the pool.

    Regardless of whether the rule applies the SNAT correctly, you shouldn't be seeing a TCL error using the class and rule you just listed.

    Can you retry with the following rule to see if a) works without an error and b) actually SNAT's the traffic as you want?

    
    when CLIENT_ACCEPTED {
       log local0. "\[IP::client_addr\]: [IP::client_addr]"
        SNAT requests if client_addr is defined in the class
       if { [matchclass [IP::client_addr] equals $::Hosts]} {
          log local0. "matched for [IP::client_addr]"
          snat automap
       }
    }

    If that doesn't work for some reason, can you try this rule without the class as a test:

    
    when CLIENT_ACCEPTED {
       log local0. "\[IP::client_addr\]: [IP::client_addr]"
        SNAT requests if client_addr matches this IP
       if { [IP::addr [IP::client_addr]/24 equals 1.2.3.4]} {
          log local0. "matched for [IP::client_addr]"
          snat automap
       }
    }

    Aaron