Persistence Cookie Parsing (TMOS 11.1+ compatible)
Problem this snippet solves:
Hi Folks,
the iRule below allows you to extract persistence cookie information as defined in SOL6917.
The provided iRule has support to extract persistence cookie information for:
- IPv4 pool members
- IPv4 pool members in non-default route domains
- IPv6 pool members
- IPv6 pool members in non-default route domains
The iRule stores the extracted information in the variable
$lb_select
in a [LB::select]
compatible format as outlined below.
pool /Common/MyPool member 10.0.0.1 80 pool /Common/MyPool member 10.0.0.1%1 80 pool /Common/MyPool member 2001:0112:0000:0000:0000:0000:0030:0030 80 pool /Common/MyPool member 2001:0112:0000:0000:0000:0000:0000:0030%1 80
Cheers, Kai
How to use this snippet:
- Integrate the provided code in your iRule to extract and analyse persistence cookie information.
- Tweak the
and$pool
variables as needed to match a hardcoded pool and your custom cookie names.$cookie_name
- Access the
variable to extract the persistence cookie information.$lb_select
- Enjoy!
Code :
when HTTP_REQUEST { # Setting the currently selected pool and cookie name set pool "[LB::server pool]" set cookie_name "BIGipServer[getfield $pool "/" 3]" # Inject the persistence cookie test values as outlined in SOL6917 # # IPv4 route domain disabled cookie value # HTTP::header replace "Cookie" "BIGipServer[getfield $pool "/" 3]=1677787402.36895.0000" # IPv6 route domain disabled cookie value # HTTP::header replace "Cookie" "BIGipServer[getfield $pool "/" 3]=vi20010112000000000000000000000030.20480" # IPv4 route domain enabled cookie value # HTTP::header replace "Cookie" "BIGipServer[getfield $pool "/" 3]=rd5o00000000000000000000ffffc0000201o80" # IPv6 route domain enabled cookie value # HTTP::header replace "Cookie" "BIGipServer[getfield $pool "/" 3]=rd3o20010112000000000000000000000030o80" # Trying to extract the persistence cookie value if { [HTTP::cookie value $cookie_name] ne "" } then { # A persistence cookie value is found. Enumerate the format of the persistence cookie value. switch -glob -- [HTTP::cookie value $cookie_name] { "rd*00000000000000000000ffff*" { # The received persistence cookie has an route domain enabled IPv4 format if { [scan [HTTP::cookie value $cookie_name] {rd%do00000000000000000000ffff%2x%2x%2x%2xo%d} rd oct1 oct2 oct3 oct4 port] == 6 } then { # The received persistence cookie is well formated. Contructing the lb select string. set lb_select "pool $pool member ${oct1}.${oct2}.${oct3}.${oct4}%$rd $port" } else { # The received persistence cookie is malformated. set lb_select "" } } "rd*" { # The received persistence cookie has an route domain enabled IPv6 format if { [scan [HTTP::cookie value $cookie_name] {rd%do%4[0-9a-fA-F]%4[0-9a-fA-F]%4[0-9a-fA-F]%4[0-9a-fA-F]%4[0-9a-fA-F]%4[0-9a-fA-F]%4[0-9a-fA-F]%[0-9a-fA-F]o%d} rd group1 group2 group3 group4 group5 group6 group7 group8 port] == 10 } then { # The received persistence cookie is well formated. Contructing the lb select string. set lb_select "pool $pool member ${group1}:${group2}:${group3}:${group4}:${group5}:${group6}:${group7}:${group8}%$rd $port" } else { # The received persistence cookie is malformated set lb_select "" } } "vi*" { # The received persistence cookie has an route domain disabled IPv6 format if { [scan [HTTP::cookie value $cookie_name] {vi%4[0-9a-fA-F]%4[0-9a-fA-F]%4[0-9a-fA-F]%4[0-9a-fA-F]%4[0-9a-fA-F]%4[0-9a-fA-F]%4[0-9a-fA-F]%[0-9a-fA-F].%d.} group1 group2 group3 group4 group5 group6 group7 group8 port] == 9 } then { # The received persistence cookie is well formated. Extracting the port information set port [format %04x ${port}] set port [expr { "0x[string range $port 2 3][string range $port 0 1]" }] # Contructing the lb select string. set lb_select "pool $pool member ${group1}:${group2}:${group3}:${group4}:${group5}:${group6}:${group7}:${group8} $port" } else { # The received persistence cookie is malformated set lb_select "" } } "*.*.*" { # The received persistence cookie has an route domain disabled IPv4 format if { [scan [HTTP::cookie value $cookie_name] {%d.%d.} ipv4 port] == 2 } then { # The received persistence cookie is well formated. Extracting the port information set port [format %04x $port] set port [expr { "0x[string range $port 2 3][string range $port 0 1]" }] # Extracting the IPv4 octets and contructing the lb select string. scan [format %08x $ipv4] "%2x%2x%2x%2x" oct4 oct3 oct2 oct1 set lb_select "pool $pool member ${oct1}.${oct2}.${oct3}.${oct4} $port" } else { # The received persistence cookie is malformated set lb_select "" } } default { # The received persistence cookie has an unknown format set lb_select "" } } } else { # The current request does not provide a persistence cookie set lb_select "" } # Log the extracted cookie information log local0.debug "Cookie Persistence Info: $lb_select" }
Tested this on version:
12.0Updated Jun 06, 2023
Version 2.0Kai_Wilke
My name is Kai Wilke and I'm working as a Principal Consultant for IT-Security at itacs GmbH - a German consulting company specialized in Microsoft Security cloud solutions, F5 customizations as well as for classic IT-Consulting.
You can find additional information about me and my work here:
https://devcentral.f5.com/articles/q-a-with-itacs-gmbhs-kai-wilke-devcentrals-featured-member-for-february-24890MVP
No CommentsBe the first to comment