Remote users IPV6 address shows as localhost

I’ve just noticed that the IP addresses for a lot of members on my forum are being stored as 172.17.0.1. I’m not running a reverse proxy or anything - there’s nothing between you and Discourse’s Docker. Any ideas?

Are you using CloudFlare or anything similar?

Only for DNS (grey mode). (Technically I think I have orange mode for www.intfiction.org, but it will be redirected to the apex intfiction.org before it hits my server.) I have the following in my app.yml, though I didn’t think either part would be relevant:

  after_web_config:
    - replace:
        filename: /etc/nginx/nginx.conf
        from: /sendfile.+on;/
        to: |
          server_names_hash_bucket_size 64;
          sendfile on;
    - file:
        path: /etc/nginx/conf.d/discourse_redirect_1.conf
        contents: |
          server {
            listen 80;
            server_name www.intfiction.org;
            return 301 $scheme://intfiction.org$request_uri;
          }

See Last IP address and action_dispatch.trusted_proxies

1 Like

Won’t that only be relevant if there’s a proxy in front of my server?

I’m also experiencing this issue, after migrating my Discourse to a new server and deciding to NOT use Cloudflare.

I reinstalled Discourse from scratch then restored my backup.
I never re-added the Cloudflare template option from app.yml.

I tried adding the code from the other thread also:

- replace:
filename: /etc/nginx/conf.d/discourse.conf
from: "types {"
to: |
  set_real_ip_from 10.0.0.0/24;
  set_real_ip_from 172.17.0.0/24;
  real_ip_header X-Forwarded-For;
  real_ip_recursive on;
  types {

to app.yml but the issue still stands:

All IPv6 users show their last IP as 172.17.0.1.

IPv4 users addresses are shown perfectly.

There’s no reverse proxy or anything in use on this server - just the standard Discourse install as set out in the docs, serving traffic to 80/443.

3 Likes

I think I know why this is happening.

For IPv4 Docker inserts firewall rules into iptables to reverse NAT from the exposed host address/port to the container host/port. This lets the container see the original source address.
For IPv6 Docker uses a userland proxy (docker-proxy) which just forwards from one port to the other. This causes the container to see the source address as localhost. This isn’t a HTTP aware proxy it is just port forwarding so it is unable to insert X-Forwarded-For headers.

The core Docker project hasn’t added support for doing NAT on IPv6, either because they think IPv6 NAT is icky or because they haven’t got around to doing it.

But you can fix this by enabling IPv6 for Docker and then running a container which automatically inserts the correct IPv6 NAT rules.

See Enable IPv6 for Docker containers on Ubuntu 18.04 | Medium for a guide to how to set this up.

TLDR: Make sure IPv6 works in your containers and then run https://github.com/robbertkl/docker-ipv6nat

7 Likes

Is this something that has to be changed within the app/Docker container, externally or both? I assume both… but this sound like high level admin stuff. If confirmed, an easy to follow guide on how to enable Discourse (Docker) for IPv6 would be highly appreciated.

2 Likes

I’ll have a go at implementing this on my site later and try to document my steps. By no means am I a docker expert but I think it shouldn’t be too difficult.

2 Likes

Sadly this has been more tricky than expected due to my limited Docker knowledge. I’m currently experimenting with just proxying discourse through nginx running on the house to get around this limitation. If all else fails I’ll go back to using cloudflare but I’d rather not rely on them for a functional site.

1 Like

A quick note to anyone interested: Putting Discourse behind nginx is the easiest solution to this issue. Use the link in the default app.yml comments for setting up Discourse on a socket. Added benefit for me has been the ability to set up a custom error page to appear during rebuilds.

3 Likes