F5 LTM Encrypted Cookie Insert Persistence

Originally posted on Packet Pushers on 20 October 2013.

The purpose of a load balancer is to distribute client connections to multiple servers to increase load capacity and provide high availability. One common requirement of load balanced applications, since most application servers maintain session information on the local box, is that a client must stay locked to a single server for the duration of the session. The ability of a load balancer to keep a client locked to the same server is known as persistence.

Note: An application can overcome the session persistence issue if it is architected to store session data in a centralized database of some sort. However, most applications are not designed this way.

One popular persistence method for HTTP traffic on the F5 LTM is cookie insert. Cookie insert is when the load balancer adds a session cookie to the clients session. With every request the client makes, it sends this cookie which the load balancer decodes to determine which server to send the client to. To understand this a little more, let’s look at a client request and server response from an F5 with cookie persistence. This is a capture from HTTPwatch with the client request on top and the server response on the bottom –

ef_profile_header

The client request was the first request to the server and does not have the cookie. Because of this the F5 inserts the persistence cookie in the response outlined in red. For the rest of this browser’s session it will put this cookie in each request as shown below –

ef_profile_header2

The cookie insert method is one of the best for HTTP because the client will have this cookie until the browser is restarted. Source IP on the other hand will time out after 180 seconds (by default) if no packets are sent.

Cookie Insert Information Leakage

While cookie insert is a great persistence method, the default settings create some security issues with information leakage. The default F5 cookie has the following format –

BIGipServertest_pool=335653056.20480.0000
BIGipServer<pool name>=<coded server IP>.<coded server port>.0000

The cookie tells us the following information –

  • BIGipServer – We now know that the server is behind an F5 BigIP device.
  • <pool name> – The name of the pool as configured on the F5.
  • <coded server IP> – The real IP of the server with a simple encoding method.
  • <coded server port> – The real port of the server with a simple encoding method.

As you can see quite a bit of information is leaked from this cookie. If you have penetration testing performed on your applications, the default cookie insert profile will show up as a security finding. The encoding method used for the server IP and port is a very simple method that can be easily decoded (you can find more information about encoding in the link at the end of the article). Using a decoding program I wrote in perl (also at the end of this article) you can gather this information from the cookie –

The persistence cookie decoded: 192.168.1.20:80

Plugging the Information Hole

Fortunately the F5 can be configured to not reveal this information. The first item will we tackle is the cookie name.

Changing Cookie Name
The default cookie name of BIGipServer<pool name> can be changed by creating a custom cookie persistence profile. To create the custom profile navigate to the menu as shown below –

ef_profile2

In the New Persistence Profile, set the following settings as shown –

ef_profile3

The settings should be –

  • Name – Something that makes sense.
  • Cookie Name – Check the custom box and enter a cookie name that does not conflict with any existing cookie names the application might use.

To apply this new profile, find your virtual server and click on the edit resources section in the virtual server list as shown –

ef_virtual1

Then select the cookie persistence profile just created as the default profile –

ef_virtual2

Now let’s take a look at the server response –

ef_profile_header3

As we can see the cookie name has changed as set in the profile and no longer has the pool name either. However, the server IP and port are still in the same format.

Encrypting the Cookie
The session cookie’s contents can be encrypted with a custom HTTP profile. To create the profile navigate to the window as shown –

ef_http1

In the Create New HTTP profile section set the fields as shown –

ef_http2

Change the settings as follows –

  • Name – Something that makes sense.
  • Encrypt Cookies – Check the custom box and enter the exact name you gave the cookie in the custom persistence profile.
  • Cookie Encryption Password – Check the custom box and enter a unique password.

Now you must go back to your virtual server and apply the custom HTTP profile you created –

ef_virtual3

Let’s double check the cookie by looking at a new server response –

ef_profile_header4

You can now see that the persistence cookie contents have been encrypted. The encryption cipher used is AES which by itself would turn it into a binary blob. The blob is then base64 encoded to make it compatible with a text protocol such as HTTP.

Your server info is no longer revealed and your security folks will be happy.

Cookie Decode Perl Script –

#!/usr/bin/perl
use strict;
use warnings;

my ($ip,$port) = split('\.',$ARGV[0]);
#Convert to IP to hex
my $ip_hex = sprintf("%x",$ip);
#Prepend extra 0 if hex value is only 7 char
$ip_hex = "0"."$ip_hex" if (length $ip_hex ==7);
#Decode hex to IP
my $d_ip = join ('.',map {hex $_} reverse ($ip_hex =~ m/../g));
#Decode hex to port
my $d_port = hex join("",reverse( sprintf("%x",$port) =~ m/../g) );

print "The persistence cookie decoded: $d_ip:$d_port\n";

Usage:

./f5_decode.pl 335653056.20480.0000

References –
F5 SOL6917: Overview of BIG-IP persistence cookie encoding
F5 SOL 7784: Overview of cookie encryption

Tagged , , . Bookmark the permalink.

Comments are closed.