Encrypt HTTP cookies with dynamic names

Problem this snippet solves:

This example iRule encrypts cookies whose names match a given pattern.

The specific use case is to allow an admin to apply one iRule to multiple virtual servers and encrypt all of the BIG-IP persistence cookies regardless of their specific name. So the iRule checks if the request/response cookies match the persistence cookie prefix of BIGipServer. This could easily be changed to any other string glob pattern to encrypt application set cookies.

Note that you should use this iRule on 11.2 or higher to take advantage of the fix to HTTP::cookie encrypt:

https://devcentral.f5.com/community/group/asg/50/aft/1178469/showtab/groupforums Note also that the HTTP::cookie encrypt and decrypt commands were also fixed in 11.2, and so should no longer be any slower than configuring cookie encryption via the HTTP profile.

Code :

when RULE_INIT {

# Cookie name prefix
set static::ck_pattern "BIGipServer*"

# Log debug to /var/log/ltm? 1=yes, 0=no)
set static::ck_debug 1

# Cookie encryption passphrase
# Change this to a custom string!
set static::ck_pass "mypass1234"
}
when HTTP_REQUEST {

if {$static::ck_debug}{log local0. "Request cookie names: [HTTP::cookie names]"}

# Check if the cookie names in the request match our string glob pattern
if {[set cookie_names [lsearch -all -inline [HTTP::cookie names] $static::ck_pattern]] ne ""}{

# We have at least one match so loop through the cookie(s) by name
if {$static::ck_debug}{log local0. "Matching cookie names: [HTTP::cookie names]"}
foreach cookie_name $cookie_names {

# Decrypt the cookie value and check if the decryption failed (null return value)
if {[HTTP::cookie decrypt $cookie_name $static::ck_pass] eq ""}{

# Cookie wasn't encrypted, delete it
if {$static::ck_debug}{log local0. "Removing cookie as decryption failed for $cookie_name"}
HTTP::cookie remove $cookie_name
}
}
if {$static::ck_debug}{log local0. "Cookie header(s): [HTTP::header values Cookie]"}
}
}
when HTTP_RESPONSE {

if {$static::ck_debug}{log local0. "Response cookie names: [HTTP::cookie names]"}

# Check if the cookie names in the request match our string glob pattern
if {[set cookie_names [lsearch -all -inline [HTTP::cookie names] $static::ck_pattern]] ne ""}{

# We have at least one match so loop through the cookie(s) by name
if {$static::ck_debug}{log local0. "Matching cookie names: [HTTP::cookie names]"}
foreach cookie_name $cookie_names {

# Encrypt the cookie value
HTTP::cookie encrypt $cookie_name $static::ck_pass
}
if {$static::ck_debug}{log local0. "Set-Cookie header(s): [HTTP::header values Set-Cookie]"}
}
}
Published Mar 17, 2015
Version 1.0

Was this article helpful?