Forum Discussion

hosting-team_36's avatar
hosting-team_36
Icon for Nimbostratus rankNimbostratus
Oct 29, 2018

irule to extract single IP from X-Forwarded-for results with multiple IPs

I need an irule to split the IP::remote_addr and just set the first IP as theX-Forwarded-For

when HTTP_REQUEST { HTTP::header insert X-Forwarded-For [IP::remote_addr] }

https://devcentral.f5.com/questions/Using-X-Forwarded-for-to-block-Clients Is almost there with the following but it doesn't apply after the "foreach" line(they were trying to something different though in the end):

when HTTP_REQUEST {

if {[HTTP::header "X-Forwarded-For"] ne ""}{

  log local0. "XFF: [HTTP::header "X-Forwarded-For"]"

  foreach xff [split [string map [list " " ""] [HTTP::header "X-Forwarded-For"]] ","] {

 log local0. "Current XFF element: $xff"

 if {[IP::addr $xff equals 1.2.3.4]}{
        log local0. "Sending 410 for $xff"
        HTTP::respond 410
        break
     }
  }

} }

3 Replies

  • Can you clarify? How would IP::remote_addr contain multiple addresses? The XFF header might, but IP::remote_addr gets its information from the TCP packet.

     

  • XFF is returning IP,IP sometimes. Is there a way to split that out and send just first listed IP?

     

  • Ah, ok. Wasn't sure how [IP::remote_addr] was involved.

    An X-Forwarded-For header with multiple IPs will be comma-delimited:

    X-Forwarded-For: 10.10.0.1, 10.10.0.2, 10.10.0.3
    

    So to grab the first one, you can do some simple list manipulation:

    if { [HTTP::header "X-Forwarded-For"] ne "" } {
        if { [HTTP::header "X-Forwarded-For"] contains "," }{
            set ips [split [HTTP::header "X-Forwarded-For"] ","]
            set xff [lindex ${ips} 0]
        } else {
            set xff [HTTP::header "X-Forwarded-For"]
        }
    } else {
        set xff [IP::remote_addr]
    }