Forum Discussion

Christopher_Da1's avatar
Christopher_Da1
Icon for Nimbostratus rankNimbostratus
Aug 08, 2006

iRule to manipulate designation content based off ip/subnet

First of all I’m new to iRules and not familiar with the syntax.

 

 

I have composed an irule and the editor says the syntax is correct, but it doesn’t behave correctly or the way I intend for it to.

 

 

In need to permit the following traffic to a specific pool.

 

 

156.74.138.63

 

156.74.12.223

 

156.74.12.222

 

156.74.16.0/24

 

 

If the source isn’t one of the above the traffic should be redirected to

 

 

http://inweb.ci.seattle.wa.us/ccss/noaccess.asp

 

 

When I access the vip the irule is applied to from 156.74.138.63 I get a “The page cannot be displayed” error. Statically I can see hits on the irule, however it doesn’t work and yes the web server in the pool is up.

 

 

HELP!!!

 

 

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

 

 

when CLIENT_ACCEPTED {

 

if { [IP::addr [IP::client_addr] equals 156.74.138.63] } {

 

pool GWWEB-HTTP

 

}

 

elseif { [IP::addr [IP::client_addr] equals 156.74.12.223] } {

 

pool GWWEB-HTTP

 

}

 

elseif { [IP::addr [IP::client_addr] equals 156.74.12.222] } {

 

pool GWWEB-HTTP

 

}

 

elseif {not[IP::addr [IP::client_addr] equals 156.74.16.0/24] } {

 

set issue_redirect 1 }

 

else

 

{ pool GWWEB-HTTP

 

}

 

}

 

