Forum Discussion

Cameron_Merrick's avatar
Cameron_Merrick
Icon for Altostratus rankAltostratus
Aug 06, 2018

X-Forwarded-For: Multiple IP's Chained | Need Original IP | iRules and HTTP Profile?

Hello,

 

I am at a loss. I am a security engineer and one of my jobs is managing the SIEM, which I am building out currently. One of the log sources is, of course, the F5 ASM logs. The problem, however, is that the logs come in with the wrong IP in the source IP field. They come in with IP addresses from our own architecture components such as the ALB or cloudfront instead of correctly parsing the XFF (via the iRule below or otherwise). It definitely has to do with the XFF header situation of our architecture. I have read a boat load of stuff to no avail. Just cannot seem to get the right IP (the ACTUAL origin IP) in the source IP spot. Any help would be greatly appreciated!

 

Architecture:

internet/users —> Cloudfront —> ALB —> F5 —> Amazon ECS backend incl. Logrhythm SIEM

 

Also, the profile being used in the LTM is http. We have "insert x-forwarded-for" set to DISABLED, and "Accept XFF" ENABLED, as well as the Alternate XFF box filled in with "X-Forwarded-For" (just to be safe).

 

Desired Solution:

We are hoping for the F5 to send its syslog ASM logs to our SIEM (Logrhythm) with the true original IP address listed correctly as the source/client IP address. In other words, We need the SIEM to see the origin IP as the true original IP.

 

Problem:

The issues with the xff headers and various IP addresses has created a situation where either Cloudfront, the ALB, the F5, or one of the backend service’s IP address is incorrectly in the original source/client IP spot. The implications of this are far reaching and totally screws things up for our SIEM and security orchestration and all sorts of stuff.

 

iRule Currently Used:

We are currently using this iRule which is at the top of the list of execution order.

 

 

when HTTP_REQUEST {
  HTTP::header insert X-Forwarded-For [IP::remote_addr]
  HTTP::header replace X-Forwarded-For [getfield [HTTP::header X-Forwarded-For] "," 1]
  HTTP::header replace X-Forwarded-For-Raw [getfield [HTTP::header X-Forwarded-For] "," 1]
  HTTP::header replace CF-Connecting-IP [getfield [HTTP::header X-Forwarded-For] "," 1]
}

Example Request seen in the F5 ASM Event Logs (to be fwded to SIEM):

GET / HTTP/1.1
X-Forwarded-For: AAA.AAA.AAA.AAA, BBB.BBB.BBB.BBB
X-Forwarded-Proto: https
X-Forwarded-Port: 443
Host: sub.exampledomain.com
X-Amzn-Trace-Id: Root=1-5b67cf53-df48e8adfafafdsaff4a726f
X-Amz-Cf-Id: PYTrCasdfafgh_5xIO_P4IpHafdsafsdafETZLgQr4CJEfOpQ==
User-Agent: Mozilla/5.0 (compatible; Uptime/1.0; http://uptime.com)
Via: 1.1 aa9157a1414f639asdfasdfasb7df10.cloudfront.net (CloudFront)
CloudFront-Is-Mobile-Viewer: false
CloudFront-Is-Tablet-Viewer: false
CloudFront-Is-SmartTV-Viewer: false
CloudFront-Is-Desktop-Viewer: true
CloudFront-Viewer-Country: SG
Accept: */*
CloudFront-Forwarded-Proto: https
x-salt-cloudfront-secret: 6CsSe4cBZwuTBOasdfadUhu3sPKJ5K8SCA
X-Forwarded-For: CC.CC.CC.CC
X-Forwarded-For-Raw: CC.CC.CC.CC
CF-Connecting-IP: CC.CC.CC.CC

 

In this case, the F5 would have CC.CC.CC.CC listed in the source IP Address

 

Thank you very much to anyone who can help!

 

2 Replies

  • try this code

     

    when HTTP_REQUEST {
        set FIRST_XFF [[getfield [lindex [HTTP::header values X-Forwarded-For] 0] "," 1]]
        HTTP::header insert X-Forwarded-For [IP::remote_addr]
        HTTP::header remove X-Forwarded-For
        HTTP::header remove X-Forwarded-For-Raw
        HTTP::header remove CF-Connecting-IP
        HTTP::header insert X-Forwarded-For FIRST_XFF
        HTTP::header insert X-Forwarded-For-Raw $FIRST_XFF
        HTTP::header insert CF-Connecting-IP $FIRST_XFF
    }
    

     

  • JG's avatar
    JG
    Icon for Cumulonimbus rankCumulonimbus

    This is a case of multiple XFF headers and you can't really know which contains the end-user address unless you know the addresses of the intermediate systems to filter them out. To log all the addresses locally, you can do:

     

     

    when HTTP_REQUEST {
        if { [HTTP::header values "X-Forwarded-For"] ne "" } {
            log local0. "[HTTP::header values \"X-Forwarded-For\"]"
        }
    }
    

     

    You will need to make some changes for remote logging.