Forum Discussion

Scot_85536's avatar
Scot_85536
Icon for Nimbostratus rankNimbostratus
Jul 31, 2009

Can't read cookie on F5 terminated SSL?

Hey everyone,

 

I've got a VIP that I can connect to via HTTP and HTTPS, with the BigIP terminating the SSL with a client SSL profile. Nothing set for the server SSL profile as I don't need to encrypt the last leg to the server. On that VIP I'm trying to read a cookie with an irule. I can successfully read it on http requests, but not on https requests. Am I missing something? As I understood, as long as the F5 is terminating the SSL connection I should be able to read the cookie.

 

I'm trying to do something simple until I get it working:

 

if { [HTTP::cookie exists "customcookie"]} {

 

log "cookie customcookie value [HTTP::cookie customcookie]"

 

}

 

Thanks!

15 Replies

  • Can you try changing this line:

     

     

    node [HTTP::cookie F5NODEPERSIST]

     

     

    to:

     

     

    node [HTTP::cookie F5NODEPERSIST] 80

     

     

    and retest? If that doesn't work, it would really help to see the full iRule and the full log logs from a failure. I understand that there may be nothing more than log statements, but that's exactly what I want to see in order to understand what request(s) are being made and what commands are being run. It would help if you could prefix the log statements as log local0. "[IP::client_addr]:[TCP::client_port]: ". If you're using the same iRule on HTTP and HTTPS virtual servers, can you also add a log statement to the very beginning containing the local IP:port:

     

     

    log local0. "[IP::cient_addr]:[TCP::client_port]: New request to [IP::local_addr]:[TCP::local_port] for [HTTP::uri]"

     

     

    You can change the first two octets of the client and virtual server IP addresses to anonymize the logs.

     

     

    Aaron
  • Interesting... that fixed it Thanks Aaron!

     

     

    I thought it would automatically pick up the port from the pool member that I specify which is why I didn't specify a port, but apparently that's not the case. When I use the override I get the following errors, although the rule seems to work properly:

     

     

    Aug 5 12:37:56 tmm tmm[1086]: 01220001:3: TCL error: Rule HTTP-With-Unavailable - no such pool Failed Tcl_pool_GetFromObj: pool (line 1) invoked from within "active_members [LB::server pool] " ("default" arm line 3) invoked from within "switch [HTTP::uri] { "/maintenance" { if { [active_members [LB::server pool] ] > 0 } {HTTP::redirect http://$host} else { HTTP::respon..."

     

    Aug 5 12:37:56 tmm tmm[1086]: 01220001:3: TCL error: Rule HTTP-With-Unavailable - no such pool Failed Tcl_pool_GetFromObj: pool (line 15) invoked from within "active_members [LB::server pool] " ("default" arm line 3) invoked from within "switch [HTTP::uri] { "/maintenance" { if { [active_members [LB::server pool] ] > 0 } {HTTP::redirect http://$host} else { HTTP::respon..."

     

    Aug 5 12:37:56 tmm tmm[1086]: 01220001:3: TCL error: Rule HTTP-With-Unavailable - no such pool Failed Tcl_pool_GetFromObj: pool (line 15) invoked from within "active_members [LB::server pool] " ("default" arm line 3) invoked from within "switch [HTTP::uri] { "/maintenance" { if { [active_members [LB::server pool] ] > 0 } {HTTP::redirect http://$host} else { HTTP::respon..."

     

    Aug 5 12:37:56 tmm tmm[1086]: 01220001:3: TCL error: Rule HTTP-With-Unavailable - no such pool Failed Tcl_pool_GetFromObj: pool (line 15) invoked from within "active_members [LB::server pool] " ("default" arm line 3) invoked from within "switch [HTTP::uri] { "/maintenance" { if { [active_members [LB::server pool] ] > 0 } {HTTP::redirect http://$host} else { HTTP::respon..."

     

     

     

    Here's the complete rule now:

     

    when HTTP_REQUEST {

     

     

     

    sets the timer to return client to host URL

     

    set sectime 60

     

     

    Use the Host header value for the responses if it's set. If not, use the VIP address.

     

    if {[string length [HTTP::host]]}{

     

    set host [HTTP::host]

     

    set errhost1 [HTTP::host]

     

    set errhost2 [HTTP::host]

     

    } else {

     

    set host [IP::local_addr]

     

    set errhost1 "site"

     

    set errhost2 "the site"

     

    }

     

     

     

    switch [HTTP::uri] {

     

    "/maintenance" {

     

    if { [active_members [LB::server pool] ] > 0 } {HTTP::redirect http://$host}

     

    else { HTTP::respond 503 content "Maintenance page content=$sectime;url=http://$host>\

     

     

    503 - Service temporarily unavailable

    \

     

     

    We are performing routine maintenance designed to improve your $errhost1 experience. \

     

    We will have $errhost2 up again as soon as possible.

     

    \

     

    You will be automatically redirected to $errhost2 when it becomes available.

     

    " "Content-Type" "text/html"

     

    return

     

    }

     

    return

     

    }

     

    "/" {HTTP::redirect "http://$host[HTTP::uri]"

     

    return

     

    }

     

    default {

     

    If the pool is down, redirect to the maintenance page

     

    if { [active_members [LB::server pool] ] == 0 } {

     

    HTTP::respond 200 content \

     

    "

     

     

    "}

     

    }

     

    }

     

    if { [HTTP::cookie exists "F5NODEPERSIST"]} {

     

    node [HTTP::cookie F5NODEPERSIST] 80

     

    }

     

     

    if {[HTTP::uri] contains "/F5SERVERSELECT"} {

     

    set backendip [getfield [HTTP::uri] "&" 2]

     

    set backendip [getfield $backendip "/" 1]

     

    HTTP::respond 200 content "Persistence cookie set until browser is closed or cookies are cleared" "Set-Cookie" "F5NODEPERSIST=$backendip; path=/"

     

    return

     

    }

     

     

    }

     

     

    when HTTP_RESPONSE {

     

    HTTP::header insert SOURCE_ADDRESS [IP::server_addr]

     

    }
  • Good to hear the node command is working. To figure out why you're getting the TCL error on the pool check, you could try logging the LB::server pool output. It's probably related to the use of the node command. If you want to check the default pool state, you could save the pool name in CLIENT_ACCEPTED before the current pool has been changed:

     
     when CLIENT_ACCEPTED { 
      
        set default_pool [LB::server pool] 
     } 
     

    You can then reference $default_pool in the rest of the rule instead of using [LB::server pool]

    Aaron
  • I thought it might be because the F5 doesn't have to make a load balancing decision so it didn't have a pool name. Either way I reordered the rule so that it wouldn't be an issue. I now check to see if the override cookie is there, if not I check the pool to see how many members are up. I also added some on and off switches at the top to make things easier to keep track of. It's getting too big and complicated to just go in and comment stuff out when I want to turn things off. I've pasted my entire irule below for anyone that wants it. I'll also codeshare it.

     

     

     

     

    when HTTP_REQUEST {

     

     

    set some variables:

     

    sets the timer to return client to host URL

     

    set sectime 6

     

     

    if we want to redirect any uri's consisting of / to anywhere, set the following entries:

     

    0=off, 1=on

     

    set redirectdefaulturlon 0

     

    and set the URI that you want to redirect to:

     

    set redirectdefaulturl ""

     

     

    Turn on redirect of http to https?

     

    0=off, 1=on

     

    set redirectsecureon 0

     

     

    enable persistence override?

     

    0=off, 1=on

     

    set persistenceoverrideon 0

     

     

     

    set the incoming port, so we know what port to use on the server side

     

    if {[TCP::local_port] == 443} {

     

    set incomingport 80

     

    }

     

    else {

     

    set incomingport [TCP::local_port]

     

    }

     

     

    if { $persistenceoverrideon == 1 } {

     

    check for a cookie override on persistence

     

    if { [HTTP::cookie exists "F5NODEPERSIST"]} {

     

    node [HTTP::cookie F5NODEPERSIST] $incomingport

     

    log "[IP::client_addr]:[TCP::client_port]: New request to [IP::local_addr]:[TCP::local_port] for [HTTP::uri], sent to node [HTTP::cookie F5NODEPERSIST]:$incomingport"

     

    set activememberslbpool 1

     

    }

     

    else {

     

    set activememberslbpool [active_members [LB::server pool] ]

     

    }

     

     

    check if we need to set persistence override

     

    if {[HTTP::uri] contains "/F5SERVERSELECT"} {

     

    set backendip [getfield [HTTP::uri] "&" 2]

     

    set backendip [getfield $backendip "/" 1]

     

    HTTP::respond 200 content "Persistence cookie set until browser is closed or cookies are cleared" "Set-Cookie" "F5NODEPERSIST=$backendip; path=/"

     

    log "[IP::client_addr]:[TCP::client_port]: New request to [IP::local_addr]:[TCP::local_port] for [HTTP::uri]"

     

    return

     

    }

     

    }

     

    else {

     

    set activememberslbpool [active_members [LB::server pool] ]

     

    }

     

     

    Use the Host header value for the responses if it's set. If not, use the VIP address.

     

    if {[string length [HTTP::host]]}{

     

    set host [HTTP::host]

     

    set errhost1 [HTTP::host]

     

    set errhost2 [HTTP::host]

     

    } else {

     

    set host [IP::local_addr]

     

    set errhost1 "site"

     

    set errhost2 "the site"

     

    }

     

    check to see if we match any URI's, to do various things like 503 response, redirect, etc

     

    switch [HTTP::uri] {

     

    "/maintenance" {

     

    if { $activememberslbpool > 0 } {

     

    if { $redirectdefaulturlon == 1} {

     

    HTTP::redirect http://$host$redirectdefaulturl

     

    }

     

    else {

     

    HTTP::redirect http://$host

     

    }

     

    }

     

    else { HTTP::respond 503 content "Maintenance page content=$sectime;url=http://$host>\

     

     

    503 - Service temporarily unavailable

    \

     

     

    We are performing routine maintenance designed to improve your $errhost1 experience. \

     

    We will have $errhost2 up again as soon as possible.

     

    \

     

    You will be automatically redirected to $errhost2 when it becomes available.

     

    " "Content-Type" "text/html"

     

    return

     

    }

     

    return

     

    }

     

    "/" {

     

    if { $redirectdefaulturlon == 1 } {

     

    HTTP::redirect "http://$host$redirectdefaulturl"

     

    }

     

    return

     

    }

     

    default {

     

    If the pool is down, redirect to the maintenance page

     

    if { $activememberslbpool == 0 } {

     

    HTTP::respond 200 content \

     

    "

     

     

    "

     

    }

     

    return

     

    }

     

    }

     

     

    if { $redirectsecureon == 1 } {

     

    if { [TCP::local_port] == 80} {

     

    HTTP::redirect https://$host[HTTP::uri]

     

    return

     

    }

     

    }

     

     

    }

     

     

    when HTTP_RESPONSE {

     

    HTTP::header insert SOURCE_ADDRESS [IP::server_addr]

     

    }