[GH-ISSUE #555] IP detection behing Nginx Proxy Manager running on another machine fails #382

Closed
opened 2026-02-26 10:31:11 +03:00 by kerem · 8 comments
Owner

Originally created by @gabviv73 on GitHub (Jun 19, 2024).
Original GitHub issue: https://github.com/nsupdate-info/nsupdate.info/issues/555

I'm building a docker container for nsupdate.info.
The web gui and the updates are working, but the IP detection fails: it detects the IP address of the nginx reverse proxy.
What could I do to investigate the issue ?

Originally created by @gabviv73 on GitHub (Jun 19, 2024). Original GitHub issue: https://github.com/nsupdate-info/nsupdate.info/issues/555 I'm building a docker container for nsupdate.info. The web gui and the updates are working, but the IP detection fails: it detects the IP address of the nginx reverse proxy. What could I do to investigate the issue ?
kerem closed this issue 2026-02-26 10:31:11 +03:00
Author
Owner

@ThomasWaldmann commented on GitHub (Jun 19, 2024):

There are 2 ways to solve this:

  • set the usual env vars from nginx to pass through the outside IP address to the nsupdate.info python code. Guess this is also needed if you'ld like the correct ip in the webserver logs.
  proxy_set_header Host $http_host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;
  • directly answer the requests for the IP from nginx (from the reverse proxy webserver) and do not forward them to the nsupdate.info python code at all (performance / load optimisation)
  location /myip {
    add_header Content-Type text/plain;
    return 200 $remote_addr;
  }
<!-- gh-comment-id:2178945648 --> @ThomasWaldmann commented on GitHub (Jun 19, 2024): There are 2 ways to solve this: - set the usual env vars from nginx to pass through the outside IP address to the nsupdate.info python code. Guess this is also needed if you'ld like the correct ip in the webserver logs. ``` proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; ``` - directly answer the requests for the IP from nginx (from the reverse proxy webserver) and do not forward them to the nsupdate.info python code at all (performance / load optimisation) ``` location /myip { add_header Content-Type text/plain; return 200 $remote_addr; } ```
Author
Owner

@gabviv73 commented on GitHub (Jun 20, 2024):

I have simplified my test environment to ease investigation. Now the docker containers are running on a machine with public IP Address.
The Nginx reverse proxy running on container A with IP address 192.168.48.2 seems to set the correct headers:

socat -v TCP-LISTEN:8916 STDOUT

Host: <redacted>\r
X-Forwarded-Scheme: https\r
X-Forwarded-Proto: https\r
X-Forwarded-For: 82.54.46.1\r
X-Real-IP: 82.54.46.1\r
user-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0\r
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8\r
accept-language: it,en-US;q=0.7,en;q=0.3\r
accept-encoding: gzip, deflate, br, zstd\r
dnt: 1\r
upgrade-insecure-requests: 1\r
sec-fetch-dest: document\r
sec-fetch-mode: navigate\r
sec-fetch-site: none\r
sec-fetch-user: ?1\r
priority: u=1\r
cookie: csrftoken=hPmoKFAzVgfZ8ZayYyo8LD1CIvQQiNHD; sessionid=z63akq8bevrkij0qhhmd2zbb1a6u4dg7\r

The gunicorn server running nsupdate.info on conatiner B with IP Address 192.168.0.2 is started with:
gunicorn --workers=4 --log-level=info --forwarded-allow-ips='*' --bind 0.0.0.0:8000 nsupdate.wsgi

But nsupdate.info detects the IP address of the docker host interface 192.168.0.1:

nsupdate.info | [2024-06-20 19:26:13,045] DEBUG ajax_get_ips response: {'ipv4': '192.168.0.1', 'ipv4_rdns': '', 'ipv6': '', 'ipv6_rdns': ''} [ip: 192.168.0.1, ua: "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0"]

It seems that gunicorn discards the headers ...

<!-- gh-comment-id:2181233751 --> @gabviv73 commented on GitHub (Jun 20, 2024): I have simplified my test environment to ease investigation. Now the docker containers are running on a machine with public IP Address. The Nginx reverse proxy running on container A with IP address 192.168.48.2 seems to set the correct headers: `socat -v TCP-LISTEN:8916 STDOUT` ```GET / HTTP/1.1\r Host: <redacted>\r X-Forwarded-Scheme: https\r X-Forwarded-Proto: https\r X-Forwarded-For: 82.54.46.1\r X-Real-IP: 82.54.46.1\r user-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0\r accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8\r accept-language: it,en-US;q=0.7,en;q=0.3\r accept-encoding: gzip, deflate, br, zstd\r dnt: 1\r upgrade-insecure-requests: 1\r sec-fetch-dest: document\r sec-fetch-mode: navigate\r sec-fetch-site: none\r sec-fetch-user: ?1\r priority: u=1\r cookie: csrftoken=hPmoKFAzVgfZ8ZayYyo8LD1CIvQQiNHD; sessionid=z63akq8bevrkij0qhhmd2zbb1a6u4dg7\r ``` The gunicorn server running nsupdate.info on conatiner B with IP Address 192.168.0.2 is started with: `gunicorn --workers=4 --log-level=info --forwarded-allow-ips='*' --bind 0.0.0.0:8000 nsupdate.wsgi` But nsupdate.info detects the IP address of the docker host interface 192.168.0.1: `nsupdate.info | [2024-06-20 19:26:13,045] DEBUG ajax_get_ips response: {'ipv4': '192.168.0.1', 'ipv4_rdns': '', 'ipv6': '', 'ipv6_rdns': ''} [ip: 192.168.0.1, ua: "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0"]` It seems that gunicorn discards the headers ...
Author
Owner

@gabviv73 commented on GitHub (Jun 21, 2024):

I came to a solution after a bit of research.
It seems that django does know anything about X-Forwarede headers things.
I've installed and configured a middleware, and now it works:

pip install django-xff

activated the middleware in

local_settings.py

MIDDLEWARE = MIDDLEWARE + ('xff.middleware.XForwardedForMiddleware',)

Now the X-Forwarded IP is correctly red.

See here

<!-- gh-comment-id:2182710625 --> @gabviv73 commented on GitHub (Jun 21, 2024): I came to a solution after a bit of research. It seems that django does know anything about X-Forwarede headers things. I've installed and configured a middleware, and now it works: `pip install django-xff` activated the middleware in ` local_settings.py` `MIDDLEWARE = MIDDLEWARE + ('xff.middleware.XForwardedForMiddleware',)` Now the X-Forwarded IP is correctly red. See [here](https://devjunhong.github.io/python/client_ip_address/)
Author
Owner

@ThomasWaldmann commented on GitHub (Jun 21, 2024):

I don't think I've ever used / needed that middleware.

<!-- gh-comment-id:2183256206 --> @ThomasWaldmann commented on GitHub (Jun 21, 2024): I don't think I've ever used / needed that middleware.
Author
Owner

@gabviv73 commented on GitHub (Jun 24, 2024):

I don't think I've ever used / needed that middleware.

Maybe you are using Nginx or Apache with wsgi modules to serve the app.
Using gunicorn, it's necessary. Have a look at my PR for the docker container.

<!-- gh-comment-id:2186190620 --> @gabviv73 commented on GitHub (Jun 24, 2024): > I don't think I've ever used / needed that middleware. Maybe you are using Nginx or Apache with wsgi modules to serve the app. Using gunicorn, it's necessary. Have a look at my PR for the docker container.
Author
Owner

@tsz-systems commented on GitHub (Aug 1, 2024):

I don't think I've ever used / needed that middleware.

Maybe you are using Nginx or Apache with wsgi modules to serve the app. Using gunicorn, it's necessary. Have a look at my PR for the docker container.

Did you manage to get both IPv4 and IPv6 working with your setup?
Both ipv4.example.com and ipv6.example.com return my ipv6 address.
When I curl -4 it returns my v4 address.

My setup is also nginxproxymanager -> nsupdate (dockerized)

<!-- gh-comment-id:2262806547 --> @tsz-systems commented on GitHub (Aug 1, 2024): > > I don't think I've ever used / needed that middleware. > > Maybe you are using Nginx or Apache with wsgi modules to serve the app. Using gunicorn, it's necessary. Have a look at my PR for the docker container. Did you manage to get both IPv4 and IPv6 working with your setup? Both ipv4.example.com and ipv6.example.com return my ipv6 address. When I curl -4 it returns my v4 address. My setup is also nginxproxymanager -> nsupdate (dockerized)
Author
Owner

@gabviv73 commented on GitHub (Aug 2, 2024):

Hy, sorry, I can't test IPv6 on my setup.

Did you manage to get both IPv4 and IPv6 working with your setup?

<!-- gh-comment-id:2266051448 --> @gabviv73 commented on GitHub (Aug 2, 2024): Hy, sorry, I can't test IPv6 on my setup. > Did you manage to get both IPv4 and IPv6 working with your setup?
Author
Owner

@tsz-systems commented on GitHub (Aug 5, 2024):

I found my mistake. It wasn’t related to my compose stack…
In my DNS, I had set a CNAME for the wildcard domain which returned both v4 and v6.

After fixing this, the “distinction” between v4 and v6 requests now works.

… that’s what comes from lack of sleep.

<!-- gh-comment-id:2268782493 --> @tsz-systems commented on GitHub (Aug 5, 2024): I found my mistake. It wasn’t related to my compose stack… In my DNS, I had set a CNAME for the wildcard domain which returned both v4 and v6. After fixing this, the “distinction” between v4 and v6 requests now works. … that’s what comes from lack of sleep.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/nsupdate.info-nsupdate-info#382
No description provided.