Forum Discussion

madi_56757's avatar
madi_56757
Icon for Nimbostratus rankNimbostratus
Jan 17, 2005

inteligent SNAT with iRule

Hi,

 

 

 

I have in the version 4.5.10 a iRule for an inteligent SNAT,

 

 

VIRTUAL ANY UNIT 1

 

|

 

|

 

|

 

+---+--> WILDCARD SERVICE ENABLED

 

|

 

|

 

|

 

+---+--> RULE SNAT

 

+---+--> POOL forward_no_snat

 

+---+--> POOL forward_snat

 

 

the rule is configured

 

----------------------------------------------------------------------

 

if (server_addr == 10.0.0.0 netmask 255.0.0.0) {

 

use pool forward_no_snat

 

}

 

else {

 

if (server_addr == xxx.xxx.xxx.0 netmask 255.255.255.0) {

 

use pool forward_no_snat

 

}

 

else {

 

use pool forward_snat

 

}

 

}

 

----------------------------------------------------------------------

 

and it works fine !

 

 

 

 

currently we have a new B6400 (Version 9.0.3) in test phase and I tried to configure the same with the new syntax

 

but it doesn't work

 

 

I've configured an 0.0.0.0:0 forwarding server for all Vlans and a iRule "mysnat" attached.

 

 

This iRule has the folowing statement (it is not exactly the same like the IRule descipted above

 

but this example makes it easier to point up my problem)

 

 

----------------------------------------------------------------------

 

when SERVER_CONNECTED {

 

if {[IP::remote_addr] egual "2.2.2.0 netmask 255.255.255.0"}

 

{forward }

 

else {use snatpool test_snat}

 

}

 

---------------------------------------------------------------------

 

I have tried with another statment

 

---------------------------------------------------------------------

 

when SERVER_CONNECTED {

 

if { [IP::addr [IP::remote_addr] egual 2.2.2.0 netmask 255.255.255.0] }

 

{forward }

 

else {use snatpool test_snat}

 

}

 

---------------------------------------------------------------------

 

 

following architecture

 

 

-------------- 1.1.1.0/24

 

|

 

-------------

 

| Router |

 

-------------

 

|2.2.2.1

 

|

 

-----------------------------------------

 

Network 2.2.2.0/24 VLAN 50

 

|

 

| 2.2.2.27 VIP.26

 

---------------

 

| BIGIP |

 

---------------

 

| 30.30.30.2 VIP.1

 

|

 

-----------------------------------------

 

Privat Network 30.30.30.0/24 VLAN 60

 

 

---------------------------------------------------------------------

 

 

connecting from the server 30.30.30.10 to the Network 2.2.2.0 => the BIgIP forward this paket with the Origin IP address

 

 

connecting from the server 30.30.30.10 to other networks => should be forwarded with the SNAT address

 

 

fact is the rule is matching (looking in the iRule statistics) ...but any connection is forwarded without the SNAT

 

 

I tried the same iRule with a drop statment instead "else {use snatpool test_snat}"

 

 

----------------------------------------------------------------------

 

when SERVER_CONNECTED {

 

if {[IP::remote_addr] eg "2.2.2.0 netmask 255.255.255.0"}

 

{forward }

 

else {drop}

 

}

 

-----------------------------------------------------------------------

 

this works !

 

 

...it seems that's only a problem with the SNAT !

 

 

 

 

Could anybody give me a hand ?

 

 

