[PATCH] Improve X-Forwarded-For handling in realip
omar.kilani at gmail.com
Thu Dec 2 06:23:26 MSK 2010
According to the nginx wiki, the realip module seems to want to work
like mod_extract_forward for Apache, and says this:
"User Note: "You will build a list of trusted proxies (see below) and
the first IP in the header which is not trusted will be used as the
client IP." Source: README of the Apache module mod_extract . Quite
informative, about why and how this security feature is helpful."
The problem is that nginx doesn't do the "first IP in the header which
is not trusted" part -- it always returns the last IP in the
X-Forwarded-For header, no matter what.
"If a request has passed through multiple proxies then the
X-Forwarded-For may contain several IPs like this:
X-Forwarded-For: client1, proxy1, proxy2
Additionally there is the IP of the requesting host itself which is
not included in the header. Let's say the requesting host is proxy3.
First we check that the connecting host is in the is acceptable. Then
we traverse the header from right to left and the first encountered IP
which is not acceptbale will be treated as the client IP. For example
if proxy1, proxy2, and proxy3 are acceptable then in the above header
client1 would be shown as the connecting IP. But in the following
X-Forwarded-For: client1, untrusted1, proxy1, proxy2
untrusted1 would be shown as the connecting IP even though untrusted1
is proxying for client1. (Because untrusted1 might be lying.)"
In both these cases, nginx always returns 'proxy2', even if proxy2's
ip matches a 'set_real_ip_from' entry.
The patch at: http://treehou.se/~omar/nginx-0.8.53-xff.patch
Improves X-Forwarded-For handling so that, in case 1, 'client1' is
returned if 'proxy1' and 'proxy2' are in 'set_real_ip_from' and
'untrusted1' is returned for case 2.
FWIW, we've been running this patch in production for 24 hours with no
Hope this helps!
More information about the nginx