Forum Discussion

Benoit_Durand's avatar
Benoit_Durand
Icon for Nimbostratus rankNimbostratus
Feb 10, 2021

Are variables permeable across calls to the same iRule?

Greetings, My question is at the bottom. Some context first.

 

We have an LTM appliance inline with an ASM appliance (two appliances). LTM front ends the customer side and sends to ASM after. We have customers targetting some web VS by IP addresses (https://10.10.10.10) instead of by URL (https://www.website.com). ASM does not like the calls by IP and blocks them as being a threat. We cannot move away from those calls by IP address unfortunately. So, we were thinking of a simple iRule on LTM to manipulate the "host::" field of the header prior to sending to ASM and upon its return. Something like this:

 

when HTTP_REQUEST {

  if {not ([string tolower [HTTP::host]] starts_with "www.website.com")}{

    set hostname [HTTP::host]

     HTTP::header replace Host "www.website.com"

  }

}

 

when HTTP_RESPONSE {

  HTTP::header replace Host "$hostname"

}

 

Essentially, whatever HTTP::host the customer arrived with in HTTP_REQUEST is fed back to them in HTTP_RESPONSE via the variable "hostname".

 

My question: Can the variable "hostname" be modified by another instance of the same irule through another connection or is each variable specific to a particular connection? 

 

For example, if client A arrives with "http://10.10.10.10", the "HTTP_REQUEST" will set the variable "hostname" to "10.10.10.10" (presumably to later be fed back through HTTP_RESPONSE). However, if in the meantime client "B" arrives with "https://www.website.com", BEFORE the HTTP_RESPONSE comes through for client A, will Client A's "hostname" variable value still be at its original "10.10.10.10" value or will it have been modified to "www.website.com" by client B while A was waiting for a response?

 

Would there be a better approach to this? (other than telling Client A to start using URL instead of IP)

 

Thank you

 

  • Ben
  • To answer your question: Variables are local and session based by default.

     

    See https://devcentral.f5.com/s/articles/getting-started-with-irules-variables-20403

    "Local Variables

    All variables, unless otherwise specified, are created as local variables within an iRule. What does that mean? Well, a local variable means that it is assigned the same scope as the iRule that created it. All iRules are inherently session based, and as such all local variables are session based as well. This means that the session dictates the memory space for a given iRule's local variables and data. For instance, if connection1 comes in and an iRule executes, creating 5 variables, those variables will only exist until connection1 closes and the session is terminated on the BIG-IP. At that time the memory allocated to that flow will be freed up, and the variables created while processing that particular session's iRule(s) will no longer be accessible."

     

     

    However, why not just change the ASM policy? You can disable the "Host header contains IP address" violation for this policy.

     

    • Benoit_Durand's avatar
      Benoit_Durand
      Icon for Nimbostratus rankNimbostratus

      So by what you are saying, my variable would have different values each based on the specific session?

       

      About your question on ASM and the policy, I wish :) It's a corporate standard applied on all ASM and they don't want to deviate for particular cases :/ That would be too simple.

       

      Thanks again.

      • gersbah's avatar
        gersbah
        Icon for Cirrostratus rankCirrostratus

        Yes, that is correct. Unless you specifically make a variable global/static, it will not be shared accross sessions.

         

        One additional idea: You could disable the violation via iRule, if the ASM policy has ASM iRule events enabled. See here: https://support.f5.com/csp/article/K15573541

        Not sure if that would necessarily be "better", I just have an aversion against rewriting requests/responses.

         

        PS: One more thing regarding your initial idea. Server response doesn't typically include a host header. I don't think that header replace statement will ever do anything.

        If the server response has fully qualified links which are based on the request host header, you may have to rewrite those links in the response content (which could be difficult).