mcdanlj
(Michael K Johnson)
July 16, 2026, 1:02pm
1
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. But I’d appreciate pointers on what might have changed, to which I need to adapt.
pfaffman
(Jay Pfaffman)
July 16, 2026, 1:27pm
2
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.
run:
- file:
path: /etc/nginx/conf.d/outlets/server/real-ip-header.conf
chmod: 644
contents: |
real_ip_header cf-connecting-ip;
- exec:
cmd:
# avoid the trap of specifying both URLs on one curl line; the data might not have a final newline
# print sprintf looks dubious at first, but avoids the problem of "how many times do you backslash a \\\\n"
- curl -s https://www.cloudflare.com/ips-v4/ | awk '{print sprintf("set_real_ip_from %s;", $0)}' > /etc/nginx/conf.d/outlets/server/set-real-ip-from-cloudflare.conf
- curl -s https://www.cloudflare.com/ips-v6/ | awk '{print sprintf("set_real_ip_from %s;", $0)}' >> /etc/nginx/conf.d/outlets/server/set-real-ip-from-cloudflare.conf
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 {
chapoi
July 16, 2026, 2:39pm
3
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:
Background
Discourse needs to be aware of the end user’s real IP address.
However, an end user never directly connects to Discourse since there is always one or more upstream web servers (nginx running in the Discourse container) in place. Thus, we need a way to pass along that information to Discourse in a trusted manner.
The x-forwarded-for header is the solution. In this topic I will describe the specific mechanisms for properly handling that information and how we’re expecting it to be pro…
mcdanlj
(Michael K Johnson)
July 16, 2026, 3:16pm
4
As usual, posting it and seeing responses helps me find other similar posts. e.g.
Hi,
I have researched quite a lot but nothing seems to work with me.
I have a discourse setup installed. And I have this remote reverse proxy server that acts as a HTTPS layer between the user and the main discourse server..
[image]
I have included these revers proxy settings properly.. But why does it still show my Reverse Proxy server’s IP Address (hostname to be specific)
[image]
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 {
mcdanlj
(Michael K Johnson)
July 16, 2026, 5:07pm
5
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;