encrypted cookie generation and decryption
Problem this snippet solves:
- AES::key command in RULE_INIT event doesn't have compatibility with CMP
- generate dynamic cooke to provide http client and encrypted the cookie before providing to client.
How to use this snippet:
Generate key to use in iRule.
when RULE_INIT { log local0. "key value : [b64encode [AES::key 256]]" }
If iRule is saved in BIG-IP, the command is executed and log on /var/log/ltm file.
Rule /Common/aes_key <RULE_INIT>: key value : QUVTIDI1NiAxYTIyZTdlMzMxZDBhYmQ0NTNlYTVlMTJhODdhZThiNTdmMjRiZGUwYjZiNDI1YzYwZmMxNDk0ZjNkYzNlMmRi
The generated key can be used in any iRule, and the key must to keep in secure place (place in iRule only)
when RULE_INIT { set static::my_key_256 "QUVTIDI1NiAxYTIyZTdlMzMxZDBhYmQ0NTNlYTVlMTJhODdhZThiNTdmMjRiZGUwYjZiNDI1YzYwZmMxNDk0ZjNkYzNlMmRi" set static::my_key $static::my_key_256 } when HTTP_REQUEST { ... # cookie encryption with dynamic value set cookie_data "[IP::client_addr]:[clock seconds]:MY_COOKIE" set b64_enc_cookie "[b64encode [AES::encrypt [b64decode $static::my_key] $cookie_data]]" HTTP::respond 302 -version 1.1 Location "http://[HTTP::host][HTTP::uri]" Set-Cookie "MyCookie=$b64_enc_cookie" ... # cookie decryption set d_data [AES::decrypt [b64decode $static::my_key] [b64decode [HTTP::cookie MyCookie]]] ... }
Code :
when RULE_INIT { # key value and select one of key to decipher HTTP Cookie # 256 bit key set static::my_key_256 "QUVTIDI1NiAxYTIyZTdlMzMxZDBhYmQ0NTNlYTVlMTJhODdhZThiNTdmMjRiZGUwYjZiNDI1YzYwZmMxNDk0ZjNkYzNlMmRi" # Select one of key set static::my_key $static::my_key_256 log local0. "selected key : $static::my_key" # cookie life time set static::cookie_lifetime "600" # cookie re-generation time before expire set static::cookie_exp "15" } when HTTP_REQUEST { # Debug log setting # enable : 1 # disable : 0 set DEBUG 1 # Cookie data : client_IP::MY_COOKIE # check cookie value is existence if { [HTTP::cookie MyCookie] ne "" } { # decrypt cookie data set d_data [AES::decrypt [b64decode $static::my_key] [b64decode [HTTP::cookie MyCookie]]] if { $DEBUG } { log local0. "cookie value : [HTTP::cookie MyCookie]" } if { $DEBUG } { log local0. "decrypted cookie value : $d_data" } # check decryption status / set dummy value if the decryption was failed (empty string) if { $d_data ne "" } { set cookie_data [split $d_data ":"] } else { # set dummy data to send new cookie set cookie_data {0.0.0.0 1458328520 COOKIE_DUM} if { $DEBUG } { log local0. "decryption faile (by changing key) and set dummy value" } } if { (([clock seconds] - [lindex $cookie_data 1]) <= ($static::cookie_lifetime - $static::cookie_exp)) && ([lindex $cookie_data 2] eq "MY_COOKIE") } { if { $DEBUG } { log local0. "allowed request : [HTTP::host][HTTP::uri]" } } else { # cookie is invalid or expire soon, and set a new cookie if { $DEBUG } { log local0. "cookie value is invalid or expired and re-generate a new cookie" } call redirect_with_cookie $DEBUG } # HTTP request doesn't have MyCookie } else { if { $DEBUG } { log local0. "No MyCookie cookie in HTTP request and generate a new cookie" } call redirect_with_cookie $DEBUG } } proc redirect_with_cookie args { set cookie_data "[IP::client_addr]:[clock seconds]:MY_COOKIE" set b64_enc_cookie "[b64encode [AES::encrypt [b64decode $static::my_key] $cookie_data]]" if { $args } { log local0. "new generated cookie : $b64_enc_cookie" } HTTP::respond 302 -version 1.1 Location "http://[HTTP::host][HTTP::uri]" Set-Cookie "MyCookie=$b64_enc_cookie" }
Updated Jun 06, 2023
Version 2.0wonsoo_41223
Historic F5 Account
Joined January 04, 2011
- Daniel_VarelaEmployeeHi Wonsoo, very nice and neat irule. I have a question, HTTP profiles already allow us to encrypt cookies, we just need to specify the cookie name and passphrase. I am not sure which encryption method is used but probably is enough for the majority of the cases and more efficient. AES command is quite resource demanding for the nature of the operation. Am I missing something? Thanks!