Behavior of realip module with this config

Maxim Dounin mdounin at mdounin.ru
Fri Feb 10 16:05:08 UTC 2017


Hello!

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:
> http://nginx.org/en/docs/http/ngx_http_realip_module.html
> "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, 8.47.98.0/24;
> real_ip_header X-Forwarded-For;
> real_ip_recursive on;
> 
> client's computer (192.168.1.79) > client's gateway (178.150.189.138) > my
> content delivery network (8.47.98.129) > my load balancer (10.6.1.56) > my
> NGINX box
> 
> X-Forwarded-For = 192.168.1.79, 178.150.189.138, 8.47.98.129
> 
> I think in your answer, $remote_addr would be set to 192.168.1.25, while in
> my interpretation, it would be set to 178.150.189.138. 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, 8.47.98.129.
So the result will be:

    $remote_addr = 8.47.98.129
    (rest of X-Forwarded-For) = 192.168.1.79, 178.150.189.138

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 8.47.98.129 is again trusted, so 
nginx will use the next address from X-Forwarded-For, 
178.150.189.138:

    $remote_addr = 178.150.189.138
    (rest of X-Forwarded-For) = 192.168.1.79

Since 178.150.189.138 is not trusted, the process will stop here.

The sentence

: 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, 178.150.189.138, 8.47.98.129" 
is 178.150.189.138.  The only address which follows it, 
8.47.98.129, is trusted.  So 178.150.189.138 is used as the client 
address.

-- 
Maxim Dounin
http://nginx.org/


More information about the nginx mailing list