19-Aug-2020 02:25
Hello.
The HTTP::header command in a irule returns the value of this header, at the time the irule is evaluated. As a consequence, any header set or modified by an HTTP profile, such as X-Forwarded-For, now has a value different from the original received request. I also tried HTTP::request, with the same result.
Is there any way to log the original value for this header ?
Solved! Go to Solution.
21-Aug-2020
14:35
- last edited on
04-Jun-2023
21:18
by
JimmyPackets
Hello Guillaume.
Actually, the XFF headers insertion occurs when HTTP protocol is parsed, which means before HTTP_REQUEST event.
Your only chance is to capture TCP::payload.
when CLIENT_ACCEPTED {
TCP::collect
}
when CLIENT_DATA {
set LogString "Client [IP::client_addr]:[TCP::client_port]"
log local0. "============================================="
log local0. "$LogString (request_pre)"
foreach rec [split [TCP::payload] "\r\n"] {
if { $rec ne "" } {
log local0. $rec
}
}
TCP::release
log local0. "============================================="
}
when HTTP_REQUEST {
set LogString "$LogString -> [HTTP::host][HTTP::uri]"
log local0. "============================================="
log local0. "$LogString (request) - request: [HTTP::method]"
foreach aHeader [HTTP::header names] {
log local0. "$aHeader: [HTTP::header value $aHeader]"
}
log local0. "============================================="
}
when HTTP_REQUEST_RELEASE {
log local0. "============================================="
log local0. "$LogString (request_post) - request: [HTTP::method]"
foreach aHeader [HTTP::header names] {
log local0. "$aHeader: [HTTP::header value $aHeader]"
}
log local0. "============================================="
}
This an example:
<CLIENT_DATA>: =============================================
<CLIENT_DATA>: Client 10.130.40.41:53563 (request_pre)
<CLIENT_DATA>: GET / HTTP/1.1
<CLIENT_DATA>: User-Agent: curl/7.19.7
<CLIENT_DATA>: Host: 10.130.40.50
<CLIENT_DATA>: Accept: */*
<CLIENT_DATA>: =============================================
<HTTP_REQUEST>: =============================================
<HTTP_REQUEST>: Client 10.130.40.41:53563 -> 10.130.40.50/ (request) - request: GET
<HTTP_REQUEST>: User-Agent: curl/7.19.7
<HTTP_REQUEST>: Host: 10.130.40.50
<HTTP_REQUEST>: Accept: */*
<HTTP_REQUEST>: X-Forwarded-For: 10.130.40.41
<HTTP_REQUEST>: =============================================
<HTTP_REQUEST_RELEASE>: =============================================
<HTTP_REQUEST_RELEASE>: Client 10.130.40.41:53563 -> 10.130.40.50/ (request_post) - request: GET
<HTTP_REQUEST_RELEASE>: User-Agent: curl/7.19.7
<HTTP_REQUEST_RELEASE>: Host: 10.130.40.50
<HTTP_REQUEST_RELEASE>: Accept: */*
<HTTP_REQUEST_RELEASE>: X-Forwarded-For: 10.130.40.41
<HTTP_REQUEST_RELEASE>: =============================================
Take into account that if you use TLS, you should repeat the same but in CLIENT_SSL_DATA event.
https://clouddocs.f5.com/api/irules/CLIENTSSL_DATA.html
Regards,
Dario.
21-Aug-2020
14:35
- last edited on
04-Jun-2023
21:18
by
JimmyPackets
Hello Guillaume.
Actually, the XFF headers insertion occurs when HTTP protocol is parsed, which means before HTTP_REQUEST event.
Your only chance is to capture TCP::payload.
when CLIENT_ACCEPTED {
TCP::collect
}
when CLIENT_DATA {
set LogString "Client [IP::client_addr]:[TCP::client_port]"
log local0. "============================================="
log local0. "$LogString (request_pre)"
foreach rec [split [TCP::payload] "\r\n"] {
if { $rec ne "" } {
log local0. $rec
}
}
TCP::release
log local0. "============================================="
}
when HTTP_REQUEST {
set LogString "$LogString -> [HTTP::host][HTTP::uri]"
log local0. "============================================="
log local0. "$LogString (request) - request: [HTTP::method]"
foreach aHeader [HTTP::header names] {
log local0. "$aHeader: [HTTP::header value $aHeader]"
}
log local0. "============================================="
}
when HTTP_REQUEST_RELEASE {
log local0. "============================================="
log local0. "$LogString (request_post) - request: [HTTP::method]"
foreach aHeader [HTTP::header names] {
log local0. "$aHeader: [HTTP::header value $aHeader]"
}
log local0. "============================================="
}
This an example:
<CLIENT_DATA>: =============================================
<CLIENT_DATA>: Client 10.130.40.41:53563 (request_pre)
<CLIENT_DATA>: GET / HTTP/1.1
<CLIENT_DATA>: User-Agent: curl/7.19.7
<CLIENT_DATA>: Host: 10.130.40.50
<CLIENT_DATA>: Accept: */*
<CLIENT_DATA>: =============================================
<HTTP_REQUEST>: =============================================
<HTTP_REQUEST>: Client 10.130.40.41:53563 -> 10.130.40.50/ (request) - request: GET
<HTTP_REQUEST>: User-Agent: curl/7.19.7
<HTTP_REQUEST>: Host: 10.130.40.50
<HTTP_REQUEST>: Accept: */*
<HTTP_REQUEST>: X-Forwarded-For: 10.130.40.41
<HTTP_REQUEST>: =============================================
<HTTP_REQUEST_RELEASE>: =============================================
<HTTP_REQUEST_RELEASE>: Client 10.130.40.41:53563 -> 10.130.40.50/ (request_post) - request: GET
<HTTP_REQUEST_RELEASE>: User-Agent: curl/7.19.7
<HTTP_REQUEST_RELEASE>: Host: 10.130.40.50
<HTTP_REQUEST_RELEASE>: Accept: */*
<HTTP_REQUEST_RELEASE>: X-Forwarded-For: 10.130.40.41
<HTTP_REQUEST_RELEASE>: =============================================
Take into account that if you use TLS, you should repeat the same but in CLIENT_SSL_DATA event.
https://clouddocs.f5.com/api/irules/CLIENTSSL_DATA.html
Regards,
Dario.
24-Aug-2020 09:05
Thank for the details, It confirms there is no simple way at BigIP level. I'll just send modified header value, and take care of it later in log processing.
Regards.
24-Aug-2020 10:23
You are welcome. Don't forget to mark this answer above as 'the best' to help other people to find it ;-).
Regards,
Dario.
25-Aug-2020 01:44
Good point, I did not know this feature. I just did it, thanks.
Regards.