For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Forum Discussion

AngryCat_52750's avatar
AngryCat_52750
Icon for Nimbostratus rankNimbostratus
Oct 24, 2013

iRule to a variable for chosen pool member

currently in our dev and qa environments, we have an iRule that staticly replaces a header for an application.. we can do it this way coz we only have one member in a pool..

when ACCESS_ACL_ALLOWED {
   HTTP::header replace Host "server1.domain.com"
}

In our prod environment, we have two members in the pool.. i am going to need to replace the static with a variable of the chosen pool member node...

Any ideas??

6 Replies

  • The LB_SELECTED event happens after the ACCESS_ACL_ALLOWED event, but then the HTTP_REQUEST_SEND event happens after all of that, so please give this a try:

    when HTTP_REQUEST_SEND {
        if { [class match [LB::server addr] equals my_host_lb_dg] } {
            clientside {
                HTTP::header replace Host [class match -value [LB::server addr] equals my_host_lb_dg]
            }
        }
    }
    

    where "my_host_lb_dg" is an arbitrary string-based data group that maps the pool member IPs to corresponding host names. Example:

    10.70.0.1 := foo.example.com
    10.70.0.2 := bar.example.com
    10.70.0.3 := test.example.com
    
  • i have more code in the when ACCESS_ACL_ALLOWED.. i am wondering i can move it all to the HTTP_REQUEST_SEND event..

     

    what we have now

     

    when ACCESS_ACL_ALLOWED {
       set user [ACCESS::session data get "session.logon.last.username"]
       set uri [string range [HTTP::uri] 3 end]
       HTTP::header replace "APP_USER" $user
       HTTP::header replace Host "server1.domain.com:8080"
       HTTP::uri $uri
    }
    when HTTP_RESPONSE {
    if { [HTTP::header "Location"] contains "server1" } {
    HTTP::header replace Location [string map {"server1.domain.com:8080" "app.example.com/app"} [HTTP::header value Location]] }

    }

     

    What i think we need.

     

    when HTTP_REQUEST_SEND {
        if { [class match [LB::server addr] equals prod_servers] } {
            serverside {
                set user [ACCESS::session data get "session.logon.last.username"]
                set uri [string range [HTTP::uri] 3 end]
                HTTP::header replace "APP_USER" $user
                HTTP::header replace Host "[class match -value [LB::server addr] equals prod_servers]:8900"
                HTTP::uri $uri
            }
        }
    }
        when HTTP_RESPONSE {
        if { [HTTP::header "Location"] starts_with "prodserver" } {
        HTTP::header replace Location [string map {"[class match -value [LB::server addr] equals prod_servers]:8080" "prod_app.example.com/app"} [HTTP::header value Location]] }
    }

    What do you think??

     

  • You should be guaranteed that the access session exists when you get to the HTTP_REQUEST_SEND event, so that should work.

     

  • Kevin, when using the HTTP_REQUEST_SEND, i get this error in the logs -

     

    TCL error: /Common/irule-app-test - Illegal argument. Can't execute in the current context. (line 2) invoked from within "HTTP::uri"invalid serverside expression (line 3) invoked from within "serverside { set user [ACCESS::session data get "session.logon.last.username"] set uri [string range [HTTP::uri] 3 end] ..."

     

  • You're passing headers to the server in the client side context, so you need the clientside expression, not serverside.

     

  • i actually had to split the events to do the different things i needed.. i ended up with this-

    when ACCESS_ACL_ALLOWED { 
        set user [ACCESS::session data get "session.logon.last.username"] 
        set uri [string range [HTTP::uri] 3 end] 
        HTTP::header replace "APP_USER" $user
            HTTP::uri $uri
        }
    when HTTP_REQUEST_SEND {
        if { [class match [LB::server addr] equals server-dev] } {
            clientside {
                HTTP::header replace Host "[class match -value [LB::server addr] equals server-dev]:9000"
                }
            }
        }   
    when HTTP_RESPONSE {
        if { [HTTP::header "Location"] starts_with "devserver" } {
        HTTP::header replace Location [string map {"[class match -value [LB::server addr] equals server-dev]:9000" "company.domain.com/app"} [HTTP::header value Location]] }
    }
    

    Thanks for your valuable input on this..