Nginx real_ip_recursive

Hello,

I am using nginx to proxy connections to a server I have written in
Java,
which serves connections on port 8080. I am trying to use the
X-Forwarded-For header to identify the real IP address of a connection,
but
I am running into difficulties with the nginx setting real_ip_recursive.

My nginx config file example_vhost in /etc/nginx/sites-enabled/:

server {
listen *:80;

server_name example.com;

index  index.html index.htm index.php;

location / {

proxy_pass          http://127.0.0.1:8080;
proxy_read_timeout  90;
proxy_connect_timeout  90;
proxy_redirect  off;
proxy_set_header        Host $host;
proxy_set_header        X-Real-IP $remote_addr;
#proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
set_real_ip_from    127.0.0.1;
real_ip_header      X-Forwarded-For;
real_ip_recursive   on;

}
}

This proxies requests onto my server as I expect, but I do not receive
the
correct IP address in the X-Forwarded-For header. If I connect to the
server
from a different IP address, spoofing the X-Forwarded-For header, I do
not
get the IP address of the machine, but rather get the spoofed addresses.

Example with curl on client machine 10.0.2.2:
$ curl -I --header “X-Forwarded-For: 1.1.1.1, 2.2.2.2” 10.0.2.15

Headers as received by my proxied Java server (extracted using tcpdump)
on
server machine 10.0.2.15:
$ sudo /usr/sbin/tcpdump -i lo -A -s 0 ‘tcp port 8080 and (
((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)’
tcpdump: verbose output suppressed, use -v or -vv for full protocol
decode
listening on lo, link-type EN10MB (Ethernet), capture size 65535 bytes
13:50:13.338901 IP localhost.50997 > localhost.8080: Flags [P.], seq
3051450771:
3051450976, ack 3527489033, win 4099, options [nop,nop,TS val 1891289
ecr
189128
9], length 205
E…M@.@…5"…q…A6 …
…HEAD / HTTP/1.0
Host: localhost
X-Real-IP: 10.0.2.2
Connection: close
User-Agent: curl/7.30.0
Accept: /
X-Forwarded-For: 1.1.1.1, 2.2.2.2

I assume I have got the nginx configuration wrong, but I am not sure
how. I
am using nginx/1.6.1 on debian Wheezy 7.6, and the output of nginx -V
includes --with-http_realip_module.

Thanks for any help in advance.

Posted at Nginx Forum:

Hello!

On Mon, Sep 15, 2014 at 09:11:37AM -0400, ianjoneill wrote:

Hello,

I am using nginx to proxy connections to a server I have written in Java,
which serves connections on port 8080. I am trying to use the
X-Forwarded-For header to identify the real IP address of a connection, but
I am running into difficulties with the nginx setting real_ip_recursive.

[…]

#proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

[…]

This proxies requests onto my server as I expect, but I do not receive the
correct IP address in the X-Forwarded-For header. If I connect to the server
from a different IP address, spoofing the X-Forwarded-For header, I do not
get the IP address of the machine, but rather get the spoofed addresses.

In your configuration, “proxy_set_header X-Forwarded-For” is
commented out. Therefore, the X-Forwarded-For header is passed
unmodified to the backend.


Maxim D.
http://nginx.org/

Thanks for your reply.

If I uncomment that line, the X-Forwarded-For header contains all of the
IP
addresses, as shown below:

$ sudo /usr/sbin/tcpdump -i lo -A -s 0 ‘tcp port 8080 and (
((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)’
tcpdump: verbose output suppressed, use -v or -vv for full protocol
decode
listening on lo, link-type EN10MB (Ethernet), capture size 65535 bytes
14:37:24.303617 IP localhost.50999 > localhost.8080: Flags [P.], seq
717883991:7
17884206, ack 1454594695, win 4099, options [nop,nop,TS val 2599031 ecr
2599030]
, length 215
E…“@.@…7”.*.
WV.Z…
.‘.w.’.vHEAD / HTTP/1.0
Host: localhost
X-Real-IP: 10.0.2.2
X-Forwarded-For: 1.1.1.1, 2.2.2.2, 10.0.2.2
Connection: close
User-Agent: curl/7.30.0
Accept: /

i.e. I am getting the spoofed addresses and the real one. As I
understood
it, I should only get the real ip, i.e. 10.0.2.2.

Posted at Nginx Forum:

Thanks for your explanation. If I were to later add load balancers in
front
of my proxy server, would the $remote_addr IP be correct (i.e. the
client
IP) or would it be the IP of the load balancer?

Thanks again for your help.

Posted at Nginx Forum:

Hello!

On Mon, Sep 15, 2014 at 11:41:49AM -0400, ianjoneill wrote:

Thanks for your explanation. If I were to later add load balancers in front
of my proxy server, would the $remote_addr IP be correct (i.e. the client
IP) or would it be the IP of the load balancer?

By default it will be the IP of the load balancer. If your load
balancer will be able to provide correct IP via X-Forwarded-For or
other header, the realip module can be used to instruct nginx to
use the address provided instead.


Maxim D.
http://nginx.org/

Hello!

On Mon, Sep 15, 2014 at 09:41:21AM -0400, ianjoneill wrote:

717883991:7
User-Agent: curl/7.30.0
Accept: /

i.e. I am getting the spoofed addresses and the real one. As I understood
it, I should only get the real ip, i.e. 10.0.2.2.

No, your understanding is wrong. The line in question will add
the IP address of a client to the X-Forwarded-For list. It’s up
to a backend to either trust or not individual addresses in this
list (and realip module is an example how this can be
implemented).

If you want nginx to pass only the IP of the client, without
preserving previous contents of the X-Forwarded-For header, use
$remote_addr variable instead of $proxy_add_x_forwarded_for:

proxy_set_header X-Forwarded-For $remote_addr;

Or just use X-Real-Ip as already set in your config to
$remote_addr.


Maxim D.
http://nginx.org/