Real IP no longer recognized through proxy

In the past couple of months (not sure exactly when this started), I’ve seen that my external nginx configuration, as documented in Add an offline page to display when Discourse is rebuilding or starting up , to pass through the real IP address is being ignored.

This external nginx configuration has worked for years:

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header X-Real-IP $remote_addr;

Now I’m seeing all traffic attributed to the internal docker network in RFC1918 space, like so:

This is obviously breaking the “apply this penalty to other users sharing this IP address” and all other uses of the real remote IP address.

I expect this has been addressed somewhere and I am just searching poorly. :frowning: But I’d appreciate pointers on what might have changed, to which I need to adapt.

I remember something about this recently but I can’t find it either. Handling the "chain of trust" of the end user's real IP - #8 by supermathie includes a link to the cloudflare template, which I think may be a good model.

Here’s what I’m doing and it seems to still work (as of “Discourse 2026.6.0-latest - GitHub - discourse/discourse: A platform for community discussion. Free, open, simple. · GitHub version 5c507d8359f4d6e8a5d98780c622d51cedbd9bd7”)

after_bundle_exec:
  - replace:
    filename: /etc/nginx/conf.d/discourse.conf
    from: "types {"
    to: |
      set_real_ip_from 192.168.1.0/24;
      set_real_ip_from 192.168.11.0/24;
      set_real_ip_from 172.16.0.0/12;
      set_real_ip_from 10.0.0.0/8;
      real_ip_recursive on;
      real_ip_header X-Forwarded-For;
      types {

Probably related to this commit: FIX: nginx sample configuration should be setting x-f-f to the end us… · discourse/discourse@b4a3389 · GitHub

This may help you:

As usual, posting it and seeing responses helps me find other similar posts. :rofl: e.g.

Thanks y’all! Off to configure set_real_ip_from in the container nginx!

I’m going to do the entire RFC1918 space though. For anyone else’s reference, that would be:

after_bundle_exec:
  - replace:
    filename: /etc/nginx/conf.d/discourse.conf
    from: "types {"
    to: |
      set_real_ip_from 192.168.0.0/16;
      set_real_ip_from 172.16.0.0/12;
      set_real_ip_from 10.0.0.0/8;
      real_ip_recursive on;
      real_ip_header X-Forwarded-For;
      types {

That’s not working for me.

I now understand why it quit working for me from the referenced commit; it broke the set_real_ip replace that I’d had in place for years. The rationale of making it more robust is sane, and this is a better route; one breaking change and then should break less in the future.

I don’t know why the after_bundle_exec replace isn’t applying, but I’m going to switch to dropping in files.

This works for me; sharing for the next person:

run:
  - file:
     path: /etc/nginx/conf.d/outlets/server/real-ip-recursive.conf
     chmod: 644
     contents: |
       real_ip_recursive on;
  - file:
     path: /etc/nginx/conf.d/outlets/server/real-ip-header.conf
     chmod: 644
     contents: |
       real_ip_header X-Forwarded-For;
  - file:
     path: /etc/nginx/conf.d/outlets/server/set-real-ip-from.conf
     chmod: 644
     contents: |
       set_real_ip_from 192.168.0.0/16;
       set_real_ip_from 172.16.0.0/12;
       set_real_ip_from 10.0.0.0/8;