Wrong IP with lighttpd reverse proxy

gunicornlighttpdreverse-proxy

I use a lighttpd reverse proxy to serve django with gunicorn. Now this config worked:

proxy.server = ("" => ( "" => (
    "host" => "127.0.0.1",
    "port" => 8000,
)))

Now i moved the gunicorn into a container and use:

proxy.server = ("" => ( "" => (
    "host" => "192.168.1.2",
    "port" => 8000,
)))

Now every request has the ip 192.168.1.1 as seen by gunicorn. I would understand, if the reverse proxy obfuscates the real IP, but why did it work with localhost then?

for both i get

X-Forwarded-For: client-ip
X-Host: the.domain
X-Forwarded-Proto: http

where the client-ip is public ip space.

the requests comes from

host:

nc: connect to 127.0.0.1 8000 from localhost (127.0.0.1) 44953 [44953]

container:

nc: connect to 192.168.1.2 8000 from host (192.168.1.1) 60027 [60027]

the container itself has ip 192.168.1.2, the host-bridge has 192.168.1.1 and the routes inside the container are:

default via 192.168.1.1 dev eth0 
192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.2

the host has:

192.168.1.0/24 dev bridge  proto kernel  scope link  src 192.168.1.1

EDIT:
The X-Forwarded-For was the same for both requests. (Tested with nc -vlp 8000).

Best Answer

My bet? lighttpd is adding an X-Forwarded-For header, and Django has something hardcoded somewhere to know that 127.0.0.1 is unlikely to be the real remote IP address if that header's present.

You should verify that the X-Forwarded-For header is present, then get Django to use that as the remote address (looks like the way to do that is here).

Related Topic