F5 LTM (Deep Dive) – Using ‘persist uie add’ with the ‘node’ command in an iRule causes the F5 to send a RST

Problem

When using the command “persist uie add” in conjunction with the “node” command within an iRule the F5 issues a RST back to both the client and server.

Background

Lets look at an example. First we`ll look at the configuration and then the resulting behaviour.

Configuration

You have the following configured,

  • You have persistence configured on a virtual server via the use of a Universal Persistence profile. Within the Universal Persistence profile you have an iRule attached (fig. irule example 1) thats uses the ‘persist add uie’ command.
  • Assigned to the virtual server you have an irule that uses the ‘node’ command (fig. irule example 2).
rule IRULE-COOKIEPERSIST {
     when HTTP_REQUEST {
        if { [HTTP::cookie exists "b1P"] } {
            persist uie [HTTP::cookie value "b1P"]
            set cookie_check 0    
         } else {
            set cookie_check 1
         }
    }
    when HTTP_RESPONSE {     
        if { $cookie_check eq 1 } {
            set now [clock seconds]
            set token "[IP::server_addr][expr { int(1000000 * rand()) }]"
            binary scan [md5 $token] H* md5var junk
            HTTP::cookie insert name "b1P" path / value $md5var\_$now
            persist add uie [HTTP::cookie "b1P"]
        }
    }
 }

<irule example 1>

rule IRULE-URIFORWARD { 
     when HTTP_REQUEST {
        if { [HTTP::uri] contains "Secure" } { 
            node 192.168.1.31 80
        } 
    }
 }

 <irule example 2>

Behaviour

  • At the point you issue a HTTP GET Request a RST is sent back to both the client and the server.
  • The following error can be observed within /var/log/ltm – ‘<HTTP_RESPONSE> – Prerequisite operation not in progress (line 1)’
  • If you issue a HTTP HEAD Request the headers are successfully received.
  • If you create a pool with the nodes IP as a pool member the request is successfully received.

Reason

The reason for this behaviour is because the ‘node’ command does not trigger the LB_SELECTED event which is a prerequisite for ‘persist uie add’.

Below shows each of the steps that occur prior to the RST`s being sent.

  1. The client sends a HTTP Request to the virtual server.
  2. The virtual server processes the request. This hits the iRule within the Universal Persistence profile first, then the iRule attached to the virtual server is processed.
  3. The request is then sent to the node via the ‘node’ command (fig. irule example 1).
  4. The server sends the response.
  5. Again the virtual server processes the response and the HTTP_RESPONSE event is triggered due to no cookie being seen within the initial request.
  6. The F5 then tries to execute the command “persist uie add” but fails as the LB_SELECTED event was not triggered by the previous node command (which is a prerequisite for ‘persist add uie’).
  7. The F5 sends a RST back to the client and the server and logs the appropriate log message.

Note : Though it appears that a HTTP HEAD request works actually both HEAD and GET fail and result in a RST. What really happens is the first packet of the response is sent back to the client just a fraction before the reset. Because of this if the response is only 1 packet in length it appears (by the client) the request/response is successful, even though the client receives both the response and RST.

Solution

There are 2 solutions. They are,

  1. Pool command – by using the ‘pool’ command instead of the ‘node’ command the LB_SELECTED event is triggered and the ‘persist uie add’ command is successfully executed.
  2. Changing the Priority – by placing the command “priority 1″ at the top of the iRule (i.e before the first event) that contains the ‘node’ command, you can ensure that the uie persistence iRule is not processed first. Then via the use of “event disable” you can ensure “persist uie add” is not executed. Below shows an example (fig irule example 3)
priority 1
rule IRULE-URIFORWARD { 
     when HTTP_REQUEST {
        if { [HTTP::uri] contains "Secure" } { 
            node 192.168.1.31 80
        } 
    }
    when HTTP_RESPONSE {
        event disable
    }
}

 <irule example 3>

 

Rick Donato

Want to become an F5 Loadbalancers expert?

Here is our hand-picked selection of the best courses you can find online:
F5 BIG-IP 101 Certification Exam – Complete Course
F5 BIG-IP 201 Certification Exam – Complete Course
and our recommended certification practice exams:
AlphaPrep Practice Tests - Free Trial