Home > Back-end >  Set XFF header to last appended IP Nginx
Set XFF header to last appended IP Nginx

Time:10-11

I have a seemingly simple problem that I can't figure out.

I have a micro-service that validates the Customers IP against a whitelist. The problem is that I have a LoadBalancer (ALB) and a reverse proxy (Nginx) in-front of this MicroService.

What I am using in the MicroService is the last IP in the XFF (X-Forwarded-For) header.

But this opens me up for XFF injections. Because I trust the ALB in-front of my proxy, and know it is the first hop in the network, I want to use the IP it append to the XFF header, and overwrite the header completely. ( I want to do this in NginX)

How would I go about extracting the last value in the XFF header in Nginx, and then overwriting the XFF header with only this value, and forwarding it along?

I really don't know much about nginx and its config usages but I saw that I could potentially use the Map function with some regex to extract the last value, but then I am not sure how to set the XFF header without also adding the ALB's ip to it?

This is how I think the map function would look look in the config.

map $proxy_add_x_forwarded_for $client_ip {"[^,] $" $1;}

But I am not sure if that will also add the ALB's(previous hops) IP to that service? If so I want the second last IP?

Please help.

CodePudding user response:

First and foremost, this is wrong:

What I am using in the MicroService is the last IP in the XFF (X-Forwarded-For) header.

You don't need the last IP in the header but the first one indeed. By default, AWS ALB works in append mode and when in this mode, it appends any subsequent proxy/lb IPs to the last in a comma separated manner. So, the first or the leftmost IP in the X-Forwarded-Header is the client ip. See this.

In order to get the first entry in the header, you can use map in this fashion:

http {
  ...
  ...
  server {
    ...
    map "$proxy_add_x_forwarded_for" $client_ip_addr {
      (^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}),(.*)    $1;
    }
    ...
  }
}

The $client_ip_addr variable will contain the ip address of the client from where the request originated. You can pass this variable as X-Forwarded-For in any location block like this:

location / {
  ...
  proxy_set_header  X-Forwarded-For  $client_ip_addr;
  ...
}

If you're really concerned about XFF attacks, I'd recommend this for further reading:

  • Related