Forum Discussion

rashmikantsngh1's avatar
rashmikantsngh1
Icon for Nimbostratus rankNimbostratus
Aug 22, 2018

Need help with insert-true-client-ip-header rule on F5

Hello Experts,

 

Could you please help me understand below irule configuration step by step for each statement? I have brief idea about what it does but i'm getting confused in understanding it.

 

when HTTP_REQUEST { if { not ([class match [IP::remote_addr] eq akamai-prod]) and not ([class match [IP::remote_addr] eq akamai-stage]) } { if { [HTTP::header exists True-Client-IP] } { HTTP::header remove True-Client-IP } HTTP::header insert True-Client-IP [getfield [IP::client_addr] "%" 1] } } }

 

Your help will be greatly appreciated. Thanks!

 

Regards: Rashmikant

 

3 Replies

  • The rule will first check if the destination IP adres isn’t known in the akamai-secure-prod-net an akamai-secure-stage-net. If this is true, it will check if the True-Client-IP HTTP header is set and if set it will remove it. Then it will add the True-Client-IP HTTP header with the source address of the client, but strip off the route domain.

     

  • Hope this makes sense:

    when HTTP_REQUEST {
    
         if the client address (https://devcentral.f5.com/wiki/iRules.IP__remote_addr.ashx) 
         is NOT equal to an entry in datagroup akamai-secure-prod-net
         and the client address is NOT equal to an entry in datagroup akamai-secure-stage-net
    
        if { not ([class match [IP::remote_addr] eq akamai-secure-prod-net]) and not ([class match [IP::remote_addr] eq akamai-secure-stage-net]) } { 
    
             Check the header 'True-Client-IP' exists
            if { [HTTP::header exists True-Client-IP] } { 
    
                 if true, remove the header
                HTTP::header remove True-Client-IP 
            }
    
             insert header with a value of the client IP address
             getfield will return the value for the client IP address 
             up to the  first '%' symbol = in this case it will be used for a route domain
             https://devcentral.f5.com/wiki/irules.getfield.ashx
            HTTP::header insert True-Client-IP [getfield [IP::client_addr] "%" 1] 
        } 
    }
    
  • Hi,

    Additional INFO: First of I will represent the I will represent the access as it is done from the client to the F5

    CLIENT --> Akamai (Prod or Stage) --> F5 Service

    • client try to access to the following hostname that is hosted by F5 : app.mydomain.com
    • Client Resolve this fqdn with Akamai IP
    • Akamai will redirect user to F5 service (app.mydomain.com) at the same time it will cache the client's response for the future transaction.
    • When Akamai will redirect user to F5 service (app.mydomain.com), it adds an HTTP header with Real IP of the client(pay attention, this information is added in HTTP header with the following name "True-Client-IP")
    • F5 receive the client request which was transmitted by Akamai with CLIENT IP (L4) Akamai and in this request we have also the Real IP of the customer in HTTP header (L7).

    now that we have the use case it will be easier to understand the IRULE. first of all in a global way what is the purpose of this irule:

    Your Irulle check if the client is comming for Akami:

    • if yes (irule do nothing) because Akamai added header with real client IP of the user
    • if no that seems that user don't come from akamai and therefore he does not have a header insert by akamai (True-Client-IP) So F5 do it.

    I suppose that F5 or App backend determine the real user client IP using this header that's the reason why F5 add it when it is not present (that is, when the user does not go through akamai). the user may not go through akamai if it resolves sending the application directly instead of resolving with the akamai ip.

     We manipulate or check L7 flow because we using HTTP_REQUEST event
    when HTTP_REQUEST { 
    
     we checked if user come from AKAMAI (And if CLIENT IP is not akamai we trigged the condition)
    if { not ([class match [IP::remote_addr] eq akamai-prod]) and not ([class match [IP::remote_addr] eq akamai-stage]) } { 
    
     So we now that user don't com from akamai so it should not have a "True-Client-IP" header because only akamai distributes it.
     So if the client IP have an header "True-Client-IP" we remove IT then we set IT manually to avoid that user inject fake or not right IP.
        if { [HTTP::header exists True-Client-IP] } { 
            HTTP::header remove True-Client-IP 
        }
    
     We injected the header instead of akamai (as I explained above this header is probably used by the app or F5)
        HTTP::header insert True-Client-IP [getfield [IP::client_addr] "%" 1] 
    } 
    
    }
    

    Hope it's clear.

    Regards