Behavior of realip module with this config
mdounin at mdounin.ru
Fri Feb 10 16:05:08 UTC 2017
On Fri, Feb 10, 2017 at 10:20:01AM -0500, Paul Nickerson wrote:
> On Fri, Feb 10, 2017 at 7:33 AM, Maxim Dounin wrote:
> > And real_ip_recursive switched on means that this happens
> > recursively. As a result, with the configuration in question
> > nginx will use the first address in X-Forwarded-For provided, if
> > any (assuming all addresses are valid).
> > Note that "set_real_ip_from 0.0.0.0/0" makes client's address as
> > seen by nginx easily spoofable by any client, and it is generally
> > a bad idea to use it in production.
> Thank you for the reply, Maxim. "set_real_ip_from 0.0.0.0/0" does indeed
> seem like a bad idea in production. Thank you for calling that out.
> I am confused by this statement in the documentation:
> "If recursive search is enabled, the original client address that matches
> one of the trusted addresses is replaced by the last non-trusted address
> sent in the request header field."
> The language "last non-trusted address" suggests that NGINX looks for
> something in real_ip_header which does not match set_real_ip_from. But
> maybe I am interpreting that incorrectly.
> If set_real_ip_from were set correctly to the host's content delivery
> network, load balancer, and reverse proxy infrastructures, then my
> interpretation would make sense, as $remote_addr would then get set to the
> client's public IP, even if the client has network address translation and
> forward proxy infrastructures which append to X-Forwarded-For. But in your
> answer, wouldn't $remote_addr be set to the client's private IP address if
> their firewall/gateway adds that private IP address to X-Forwarded-For
> while it does the NATing? That doesn't seem very useful.
> This is an example situation I'm thinking of (all the IPs are random, and
> are the IPs "facing" NGINX):
> set_real_ip_from 10.6.1.0/24, 126.96.36.199/24;
> real_ip_header X-Forwarded-For;
> real_ip_recursive on;
> client's computer (192.168.1.79) > client's gateway (188.8.131.52) > my
> content delivery network (184.108.40.206) > my load balancer (10.6.1.56) > my
> NGINX box
> X-Forwarded-For = 192.168.1.79, 220.127.116.11, 18.104.22.168
> I think in your answer, $remote_addr would be set to 192.168.1.25, while in
> my interpretation, it would be set to 22.214.171.124. And in either case,
> $realip_remote_addr is 10.6.1.56.
Note that my answer ("with the configuration in question nginx
will use the first address in X-Forwarded-For provided") only
applies to the particular configuration with "set_real_ip_from
0.0.0.0/0", and it is incorrect to assume it can be used as an
universal answer to all questions.
Let me elaborate how things work a bit more, hopefully it will
help you to understand things better.
In this case the original client address, as obtained from the
TCP connection, will be 10.6.1.56.
$remote_addr = 10.6.1.56
Since this address is trusted (listed in set_real_ip_from), nginx
will process X-Forwarded-For header. On the first step, it will
use most recent address from X-Forwarded-For, 126.96.36.199.
So the result will be:
$remote_addr = 188.8.131.52
(rest of X-Forwarded-For) = 192.168.1.79, 184.108.40.206
Since real_ip_recursive is on, nginx will then repeat the whole
process using the new client address and the rest of
X-Forwarded-For. The address 220.127.116.11 is again trusted, so
nginx will use the next address from X-Forwarded-For,
$remote_addr = 18.104.22.168
(rest of X-Forwarded-For) = 192.168.1.79
Since 22.214.171.124 is not trusted, the process will stop here.
: If recursive search is enabled, the original client
: address that matches one of the trusted addresses is replaced by
: the last non-trusted address sent in the request header field.
in the documentation might be a bit confusing since it doesn't
explain the process. Though it actually describes what happens as
the result of the process: the last (rightmost) untrusted address
from X-Forwarded-For is used as client's address. The last
untrusted address in "192.168.1.79, 126.96.36.199, 188.8.131.52"
is 184.108.40.206. The only address which follows it,
220.127.116.11, is trusted. So 18.104.22.168 is used as the client
More information about the nginx