Forum Discussion

Scott123456789's avatar
Mar 23, 2017

X-Forwarded-For through proxy and F5

My organization recently got the ASM module when they purchased a pair of 5250Vs. I've never used ASM before and we don't have anyone in our organization that has either, so I'm learning on the fly.

 

I have a small SharePoint farm behind the F5. Two web front ends in a pool that uses SNAT. This farm is accessible from within our organization only, not available from the open internet. We have geographically dispersed users and offices, all over the United States. Some offices have a web proxy that all client web traffic goes through as it leaves their local enclave and some sites do not have a proxy like this.

 

For traffic that comes from a site that goes through a proxy, the X-Forwarded-For header shows in ASM as the proxy IP, not the actual client IP. For sites that do not go through a proxy, I see the actual client IP in this header. I contacted the group that manages the proxy at my location and confirmed that the proxy at my site also has X-Forwarded-For enabled, they even sent me a screen shot that showed it was enabled.

 

I'd like to see the IP of the original client through the proxy. From what I read, I thought maybe I'd see multiple IPs in some circumstances, but I admit I've never worked with X-Forwarded-For header before now. Thanks in advance.

 

  • IIS doesn't handle the X-Forwarded-For header in the normal IIS logs. The most common solution I've seen is, implementing IIS Advanced Logging. Depending on the version of IIS you are running, this might be an extension you need to install on your IIS servers (through the web platform installer on 2008 and 2008 R2), or it may be available built-in (2012 R2 and 2016, not sure about 2012).

     

    Here's an example of how to configure the logging once you have advanced logging available to you: https://www.iis.net/learn/get-started/whats-new-in-iis-85/enhanced-logging-for-iis85

     

  • Thank you, I will look at that link. But I was not talking about seeing this in IIS logs. I was talking about seeing the original client IP in the HTTP header when I looked at the HTTP request in ASM.

     

  • As for the remote sites using proxies, each one NEEDS to insert the XFF. Verify they are doing this with tcpdump on the frontend of the f5.

    Then since the VS is performing SNAT, it is inserting the IP of the proxy source as the XFF. You need to use an iRule to append the header with an additional XFF received from the proxy.

    As you have disparate configurations at your remote sites, you probably need to change the behavior per source IP, as the f5 inserting the proxy IP after SNAT will not help you out, you want the XFF that the proxy is sending toward the f5 maintained when forwarded to the backend servers, so use append.

    This will append the XFF if it exists, or insert a new one if it does not-

    when HTTP_REQUEST {

    if { [string tolower [HTTP::header names]] contains "x-forwarded-for"}{
        set XFF [HTTP::header X-Forwarded-For]
        append XFF ","
        lappend XFF [IP::remote_addr]
    } else {
        set XFF [IP::remote_addr]
    }
    
    HTTP::header replace "X-Forwarded-For" $XFF
    

    }

  • I'm still working on getting decrypted application data from ssldump, but I put the iRule in place on a test virtual server that only I use and it does add a second XFF IP, but it is the same IP as the one that is already there. So it used to say: X-Forwarded-For: 10.10.10.21 With the iRule, it says: X-Forwarded-For: 10.10.10.21, 10.10.10.21

     

    When I get successfully decrypted application data, I'll report on what the X-Forwarded-For header says there.

     

  • Ok, so it appears that my Internet Explorer doesn't send an XFF header. I eventually correctly used ssldump and was able to see the traffic that was coming the F5. I didn't see a XFF header at all. From my understanding of XFF, the client system shouldn't generate the XFF header, right? The proxy should insert it with the client IP? If that's a correct understanding, I need to talk to the proxy owner again.

     

    If the proxy wasn't decrypting traffic, it seems that would make it not possible to have my client IP in the XFF header, right?

     

    Thanks again for your help.

     

  • Hi,

    Okay, I think that might be because that is from one of your proxies that already inserts XFF, correct? I hinted earlier that you might need to adjust the behavior per client(or proxy) IP. I might have some bad indentation here but this is something to the idea-

    when HTTP_REQUEST {

     if { [IP::addr [IP::client_addr] equals IP_PROXY_THAT_ALREADY_INSERT_XFF/CIDR] } { 
       we know this proxy already inserts XFF, so dont do anything but load balancer
       pool [LB::server pool]
    
    } else {
        insert client IP to add visibility after f5 SNAT
         set XFF [IP::remote_addr]
         HTTP::header replace "X-Forwarded-For" $XFF
    
         }
    

    }

    also if the proxies are sending multiple http requests per connection you may need to enable oneconnect to get your iRule to work correctly.

    Let me know how your ssldump goes...

    • Scott123456789's avatar
      Scott123456789
      Icon for Cirrus rankCirrus

      I'm sorry, but I don't follow the logic here. I'm new to this, so I'm sure it's me, but the traffic sourcing from a proxy is the traffic I can't see the client IP on. If that proxy is inserting an XFF and it is giving me the proxy IP in that XFF, why would I do nothing to that? I'd think I'd want to determine if there is a second XFF value that I'd expect to be the original client IP.

       

    • Soda_Cup_148395's avatar
      Soda_Cup_148395
      Icon for Nimbostratus rankNimbostratus

      "If that proxy is inserting an XFF and it is giving me the proxy IP in that XFF, why would I do nothing to that?"

       

      because the XFF for the true client is already in place, so we need to do nothing, the web servers can see this. isn't the goal that the servers can see the client IP after any SNAT?

       

    • Scott123456789's avatar
      Scott123456789
      Icon for Cirrus rankCirrus

      If the XFF for the true client was in place, wouldn't I see it in the header? I don't see when I look at traffic on the F5, so I don't think it is in place.

       

  • You are right I believe the proxy needs to be decrypting to modify the http header, and insert the XFF. The client SHOULDN'T be inserting its own XFF, though it could it can do whatever it wants.

     

    If I understand right, this is the simplified issue:

     

    -some requests to the f5 already have XFF, as they are proxies -some requests to the f5 are from regular clients -f5 is using SNAT, so XFF needs to be inserted

     

    I think if you create a list of proxy IPs that already insert XFF for you and 'regular' clients then the newer iRule I posted should lead you toward the fix.

     

  • The below code will check for X-Forwarded-For header. If id does not exist it will grab the client address and insert X-Forwarded-For Header in the request.

     

    i.e if proxy already inserted X-Forwarded-For no need to worry as it will have the client IP. If not coming through proxy, insert XFF header with the client IP. Will this help ? Bit modified from Soda's iRule.

     

    when HTTP_REQUEST {     
            if {not ([HTTP::header exists "X-Forwarded-For"])} {
              set XFF [IP::remote_addr]
              HTTP::header insert "X-Forwarded-For" $XFF
            }
     }
  • The reason I am not getting the original client IP is because the proxy the traffic comes through does not decrypt the original traffic, therefor it cannot add the XFF header.