Forum Discussion

Jimmy20's avatar
Jimmy20
Icon for Nimbostratus rankNimbostratus
Jun 10, 2020

Need help on Understanding mentioned iRules

Hello All,

 

Requesting help to understand below iRules.

 

1) iRule-1

 

when HTTP_REQUEST {

 # save hostname for use in response

 set fqdn_name [HTTP::host]

}

when HTTP_RESPONSE {

 if { [HTTP::is_redirect] }{

  if { [HTTP::header Location] starts_with "/" }{

   HTTP::header replace Location "https://$fqdn_name[HTTP::header Location]"

  } else {

   HTTP::header replace Location "[string map {{http://} {https://}} [HTTP::header Location]]"

  }

 }

}

+++++++++++++++++++++++++++++++++++++++

 

2) iRule-2

 

when CLIENT_ACCEPTED {

if {[matchclass [IP::client_addr] equals $::ins-prod-xyz_class]} {

      snatpool xyz_prod_snatpool

    }

}

 

++++++++++++++++++++++++++++++++++++++++

 

3) iRule-3

priority 0

when HTTP_REQUEST { if { [class match [string tolower [HTTP::header "User-Agent"]] contains undesired_agents_class ] } { drop } }

 

+++++++++++++++++++++++++++++++++++++++++

 

4) iRule-4

 

