Persistence Cookie Logger

Problem this snippet solves:

Extracts the cookie value from a persistence cookie inserted by LTM's "cookie insert" persistence method, decodes the node IP and port and logs them along with the requesting client's IP address. (If no cookie is found, that's logged as well.) Useful for troubleshooting cookie persistence. Only use this rule for v9. It still needs to be udpated for CMP compliance with v10/v11.

Edit the RULE_INIT section to reflect the actual name of the cookie inserted, which defaults to BIGipServer .

Refer to SOL6917: Overview of BIG-IP LTM cookie encoding for the cookie persistence profile for cookie encoding details.

Code :

rule persistence_cookie_logger {

when RULE_INIT {
  # see AskF5 SOL6917 for cookie encoding details: 
  # https://support.f5.com/kb/en-us/solutions/public/6000/900/sol6917.html
  set ::myCookieName BIGipServerXXXX
  set ::debug 0
}

when HTTP_REQUEST {
  # grab encoded cookie value & parse into relevant pieces
  if {[HTTP::cookie exists $::myCookieName]}{
    scan [HTTP::cookie $::myCookieName] {%[^\.].%d.%d} myIpE myPortE unused
    if {$::debug != 0}{log local0. "myIpD=$myIpE   myPortE=$myPortE  unused=$unused"}

    # calculate IP
    # %08x format strings forces padding w/leading 0's to 8 char string
    set myIpH [format %08x $myIpE]
    if {$::debug != 0}{log local0. "myIpH=$myIpH"}
    set myIpD1 [expr 0x[substr $myIpH 6 2]]
    set myIpD2 [expr 0x[substr $myIpH 4 2]]
    set myIpD3 [expr 0x[substr $myIpH 2 2]]
    set myIpD4 [expr 0x[substr $myIpH 0 2]]
    set myIpD "$myIpD1.$myIpD2.$myIpD3.$myIpD4"
    if {$::debug != 0}{log local0. "myIpD=$myIpD"}

    # calculate port
    set myPortH [format %04x $myPortE]
    if {$::debug != 0}{log local0. "myPortH=$myPortH"}

    set myPortD [string trimleft [expr 0x[substr $myPortH 2 2][substr $myPortH 0 2]] 0]
    if {$::debug != 0}{log local0. "myPortD=$myPortD"}

    # log results
    log local0. "Request from client: \
      [IP::remote_addr]:[TCP::remote_port] contains persistence cookie \
        referencing pool member $myIpD:$myPortD"
  } else { 
    log local0. "Request from client: [IP::remote_addr]:[TCP::remote_port] \
      contains NO persistence cookie"
  }
}

}

# And the inverse process of encoding an IP address and port into the LTM cookie format in an iRule (from UnRuley's post here):

# https://devcentral.f5.com/s/Default.aspx?tabid=53&forumid=5&tpage=1&view=topic&postid=9756

# Generate a persistence cookie for a sample IP:port
when HTTP_RESPONSE {
   set addr "10.10.10.10:80"
   scan $addr "%u.%u.%u.%u:%u" a b c d e
   set cookie "[format %u [expr {($d<<24)|($c<<16)|($b<<8)|$a}]].[expr {256*$e}].0000"
   HTTP::cookie insert name "BIGipServerFP_pool" value $cookie path "/"
}

# Sample Logs

# New request with no persistence cookie:
Rule persistence_cookie_logger_rule :   10.1.0.1:62606: Request for 10.1.0.15/ contains no persistence cookie
Rule persistence_cookie_logger_rule :    10.1.0.1:62606: New member selected: ubuntu_external_http_pool 10.1.0.101 80
Rule persistence_cookie_logger_rule : 10.1.0.1:62606: New member connected: 10.1.0.101:80
Rule persistence_cookie_logger_rule :  10.1.0.1:62606: Persistence cookie in Set-Cookie header(s): {BIGipServerubuntu_external_http_pool=1694499082.20480.0000; path=/}

# Request with a valid persistence cookie:
Rule persistence_cookie_logger_rule :   10.1.0.1:62894: Request for 10.1.0.15/ contains persistence cookie 1694499082.20480.0000 referencing pool member 10.1.0.101:80
Rule persistence_cookie_logger_rule :    10.1.0.1:62894: Persistence member 10.1.0.101:80 selected successfully
Rule persistence_cookie_logger_rule : 10.1.0.1:62894: Persistence member 10.1.0.101:80 connected to successfully

# Request with a persistence cookie for a downed pool member:
Rule persistence_cookie_logger_rule :   10.1.0.1:62932: Request for 10.1.0.15/ contains persistence cookie 1677721866.20480.0000 referencing pool member 10.1.0.100:80
Rule persistence_cookie_logger_rule :    10.1.0.1:62932: Persistence member 10.1.0.100:80 is not the selected member ubuntu_external_http_pool 10.1.0.101 80. State of pool member from persistence cookie: down
Rule persistence_cookie_logger_rule : 10.1.0.1:62932: Persistence member 10.1.0.100:80 is not the connected member 10.1.0.101:80. State of pool member from persistence cookie: down
Rule persistence_cookie_logger_rule :  10.1.0.1:62932: Persistence cookie in Set-Cookie header(s): {BIGipServerubuntu_external_http_pool=1694499082.20480.0000; path=/}
Published Mar 18, 2015
Version 1.0
  • I am using source address persistence not cookie.