Thanks in advance
  • unRuleY_95363's avatar
    unRuleY_95363
    Historic F5 Account
    I believe the problem you are experiencing is due to the event you have chosen for your rule. The SERVER_CONNECTED event is evaluated after the serverside of the proxy has been connected. At this point, it is too late to change any aspects of the serverside that would effect the address or port. This is why you don't see any change in the SNAT behavior. Since, the rule you have written doesn't appear to use anything but addresses to make the decisions, you should probably use the CLIENT_ACCEPTED event.

     

     

    Also, I'd like to note that the result of the IP::remote_addr and IP::local_addr commands changes depending on the "context" of the event. Serverside events (like SERVER_CONNECTED) will cause IP::remote_addr to return the result of the server's node address (this would likely be the same as the pool member address); and IP::local_addr is the proxy's local address, which would be the SNAT address if using a SNAT. For the clientside events (like CLIENT_ACCEPTED), IP::remote_addr returns the client's address; and IP::local_addr likely returns the targeted virtual address.

     

     

    Lastly, you do need to use the IP::addr command to compare IP addresses like you did in the latter commands (though you should bracket or quote the address and netmask together. Ie, either of the following are correct:

     

    [IP::addr [IP::remote_addr] equals "2.2.2.0 netmask 255.255.255.0"]

     

    or

     

    [IP::addr [IP::remote_addr] equals {2.2.2.0 netmask 255.255.255.0} ]

     

     

    Good luck!
  • unRuleY_95363's avatar
    unRuleY_95363
    Historic F5 Account
    Two things:

    Regarding the IP::addr command - I'm not sure if this problem occurred as you typed in the rule to the forum, but you need a space between the IP::addr command and the [IP::remote_addr] command. It doesn't look like you have one... ? If this is the case, then you could be getting a rule failure which is logged to /var/log/ltm.

    Regarding the snat not working - Can you give me some information about how your virtual is configured? The question I have right now is what the default action of the virtual is. Based on the way you currently have the rule, if the address doesn't match, you pick a snatpool but don't designate forwarding or a pool for load-balancing. Perhaps your rule should look like:

      
      when CLIENT_ACCEPTED {  
         if {not [IP::addr [IP::remote_addr] equals "2.2.2.0 netmask 255.255.255.0"]} {  
            use snatpool test_snat  
         }  
         forward  
      }  
      

  • Ok your suspicion was good

     

     

    the space between the IP:addr command and IP::remote command has been missing.

     

    But it's strange: I didn't get any failure when I applied the rule ...

     

    ===> Ok whatever

     

     

    Now I have configured following rule

     

     

    when CLIENT_ACCEPTED {

     

    if {[IP::addr [IP::remote_addr] equals "2.2.2.0 mask 255.255.255.0"]}

     

    {forward

     

    } else {use snatpool test_snat}

     

    }

     

     

    good but the effect is ===>>> all traffic is forwarded with the SNAT address (and this happens with the destination is 2.2.2.x , too!)

     

    I have the same result when I am using the rule as you mentioned in

     

    your last posting:

     

    -------------------------------------------------------------

     

    when CLIENT_ACCEPTED {

     

    if {not [IP::addr [IP::remote_addr] equals "2.2.2.0 mask 255.255.255.0"]} {

     

    use snatpool test_snat

     

    }

     

    forward

     

    }

     

    -------------------------------------------------------------

     

    Here again: when using the 2.2.2.x as a destination the box is still using the snatpool ??

     

     

    --------------------------------------------

     

    Virtuall Server config:

     

    The vituall Server 0.0.0.0:0 is configured for all VLAN and in IP Forwarding modus

     

    and in the recources is the "mysnat" rule attched

     

    --------------------------------------------

     

    SNAT:

     

    in the "SNAT Pool List" is the pool named "test_snat"

     

    --------------------------------------------

     

     

    It seems to be as the destination address (-> remote_addr) ist not

     

    interesting in the rule???

     

     

    regards
  • unRuleY_95363's avatar
    unRuleY_95363
    Historic F5 Account
    Ok, I will run some tests this weekend so I can better understand all the issues around this. You may want to use a different approach, like putting the snat on the virtual (or maybe you already have it that way which could be why it's always snat'ing) and then use the rule to disable the snat via the "snat none" command:

     
     when CLIENT_ACCEPTED { 
        if {[IP::addr [IP::local_addr] equals "2.2.2.0 mask 255.255.255.0"]} { 
           snat none 
        } 
     } 
     

    Have a good weekend.
  • unRuleY_95363's avatar
    unRuleY_95363
    Historic F5 Account
    Ok, I have run more tests to confirm that this does work as designed.

     

    I configured it two different ways.

     

     

    The first method was with a SNAT configured on the virtual and then

     

    using the rule to disable the SNAT when the destination matched a

     

    specific network. This worked just fine using the rule in the

     

    previous post with the "snat none" command.

     

     

    The second method was to configure the virtual without any SNAT and

     

    then use the rule to identify the snat to use (as in the previous

     

    post using the "snatpool test_snat" command). This also worked just

     

    fine.

     

     

    So, my suspicion is that perhaps you have a SNAT configured on the

     

    virtual as well as the pool, thus always selecting a SNAT.

     

     

    If you continue to have a problem, then please open a case with

     

    customer support.

     

     

    Thanks.
  • hello

     

     

    we tried again ....

     

     

     

    Our scenario is like first you described:

     

     

    We configured a snat pool and use this snat pool in a snat list, so normally

     

    snat is done. then we configured a rule in the virt. server to disable the snat.

     

    the dest. ip we try to connect is 2.2.2.16

     

     

     

    I have tested your rule two times with different effect.

     

     

    The two possibilities of the rule:

     

     

     

    (1) If I configure the rule with a "mask"-statement

     

     

    --------------------------------------------------------------

     

    when CLIENT_ACCEPTED {

     

    if {[IP::addr [IP::local_addr] equals "2.2.2.0 mask 255.255.255.0"]} {

     

    snat none

     

    }

     

    }

     

    --------------------------------------------------------------

     

    I don't have any matches on my criterias, the snat is still done !!

     

    ===>>> the rule doesn't work correctly

     

     

     

    (2) If I configure the rule instead of the "mask"-statement only with a host IP

     

     

    --------------------------------------------------------------

     

    when CLIENT_ACCEPTED {

     

    if {[IP::addr [IP::local_addr] equals "2.2.2.16"]} {

     

    snat none

     

    }

     

    }

     

    --------------------------------------------------------------

     

    The snat is turned off.

     

    ===>>> The rule works fine ???!!!

     

     

     

    So ....

     

    I have two questions:

     

     

     

    Do you use Version 9.0.3 ??

     

     

    And do you use the rule really with a "mask"-statement?

     

     

  • Tao_Liu_90341's avatar
    Tao_Liu_90341
    Historic F5 Account
    Could you try:

     

     

    If {[IP::addr 2.2.2.0 equals "[IP::local_addr]/255.255.255.0"]} {

     

    ...

     

    }

     

  • Hello tliu & unRuley

     

    it seems we have the solution.

     

    It works, thanks a lot for your help and patience.