when HTTP_REQUEST {

if { [string tolower [HTTP::host]] equals "learn.x1y2z3.com" } {

HTTP::respond 301 Location "https://www.abc.com/health-learn/quote/"

}

}

 

 

 

  • Hi,

    First, let's know about events:

    HTTP_REQUEST:

    An iRule event triggered when the system fully parses the complete client HTTP request headers (that is, the method, URI, version, and all headers, not including the HTTP request body).

    HTTP_RESPONSE:

    An iRule event triggered when the system parses all of the response status and header lines from the server response.

    Note: HTTP_RESPONSE is specific to a server response passing through the load balancer, and is not triggered for locally-generated responses (e.g. sent using the HTTP::respond command)

    CLIENT_ACCEPTED:

    An iRule event triggered when a client has established a connection.

    Complete documentation for all commands, see:

    https://clouddocs.f5.com/api/irules/

    Rule #1:

    # When client send a HTTP request
    when HTTP_REQUEST {
        # save hostname for use in response
        #
        #Stores a variable with FQDN hostname (and port when explicit) from host header during client request.
        set fqdn_name [HTTP::host]
        #
        # e.g.
        # HTTP request header
        #
        # GET /path/page?param=value HTTP/1.1
        # Host: www.mysite.com
        # User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36
        # Accept: */*
        #
        #
        # fqdn_name = www.mysite.com
    }
     
    # When server respond that HTTP request
    when HTTP_RESPONSE {
        # Check if the server response is a redirection to another location
        # e.g.
        #
        # HTTP/1.1 302 Found
        # Location: /login
        # Connection: Keep-Alive
        # Content-Length: 0
        #
        #
        if { [HTTP::is_redirect] }{
            # If Location header starts with "/", means that you were implicited redirected to a resource on same FQDN and protocol.
            # e.g.
            # Location: /login (Implicit location http://www.mysite.com/login)
            # Location: http://www.mysite.com/login (Explicit location)
            #
            if { [HTTP::header Location] starts_with "/" }{
                # Rewrite Location header to redirect to https protocol and fqdn stored on variable plus location address before send response to client
                HTTP::header replace Location "https://$fqdn_name[HTTP::header Location]"
                # e.g.
                # Location: /login - rewrite to - Location: https://www.mysite.com/login
                #
            } else {
                # Else, rewrite/replace protocol http to https on that location
                HTTP::header replace Location "[string map {{http://} {https://}} [HTTP::header Location]]"
                # e.g.
                # Location: http://www.mysite.com/login - rewrite to - https://www.mysite.com/login
                # Location: https://www.mysite.com/login - nothing to match or do
            }
        }
    }

    Rule #2:

    # When client is connected to VS
    when CLIENT_ACCEPTED {
    # Check that the client's IP matches a record within data group wich name is stored in the static variable: $::ins-prod-xyz_class
        if { [matchclass [IP::client_addr] equals $::ins-prod-xyz_class] } {
            # If so, do a source address translation with addresses within a snat pool
            snatpool xyz_prod_snatpool
        }
    }

    Rule #3:

    # Set order to be first on execution
    # If you have multiple rules attached in VS, it should be the first request event to run
    # https://clouddocs.f5.com/api/irules/priority.html
    priority 0
    when HTTP_REQUEST { 
      # Drop requests when user-agent/client browser is in a blacklist stored in datagroup
      if { [class match [string tolower [HTTP::header "User-Agent"]] contains undesired_agents_class ] } {
        drop 
      }
    }

    Rule #4:

    when HTTP_REQUEST {
        # if host is learn.x1y2z3.com, then send HTTP 301 to redirect to that location
        # HTTP 301 = Moved Permanently
        if { [string tolower [HTTP::host]] equals "learn.x1y2z3.com" } {
            HTTP::respond 301 Location "https://www.abc.com/health-learn/quote/"
        }
    }

    Is it clear? I hope it helps.

    Regards

  • Hi CJ,

     

    This is perfect, will spend some more time on your reply and back to you/forum in case of any query.

     

    Well...sorry but i missed to add 02 more iRules in my prior post,

     

    5) iRule-5

     

    when HTTP_REQUEST {

        set app_pool [class match -value -- [string tolower [HTTP::uri]] starts_with services_produat_redirect_class]

        if {$app_pool ne ""} {

          pool $app_pool

        } else {

         pool abc_uat_pool1

        }

      }

     

    Here : what is this service "services_produat_redirect_class" , Is this a custom one or pre-defined one...if custom then..where should i find and check from GUI that what all configuration has been defined under this service.

     

    ++++++++++++++++++++++++

     

     

    6) iRule-6

     

    when HTTP_REQUEST {

        set app_pool [class match -value -- [string tolower [HTTP::uri]] starts_with services_redirect_class_8085]

        if {$app_pool ne ""} {

          pool $app_pool

        } else {

         return

        }

      }

     

    Here : what is this service "services_redirect_class_8085" , Same query as in iRule-5...Is this a custom one or pre-defined one...if custom then...where should i find and check from GUI that what all configuration has been defined under this service.

    • cjunior's avatar
      cjunior
      Icon for Nacreous rankNacreous

      These data groups are custom defined. You find all ltm data groups on menu:

      Local Traffic >> iRules >> Data Group List

       

      The rules are searching for a pool name based on URI on within dg, then if found (not equals empty), request are send to this pool name, otherwise return or send to a default pool.

       

      Regards.

      • Jimmy20's avatar
        Jimmy20
        Icon for Nimbostratus rankNimbostratus

        So here by "$app_pool" meaning a default pool only.

  • Hello CJ,

     

    Could you please explore more on below iRule :

     

    when HTTP_REQUEST {

        set app_pool [class match -value -- [string tolower [HTTP::uri]] starts_with services_redirect_class_8085]

        if {$app_pool ne ""} {

          pool $app_pool

        } else {

         return

        }

      }

     

    As per your previous reply, I understand...that the rules are searching for a pool name based on URI OR within Data Group, If found (not equals empty), request are send to this pool name, otherwise return... (but return to where ...back to search criteria..?) 

    • cjunior's avatar
      cjunior
      Icon for Nacreous rankNacreous

      Hello,

       

      The "return" command tells to exit/break from event HTTP_REQUEST. In your iRule the return looks disposable since it don't have code to escape after "return".

       

      Example when return could be useful:

      {
          If { condition 1 matches } {
            Do something here
          } Else {
            return
          }
       
          # This and lines below are reacheable only if condition 1 above is met
          If { condition 2 matches } {
            Do something here
          }
          Do something here
          and on
      }

      Regards