Forum Discussion

Brian_Mayer_841's avatar
Brian_Mayer_841
Icon for Nimbostratus rankNimbostratus
Aug 19, 2008

Conditional logic based on source IP

Hi guys,

 

 

We'd like to implement an iRule that triggers on the presence of two or three specific strings in the URI. When any of the strings are found, we next want to check the source IP. If the IPs are part of a data group, then we want to allow the traffic to reach the site. All other IPs should be dropped.

 

 

Any idea if this is possible?

 

 

Thanks in advance guys,

 

B

7 Replies

  • Hi,

    This is possible with something like this

     
     when HTTP_REQUEST { 
        if {[HTTP::uri] starts_with "/appli1" } { 
            if {[matchclass [IP::addr [IP::client_addr]/16] equals $::autorized_IPs]} { 
                         pool web_pool 
           } else { 
               reject 
          } 
     } 
     

    Here are the links that may help you:

    Click here

    Click here

    Click here

    HTH

    N.
  • So I've created an iRule but it's not quite working. Here's it is:

     

     

    when HTTP_REQUEST {

     

    if {[matchclass [HTTP::uri] contains $::cm2prod_filtered_URI] and (not [matchclass [IP::client_addr] eq $::corporate_external_net])}{

     

    discard

     

    }

     

    }

     

     

    I've got a data group that contains a list of several line items. If any of the strings appears in the URI and the source IP is not the corporate network, then the traffic should be dropped.

     

     

    Here's the data group for the URI strings to match:

     

     

    /init/

     

    /msg/

     

    /debs/

     

    /amsg/

     

    /web/

     

    /catalogAdmin/

     

    /visualModeler/

     

    /attributeMgr/

     

    /productMgr/

     

    /pricingMgr/

     

    /enterpriseMgr/

     

    /tokenIF/

     

    /customerSegmentation/

     

     

    The data group for the network addresses is a simple list of our external corporate firewall IPs.

     

     

    Any idea why this isn't working and how to troubleshoot?

     

     

    Thanks!

     

    B
  • Haven't test this, but have you tried:

     
     when HTTP_REQUEST {  
            if {([matchclass [HTTP::uri] contains $::cm2prod_filtered_URI]) and (not [matchclass [IP::client_addr] eq $::corporate_external_net])} { discard }  
     } 
     

    or

     
     when HTTP_REQUEST {  
     if {([matchclass [HTTP::uri] contains $::cm2prod_filtered_URI]) and (![matchclass [IP::client_addr] equals $::corporate_external_net])}{ discard } 
     } 
     

    or

     
     when HTTP_REQUEST {  
            if {[matchclass [HTTP::uri] contains $::cm2prod_filtered_URI] and (not [matchclass [IP::client_addr] equals $::corporate_external_net])} { discard }  
     } 
     

    or

     
     when HTTP_REQUEST {  
            if {([matchclass [HTTP::uri] contains $::cm2prod_filtered_URI]) and (not [matchclass [IP::client_addr] equals $::corporate_external_net])} { discard }  
     } 
     

    Hope this helps

    CB

  • I've simplified the iRule a lot and it still doesn't work as expected:

     

     

    when HTTP_REQUEST {

     

    if {[matchclass [HTTP::uri] contains "/init/"]}{

     

    discard

     

    }

     

    }

     

     

    That should discard any URI with /init/ but it lets it through.

     

     

    Any ideas?
  • If you want to check the URI for one string, you wouldn't reference the class or use matchclass. Also, if the above examples aren't working, break each check into a separate 'if' statement and add logging to figure out what's happening.

     
     when HTTP_REQUEST { 
        log local0. "[IP::client_addr]:[TCP::client_port]: request to [HTTP::host], [HTTP::uri]" 
        if {[HTTP::uri] contains "/init/"]}{ 
           log local0. "[IP::client_addr]:[TCP::client_port]: URI contained /init/, dropped request" 
           discard 
        } 
     } 
     

     
     when HTTP_REQUEST { 
      
        log local0. "[IP::client_addr]:[TCP::client_port]: -------------------------------------" 
        log local0. "[IP::client_addr]:[TCP::client_port]: \$::cm2prod_filtered_URI contents: $::cm2prod_filtered_URI" 
        log local0. "[IP::client_addr]:[TCP::client_port]: \$::corporate_external_net contents: $::corporate_external_net" 
        log local0. "[IP::client_addr]:[TCP::client_port]: request to [HTTP::host], [HTTP::uri]" 
      
        if {([matchclass [HTTP::uri] contains $::cm2prod_filtered_URI])}{ 
      
           log local0. "[IP::client_addr]:[TCP::client_port]: matched URI to class 
      
           if {(not [matchclass [IP::client_addr] equals $::corporate_external_net])}{ 
      
      log local0. "[IP::client_addr]:[TCP::client_port]: didn't match client to external networks class 
      discard 
           } 
        } 
     }  
     

    If the application is not case sensitive, you should set the output from [HTTP::uri] to lower case using [string tolower [HTTP::uri]].

    The log output will be written to /var/log/ltm by default. You can run 'tail -f /var/log/ltm' from the command line to watch the output as you test. Hit Ctrl+c to stop the tail.

    Aaron