fir3net
PPS-Firenetbanner-780.5x190-30-03-17

F5 LTM - Cookie Persistence between HTTP and HTTPS

BACKGROUND

In order to to maintain persistence between services (such as HTTP and HTTPS) on a single Virtual Server two persistence methods are available ; Cookie Hashing and Source IP.

In order to perform "true" Cookie (insert) persistence across services an iRule is required.

Note : Though cookie persistence (insert) can be performed within the cookie persistence profile, this does not allow you to perform persistence across services when the pool members are on different backend ports (i.e HTTP->80 / HTTPS->81). 

SOLUTION

To maintain persistence across services an iRule is first created. This iRule is then assigned to a Universal Persistence profile which is then assigned to each of the Virtual Servers.

Cookie Types

Before we look at how the iRule(s) work it is worth mentioning the two main types of cookies. They are :

  • Persistent cookie - A persistent cookie has a date expiration. These cookies display when the cookie will expire under the Expires column (within the browser).
  • Session cookie - A session cookie does not have a date expiration set. These cookies display "session" under the Expires column (within the browser).

Note : The other types of cookies can be viewed here.

Overview

The iRule operates by creating a unique cookie which is provided to the client within the HTTP RESPONSE. This cookie value (UIE key) is also added to a universal persistance record on the F5 which is later referenced for any further HTTP REQUESTS.

Below is an example of a universal persistence record,

root@f5ltm(Active)(tmos)# show ltm persistence persist-records all-properties
Sys::Persistent Connections
universal - 172.16.100.10:80 - 192.168.1.31:80
-----------------------------------------------------------
  TMM           0
  Mode          universal
  Key           8abc87e0260ca1eddb577d37bf4018f5_1359498668
  Age (sec.)    6
  Virtual Name  VS-172.16.100.10-80
  Virtual Addr  172.16.100.10:80
  Node Addr     192.168.1.31:80
  Pool Name     POOL-172.16.100.10-80-A
  Client Addr   172.16.1.1

Note : The Age within the persistence record is an idle timeout. Meaning when a persistence look up is performed the Age is reset back to 0.

iRule Options

Because of the differences in how persistence should be performed there are 2 iRule options available here ; strict and standard.

Strict

View the iRule here

To ensure that a client session is only persistent for a fixed time period, the strict version is used. This adds an expiry time to the cookie. Unfortunately because not all browsers honour this expiry value, at the point the cookie is created a timestamp (using the EPOCH format) is also appended to the cookie value. This is then used to ensure that if the client sends a cookie that exceeds the timeout the connection is rebalanced.
This option works well for scenarios when session draining is required.

Within this iRule there are 2 variables that define the timeout. These are :

  • cookie_timeout - This value represents (in seconds) the amount of time between the cookie create time (appended EPOCH) and the current time.
  • cookie_expiry - This value represents (in seconds) the amount of time in seconds that will be added to the cookie expiry timeout. i.e should this value be set to 900 secs and the cookie create on the 15th April 2012 15:00 then the expiry time will be set to 15th April 2012 15:15.

Note : Both timeouts (by default) are set to 15minutes.

Standard

View the iRule here

With this option no expiry time is added to the cookie and the EPOCH timestamp is not referenced. The only value that mandates how long the session is persisted for is the Age value within the universal persistence record. However (as previously mentioned) as this is an idle timeout it can result in the client maintaining persistence to a single server for extremely long periods (i.e until the client stops sending traffic for the length of the universal persistence timeout).
This option is recommended if the application session also has a idle timeout. This ensures that the application session times out before the persistence record in turn preventing the situation where an existing session is being sent to a (newly balanced) backend server that has no knowledge of the session.

Note : Based on this you will need to ensure the idle timeout of the persistence record is longer then the idle timeout of the application. 

iRule Notes

  • For the iRule jedi`s out there, you may of noticed that in the iRule (standard) there is no logic that covers the event of a cookie being sent, but there being no corresponding persistence entry. In this scenario at the point the F5 performs a 'persist lookup' and no UIE entry is found then the traffic will be rebalanced and a new persistence entry created.
  • Though the EPOCH value is not used within the standard option, this value is still appended to the cookie to assist in any troubleshooting that may be required.

DEPLOYMENT

To deploy either of the 2 persistence options follow the steps below:

1. Create an iRule using on of the above options.
2. Create universal persistence profile using the following settings

ltm persistence universal PERSIST-COOKIE-HTTP_S { 
 defaults-from universal
 match-across-pools disabled
 match-across-services enabled
 match-across-virtuals disabled
 mirror disabled
 override-connection-limit disabled
 rule <IRULE NAME>
 timeout <???>
}

3. Assign the persistence profile to your Virtual Servers (i.e port 80 and 443).
4. Enable OneConnect on all Virtual Servers that the new persistence profile has been applied to.

TROUBLESHOOTING

Should persistence still fail or present problems there are a number of ways that you can troubleshoot. Typically I use a method of obtaining a string within the webpage to determine which server I am connected to. I then use a combination of curl (using the cookie options) and grep to determine if basic persistence is working.

However in circumstances where the issue centres around timeout issues with your persistence session then you can :

  1. Enable debugging within the iRule and remove the #_debug_# syntax for each of the log lines. These logs can then be viewed within /var/log/ltm.
  2. To also log the node that the traffic is sent to
    • add the $node variable to the log line
    • add the following syntax above each log line -- set node [persist lookup uie [HTTP::cookie value "b1P"] node]
  3. Add an entry to each log line for any other session cookie values that are being used. So that you can match up the life of the persistence cookie to that of your application session cookie.

Tags: BIG-IP F5, Persistence, Cookie

About the Author

RDonato

R Donato

Rick Donato is the Founder and Chief Editor of Fir3net.com. He currently works as a Principal Network Security Engineer and has a keen interest in automation and the cloud.

You can find Rick on Twitter @f3lix001