Forum Discussion

Chris_Miller's avatar
Chris_Miller
Icon for Altostratus rankAltostratus
Jun 28, 2010

Bit of Trouble iRule Logic

I have an iRule that handles persistence but also want to add logic that allows certain IPs to hit specific directories. I've defined a datagroup with the addresses that can hit these specific directories... Here's a basic rundown of my requirements: 1. Users who match my whitelist and specify a URI that contains 1A1 or 1A2 get sent to that pool. 2. Users who don't match my whitelist but specify a URI are passed through to the site but the switch/glob doesn't touch them. 3. Users who don't match my whitelist and don't specify a path are passed through and hit subsequent iRule text Here's my rule:
if { ([HTTP::header "True-Client-IP"] or [IP::addr[IP::client_addr]] eq $::whitelist)} {
switch -glob [HTTP::uri] {
      "*1A1*" { pool 1A1 }
      "*1A2*" { pool 1A2 }
     }
}
I have no problem with this being its own iRule and applying it to my VS, but if I do that, I'm unsure of how to close my "if" statement - I obviously don't want to reject them because if I'm understanding correctly, that will reject them if they don't meet both of the conditions above...

5 Replies

  • Maybe something like this?

    
    when CLIENT_ACCEPTED {
    
        Check client IP against the white list once per TCP connection
       if {[matchclass [IP::client_addr] equals whitelist]}{
          set check_uri 1
       } else {
          set check_uri 0
       }
    }
    when HTTP_REQUEST {
    
        Check the URI if the client IP was in the whitelist or if the True-Client-IP header is
       if { $check_uri or ([HTTP::header "True-Client-IP"] ne "" and [matchclass [HTTP::header "True-Client-IP"] equals whitelist)}{
    
           Check the requested URI
          switch -glob [HTTP::uri] {
             "*1A1*" { pool 1A1 }
             "*1A2*" { pool 1A2 }
          }
           The default action is to use the VS's default pool
       }
    }
    

    As you're only assigning a pool in some cases, you'll want to use a OneConnect profile on the VS. If you're not using SNAT on the VS, it would be good to use a custom OC profile with the source mask set to 255.255.255.255. This ensures the client IP is accurate in the server logs.

    Aaron
  • Posted By hoolio on 06/28/2010 08:44 AM

    Maybe something like this?

    when CLIENT_ACCEPTED {
    
        Check client IP against the white list once per TCP connection
       if {[matchclass [IP::client_addr] equals whitelist]}{
          set check_uri 1
       } else {
          set check_uri 0
       }
    }
    when HTTP_REQUEST {
    
        Check the URI if the client IP was in the whitelist or if the True-Client-IP header is
       if { $check_uri or ([HTTP::header "True-Client-IP"] ne "" and [matchclass [HTTP::header "True-Client-IP"] equals whitelist)}{
    
           Check the requested URI
          switch -glob [HTTP::uri] {
             "*1A1*" { pool 1A1 }
             "*1A2*" { pool 1A2 }
          }
           The default action is to use the VS's default pool
       }
    }
    

    As you're only assigning a pool in some cases, you'll want to use a OneConnect profile on the VS. If you're not using SNAT on the VS, it would be good to use a custom OC profile with the source mask set to 255.255.255.255. This ensures the client IP is accurate in the server logs.

    Aaron

    What if the VS doesn't have a default pool?
  • If the VS didn't have a default pool and a request didn't match any condition which specified a pool, the connection would be dropped. You could handle this by setting a pool in the iRule for all conditions. You can use return to avoid hitting the default pool selection in the iRule:

    
    when CLIENT_ACCEPTED {
    
        Check client IP against the white list once per TCP connection
       if {[matchclass [IP::client_addr] equals whitelist]}{
          set check_uri 1
       } else {
          set check_uri 0
       }
    }
    when HTTP_REQUEST {
    
        Check the URI if the client IP was in the whitelist or if the True-Client-IP header is
       if { $check_uri or ([HTTP::header "True-Client-IP"] ne "" and [matchclass [HTTP::header "True-Client-IP"] equals whitelist)}{
    
           Check the requested URI
          switch -glob [HTTP::uri] {
             "*1A1*" { pool 1A1; return }
             "*1A2*" { pool 1A2; return }
          }
       }
        If we haven't exited the event already, select a default pool
       pool default_pool
    }
    

    Aaron
  • Posted By hoolio on 06/29/2010 01:25 AM

    If the VS didn't have a default pool and a request didn't match any condition which specified a pool, the connection would be dropped. You could handle this by setting a pool in the iRule for all conditions. You can use return to avoid hitting the default pool selection in the iRule:

    when CLIENT_ACCEPTED {
    
        Check client IP against the white list once per TCP connection
       if {[matchclass [IP::client_addr] equals whitelist]}{
          set check_uri 1
       } else {
          set check_uri 0
       }
    }
    when HTTP_REQUEST {
    
        Check the URI if the client IP was in the whitelist or if the True-Client-IP header is
       if { $check_uri or ([HTTP::header "True-Client-IP"] ne "" and [matchclass [HTTP::header "True-Client-IP"] equals whitelist)}{
    
           Check the requested URI
          switch -glob [HTTP::uri] {
             "*1A1*" { pool 1A1; return }
             "*1A2*" { pool 1A2; return }
          }
       }
        If we haven't exited the event already, select a default pool
       pool default_pool
    }
    

    Aaron

    Thanks - in my case, I actually have another iRule that directs users to the correct pool based on cookies and if they don't have a cookie, it directs them to a pool (not specified as default in VS though) so I basically want that iRule to be executed if the user didn't query /1A1 or 1A2...if that makes sense.
  • Hi Chris,

     

     

    I'm a bit confused. Do you have two iRules? Can you post both iRules? Can you combine them? If not, which rule do you want to take precedence over the other?

     

     

    As Colin explained to me once, think of the pool command as a way to change a pointer. If you change the pointer to pool_1 and then later change the pointer to pool_2 (either in the same iRule or a different iRule), pool_2 will be used for the request.

     

     

    Aaron