Nginx – Logging original requestor IP instead of forward proxy IP for certain HTTP requests (nginx logs)

loggingnginxPROXYx-forwarded-for

I use nginx as a reverse proxy in front of our application web server (gunicorn; it's a Django app). Majority of the users hitting this web application are actually routed through a forward proxy.

Since requests pass through the forward proxy's servers, the IP address in these cases is always from proxy servers instead of from the original requestor. I want to rectify this situation.

All requests originating from the forward proxy contain a header via:proxy. In such requests, the original requestor IP is sent in a separate HTTP header field called X-IORG-FBS-UIP (and also X-FORWARDED-FOR).

My question is, how can I configure nginx such that it detects whether the request has via:proxy header, and if so, logs the original requestor IP from the X-IORG-FBS-UIP header? An illustrative example would be great; thanks in advance! My nginx is v 1.4.6


Note that I do not have the IP ranges used by the forward proxy. If I did, one way to solve this problem would been setting up etc/nginx/conf.d/proxies_acl.conf with:

set_real_ip_from 1.2.3.0/22;
set_real_ip_from 23.22.20.0/22;
real_ip_header X-IORG-FBS-UIP;

Best Answer

Try this. Interested to hear if it works. If you have any clients that aren't translated it would break that.

set_real_ip_from 0.0.0.0/0;
real_ip_header X-IORG-FBS-UIP;

Your set_real_ip_from and real_ip_header statements above are the standard way to do this. The only difference between your situation and what most people have is you don't know the IP address of the proxies. 0.0.0.0/0 means "every IP address", so the statements above say "for every request, get the client IP for the logs from the X-IORG-FBS-UIP header". My guess is if that header doesn't exist it will use the actual IP.

In most cases you can get the IP addresses of the proxies. AWS, CloudFlare, etc. Why don't you know the IPs of your proxies?

I also note you asked an almost identical question a couple of months ago, and accepted the answer. If someone doesn't answer your question, don't mark it as the answer.

Requested Alternate method - DOES NOT WORK

You asked for an alternate method based on the presence of the via:proxy header. I don't believe this is possible. I wrote this

if ($http_X_via:proxy) {
  set_real_ip_from $remote_addr;
  real_ip_header X-IORG-FBS-UIP;
}

But it fails. Nginx says set_real_ip_from can't go inside an if block. This means you have to know your IPs in advance, or use my other solution above.