For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

XFF Header Persistence iRule

Problem this snippet solves:

Identifies XFF headers and allows the selection of which header the iRule should persist on; assuming consistent ordering of multiple XFF headers. The iRule will work for single XFF headers as well, simply select 0 for the index.

How to use this snippet:

Instructions

  1. Fill in the Contributed by, Description, and iRule Source fields below.
  2. Select "SAMPLECODE" and other approprate categories.
  3. Add a meta description
  4. Include relevant iRule commands,events,etc used in this iRule.
  5. Delete this section.
  6. Click Save.

This iRule requires LTM v10. or higher. Contributed by: saltman

Code :

when HTTP_REQUEST {
     # iRule:         XFF Persistence iRule
     # Function:      Parse X-Forwarded-For header information and generate persistence records based on the selected header value
     #
     # Configuration Parameters: 
     #    xff_debug - set to 1 to enable debug logging, set to 0 to disable logging
     #    xff_header_index - select which XFF header to use in the list; 0 is the first element in the list
     #    persistence_timeout - select the duration of the persistence record in seconds    

     set xff_debug 1
     set xff_header_index 0
     set persistence_timeout 900
     set xff ''

     # Log the value for all XFF header(s)
     if {$xff_debug}{log local0. "[IP::client_addr]:[TCP::client_port]: [HTTP::method] to [HTTP::host][HTTP::uri], xff: [HTTP::header values X-Forwarded-For]"}

     if {[HTTP::header values X-Forwarded-For] ne ""}  {
           # Convert the XFF headers to a list; single items will be index 0
           set xff_list [split [HTTP::header values X-Forwarded-For] ,] 

           # Display the list elements
           for {set x 0} {$x< [llength $xff_list]} {incr x} {
                if {$xff_debug}{log local0. "XFF List Elements: Item $x [lindex $xff_list $x]"}
           }

           # Assign the preferred XFF element
           # Check to make sure the preferred index is available in the list
           if {$xff_header_index > [llength $xff_list]}{log local0. "ERROR: Preferred XFF header index is not present!"}
           
           set xff [lindex $xff_list $xff_header_index]
           if {$xff_debug}{log local0. "Preferred XFF Header Index is $xff_header_index with value of $xff"}
     
           # Log preferred XFF and show current record if one exists
           if {$xff_debug}{log local0. "[IP::client_addr]:[TCP::client_port]: Persisting on preferred XFF: $xff, existing record? [persist lookup uie $xff]"}

           # Set a persistence entry based on the preferred XFF
           persist uie $xff $persistence_timeout
     }    else {
           # No XFF header found in the payload
           if {$xff_debug}{log local0. "No XFF Header detected"}
     }
}

when SERVER_CONNECTED {
     # Log connection to identified server; show client and persistence record
     if {$xff_debug && $xff ne ""}{log local0. "[IP::client_addr]:[TCP::client_port]: Persistence record: [persist lookup uie $xff]"}
}
Published Mar 18, 2015
Version 1.0
No CommentsBe the first to comment