on
15-Oct-2015
03:42
- edited on
05-Jun-2023
22:22
by
JimmyPackets
Problem this snippet solves:
Simple iRule to read the XFF header on an incoming HTTP Request and use a Universal Persistence ID. Orginal iRule found to have an issue with multiple IP addresses in the XFF header for changed to only pass the first XFF IP.
I have updated the iRule line to account for systems where multiple 'X-Forwarded-For' headers have been added.
persist uie [lindex [ split [HTTP::header X-Forwarded-For] "," ] 0]
to
persist uie [lindex [ split [lindex [HTTP::header values X-Forwarded-For] 0] "," ] 0]
thanks to the advice from Yann Desmarest. This could also be done with the 'getfield' command see Yann's comments below.
How to use this snippet:
Create iRule using following code (mine is named 'persist_xff_uie') Create Universal Persistence Profile with iRule set to 'persist_xff_uie' (or what ever name you assign to the iRule) Assign Universal Persistence Profile to Virtual Server (ensure virtual server has HTTP profile assigned)
Code :
# Name: persist_xff_uie # # To be used with UIE Persistence Profile # # Checks HTTP Request for 'X-Forwarded-For' header and if exists takes the first 'X-Forwarded-For' IP address as sets as # Persist identifier. # If the 'X-Forwarded-For' header does not exist then the client IP address is set as Persist identifier. when HTTP_REQUEST { if {[HTTP::header X-Forwarded-For] != ""} then { persist uie [lindex [ split [lindex [HTTP::header values X-Forwarded-For] 0] "," ] 0] } else { persist uie [IP::client_addr] } }
Tested this on version:
11.5Hi,
I recommand you to change :
[lindex [ split [HTTP::header X-Forwarded-For] "," ] 0]
by
[getfield [lindex [HTTP::header values X-Forwarded-For] 0] "," 1]
If the request contains multiple X-Forwarded-For headers, your code just take the latest header value. Not the first one.
Yann, You are correct for most headers where multiple headers exist with the same name however the XFF header gets appended, i.e. Format is;
X-Forwarded-For: client, proxy1, proxy2
So there should only ever be a single X-Forwarded-For header within a HTTP request with the first IP address being closest to the original. I could do the following:
[getfield [HTTP::header X-Forwarded-For] "," 1]
However I test a lot of code directly in TCL so the getfield commend is not valid but this is just down to personal preference.
Hi AMG,
I'm not 100% sure, but AFAIK, the RFC allow the request to contain more than one HTTP header with the same name. There is nothing specific to X-Forwarded-For header, so I assume the limitations are the same as other headers.
Moreover, in real life, I regularly face this kind of request containing several X-Forwarded-For headers. That's why I suggested to change the code to take into account this possibility.