when HTTP_REQUEST {

 

if { $issue_redirect == 1 } { redirect to "http://inweb.ci.seattle.wa.us/ccss/noaccess.asp" }

 

}

 

 

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

 

  • Have you tried logging any data to see what's wrong with your logic? That should always be the first step in diagnosing a problem. One thing I noticed is that you'll want to use the HTTP::redirect command instead of "redirect to".

    when CLIENT_ACCEPTED {
      log local0. "client address: [IP::client_addr]"
      if { [IP::addr [IP::client_addr] equals 156.74.138.63] } {
        log local0. "matched address 156.74.138.63"
        pool GWWEB-HTTP
      } elseif { [IP::addr [IP::client_addr] equals 156.74.12.223] } {
        log local0. "matched address 156.74.12.223"
        pool GWWEB-HTTP
      } elseif { [IP::addr [IP::client_addr] equals 156.74.12.222] } {
        log local0. "matched address 156.74.12.222"
        pool GWWEB-HTTP
      } elseif {not[IP::addr [IP::client_addr] equals 156.74.16.0/24] } {
        log local0. "matched subnet 156.74.16.0/24"
        set issue_redirect 1
      } else { 
        log local0. "didn't match any addresses"
        pool GWWEB-HTTP
      }
    }
    when HTTP_REQUEST {
      log local0. "issue_redirect: $issue_redirect"
      if { $issue_redirect == 1 } {
        log local0. "issuing redirect..."
        HTTP::redirect "http://inweb.ci.seattle.wa.us/ccss/noaccess.asp"
      }
    }

    Run your traffic through this and then look at the /var/log/ltm file. It should point you right to your problem. Make sure you comment out or remove the log statements when you move this into production.

    -Joe
  • Thanks,

     

     

    After including the logging the following showed up in /var/log/ltm:

     

     

    Aug 8 14:05:18 tmm tmm[739]: Rule CCSS-IPADDRESS1 : client address: 156.74.138.63

     

    Aug 8 14:05:18 tmm tmm[739]: Rule CCSS-IPADDRESS1 : matched address 156.74.138.63

     

    Aug 8 14:05:19 tmm tmm[739]: 01220001:3: TCL error: Rule CCSS-IPADDRESS1 - can't read "issue_redirect": no such variable while executing "log local0. "issue_redirect: $issue_redirect""
  • Looks like you'll have to specifically set that variable to zero to avoid the no such variable error.

    when CLIENT_ACCEPTED {
      set issue_redirect 0
      log local0. "client address: [IP::client_addr]"
      if { [IP::addr [IP::client_addr] equals 156.74.138.63] } {
        log local0. "matched address 156.74.138.63"
        pool GWWEB-HTTP
      } elseif { [IP::addr [IP::client_addr] equals 156.74.12.223] } {
        log local0. "matched address 156.74.12.223"
        pool GWWEB-HTTP
      } elseif { [IP::addr [IP::client_addr] equals 156.74.12.222] } {
        log local0. "matched address 156.74.12.222"
        pool GWWEB-HTTP
      } elseif {not[IP::addr [IP::client_addr] equals 156.74.16.0/24] } {
        log local0. "matched subnet 156.74.16.0/24"
        set issue_redirect 1
      } else { 
        log local0. "didn't match any addresses"
        pool GWWEB-HTTP
      }
    }
    when HTTP_REQUEST {
      log local0. "issue_redirect: $issue_redirect"
      if { $issue_redirect == 1 } {
        log local0. "issuing redirect..."
        HTTP::redirect "http://inweb.ci.seattle.wa.us/ccss/noaccess.asp"
      }
    }

    Give that a whirl...

    -Joe
  • That did it!

     

     

    Thanks a lot!

     

     

    Tomorrow I will test it in the production environment.

     

     

    I’ll come back if need be.

     

     

    Thanks again!

     

     

    --cd

     

  • If your IP matching is going to grow, you could build a class to clean up the rule. Also, since I assume that this is all HTTP traffic, you could move all the logic to the HTTP_REQUEST event to avoid setting the variable (or use info exists in the CLIENT_ACCEPTED event).

    
    class my_exceptions {
      "156.74.138.63 GWWEB-HTTP"
      "156.74.12.223 GWWEB-HTTP"
      "156.74.12.222 GWWEB-HTTP"
      "10.10.10.10   DIFFERENT_POOL-HTTP"
    }
    when HTTP_REQUEST {
      if { [matchclass  [IP::client_addr] equals $::my_exceptions ]   } {
        log local0. "matched address [IP::client_addr] "
        pool [findclass [IP::client_addr] $::my_exceptions " " ]
      } elseif { not ( [IP::addr [IP::client_addr] equals 156.74.12.223 ] ) } {
          log local0. "matched subnet 156.74.16.0/24, issuing redirect..."
          HTTP::redirect "http://inweb.ci.seattle.wa.us/ccss/noaccess.asp"
      } else {
          log local0. "didn't match any addresses"
          pool GWWEB-HTTP
      }       
    }

    Note also that if you define GWWEB-HTTP as your default pool, you don't need the else statement...

    Also note that the class is not part of the rule, it needs to be added under the datagroups tab in the GUI, or simply paste into to the bigip.conf file at the CLI and do a bigpipe load.

    HTH

    BTW, this compiled without error in the iRule Editor, but is untested.
  • I forgot to mention that I threw that 10.10.10.10 DIFFERENT_POOL-HTTP entry into the class to show you that you can specify different sources within the class with different destinations and the pool substiution will take care of that in one command. What the findclass statement is doing is looking up your client IP in the class and taking the value after the space, which happens to be your pool name.
  • Thanks for the info. This irule is being put in place to keep unwanted traffic out during a test phase. If it becomes a permanent addition I will definitely change to your recommend logic.

     

     

    --cd
  • Deb_Allen_18's avatar
    Deb_Allen_18
    Historic F5 Account
    In iRules where the pool is dynamically selected, the "default" pool for traffic that falls through the rest of the conditions will be the last pool selected by the rule, rather than the default pool that is defined on the virtual server.

     

     

    So if you are conditionally choosing different pools, you probably DO want to include the "else" clause specifying the intended "default" pool.

     

     

    /deb
  • Great point. Whereas I think in this rule it would work without the else condition, setting it provides the necessary protection.