Forum Discussion

shakalakka's avatar
shakalakka
Icon for Altostratus rankAltostratus
Aug 22, 2022

iRule and multiple switch-statements

So we need to filter based on both URIs and host-headers AND the source-IPs. I have tried using two switch-statements, with the same action for both if the client-IP-range matches - the first one works, but the second one doesnt seem to be evaluated. Any tips?

iRule:

when HTTP_REQUEST {
   set RESPONSE "<html><title>404 - NOT FOUND</title><body>404 - not found</body></html>"
   switch -glob [string tolower [HTTP::uri]] {
      "/someuri" -
      "/someuri/*"  {
         if { [matchclass [IP::client_addr] equals dg_blockthesehosts ] } {
            HTTP::respond 404 -version auto content $RESPONSE noserver "Content-Type" "text/html;charset=utf-8"
            TCP::close
            event disable
            return
         }
      }
   }
   switch -glob [string tolower [HTTP::host]] {
      "Host1.host.com" -
      "Host2.host.com" {
         if { [matchclass [IP::client_addr] equals dg_blockthesehosts ] } {
            HTTP::respond 404 -version auto content $RESPONSE noserver "Content-Type" "text/html;charset=utf-8"
            TCP::close
            event disable
            return
         }
      }
   }
}

 

  • Don't know if you're obfuscating for this post, but you have [string tolower [HTTP::host]] as the condition, but trying to evaluate mixed case strings (ex. Host1.host.com).

  • Yes, sorry, this is example-names, and should read host1.host1.com. 

    • shakalakka's avatar
      shakalakka
      Icon for Altostratus rankAltostratus

      But is something missing to open a second switch-statement? 

  • The second switch will indeed not fire if there's a URI match, since that is doing an 'event disable'. So the logic presumes that the request does not match the URI in order to do a match on the host.

    For giggles, try adding some logging and see what falls out:

     

    when HTTP_REQUEST {
       log local0. "host: [string tolower [HTTP::host]]"
    
       set RESPONSE "<html><title>404 - NOT FOUND</title><body>404 - not found</body></html>"
       switch -glob [string tolower [HTTP::uri]] {
          "/someuri" -
          "/someuri/*"  {
             log local0. "match URI: [string tolower [HTTP::uri]]"
             if { [matchclass [IP::client_addr] equals dg_blockthesehosts ] } {
                HTTP::respond 404 -version auto content $RESPONSE noserver "Content-Type" "text/html;charset=utf-8"
                TCP::close
                event disable
                return
             }
          }
       }
       switch [string tolower [HTTP::host]] {
          "host1.host.com" -
          "host2.host.com" {
             log local0. "match host: [string tolower [HTTP::host]]"
             if { [matchclass [IP::client_addr] equals dg_blockthesehosts ] } {
                HTTP::respond 404 -version auto content $RESPONSE noserver "Content-Type" "text/html;charset=utf-8"
                TCP::close
                event disable
                return
             }
          }
       }
    }

     

    • shakalakka's avatar
      shakalakka
      Icon for Altostratus rankAltostratus

      I will try. That is correct, the URI and host-header matching will not happen on the same site, so the logic is something like this:

      If you are a source-IP in dg_blockthesehosts:

      Give a 404 if you try to access /someuri/*

      OR:

      if you try to access host1.host.com or host2.host.com.

      They wont try to access host1.host.com/someuri.

       

  • Hi shakalakka,

    I hope this iRules will help you, 

     

    when HTTP_REQUEST {

    set httphost [string tolower [HTTP::host]]

    set httpuri [string tolower [HTTP::uri]]

    if { ($httphost contains “x1”) && ($httpuri contains “y1”) } {

    pool pool1

    } elseif { ($httphost contains “x2”) && ($httpuri contains “y2”) } {

    pool pool2

    } else {

    pool pool3

    }

    }

    More information >> cloud-ttrust  <<

     

  • Hello shakalakka,

    I've noticed that you didn't include default condition in your switch blocks, so I'm assuming second block might never be evaluated since code likely breaks at first evaluation. 

    I'm pretty sure that if you try to swap the two blocks and put HOST check first, it will start working and it will break URI check.

    Can you try this ?

     

    when HTTP_REQUEST {
       set RESPONSE "<html><title>404 - NOT FOUND</title><body>404 - not found</body></html>"
       switch -glob [string tolower [HTTP::uri]] {
          "/someuri" -
          "/someuri/*"  {
             if { [matchclass [IP::client_addr] equals dg_blockthesehosts ] } {
                HTTP::respond 404 -version auto content $RESPONSE noserver "Content-Type" "text/html;charset=utf-8"
                TCP::close
                event disable
                return
             }
          } default {}
       }
       switch -glob [string tolower [HTTP::host]] {
          "Host1.host.com" -
          "Host2.host.com" {
             if { [matchclass [IP::client_addr] equals dg_blockthesehosts ] } {
                HTTP::respond 404 -version auto content $RESPONSE noserver "Content-Type" "text/html;charset=utf-8"
                TCP::close
                event disable
                return
             }
          }
       }
    }