# How to get user IP after updating commit b4a3389

**URL:** https://meta.discourse.org/t/commit-b4a3389-ip/406267
**Category:** Self-hosting
**Tags:** nginx, cloudflare
**Created:** [June 27, 2026, 3:02am UTC](https://meta.discourse.org/t/commit-b4a3389-ip/406267 "2026-06-27T03:02:07Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![CLOUD\_PHT](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/cloud_pht/32/568863_2.png) [@CLOUD\_PHT](https://meta.discourse.org/u/CLOUD_PHT)
#### Post date: [June 27, 2026, 3:02am UTC](https://meta.discourse.org/t/commit-b4a3389-ip/406267/1 "2026-06-27T03:02:07Z")

</div>

After updating

> <https://github.com/discourse/discourse/commit/b4a3389751ebe118f58ec6dd5419d6007c61228f>
>
> nginx's responsibility is to determine the correct end user's IP (as far as we
> c…an trust it) and report that to Discourse.
> 
> The correct way to do that is to teach nginx how to determine this for itself -
> this means that both the nginx logs and the downstream value will be correct.
> 
> (see https://github.com/discourse/discourse\_docker/pull/1077 which removes the
> only use of \`proxy\_add\_x\_forwarded\_for\`)
> 
> Setting the x-f-f header to \`$proxy\_add\_x\_forwarded\_for\` or
> \`$http\_x\_forwarded\_for\` hides this learned knowledge and forces Discourse to go
> through the same process and possibly arrive at a edifferent answer.
> 
> In most cases this won't make a difference, but when there is more than one
> proxy in front of Discourse this exposes a failure case.
> 
> client → proxyA → proxyB → nginx → discourse
> 
> means Discourse saw:
> \`\`\`
> x-real-ip: client\_ip
> x-forwarded-for: client\_ip, proxyA
> \`\`\`
> 
> and might end using \`client\_ip\` or \`proxyA\_ip\` depending on codepath.
> 
> After this change, Discourse sees:
> \`\`\`
> x-real-ip: client\_ip
> x-forwarded-for: client\_ip
> \`\`\`
> 
> for the same situation.

All users’ last used addresses have changed to the Docker gateway, such as 172.17.0.1

My setup is as follows

Cloudflare → VPS Nginx → Discourse Docker Nginx → Discourse

---

<div class="post-metadata">

### Author: ![iamntz](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/iamntz/32/114670_2.png) [@iamntz](https://meta.discourse.org/u/iamntz)
#### Post date: [June 29, 2026, 3:21am UTC](https://meta.discourse.org/t/commit-b4a3389-ip/406267/2 "2026-06-29T03:21:13Z")

</div>

I have a similar setup like you do, here is what I’ve added to my host nginx config so it will pass the user’s IP:

```plaintext
location / {
  set_real_ip_from 103.21.244.0/22;
  set_real_ip_from 103.22.200.0/22;
  set_real_ip_from 103.31.4.0/22;
  set_real_ip_from 104.16.0.0/13;
  set_real_ip_from 104.24.0.0/14;
  set_real_ip_from 108.162.192.0/18;
  set_real_ip_from 131.0.72.0/22;
  set_real_ip_from 141.101.64.0/18;
  set_real_ip_from 162.158.0.0/15;
  set_real_ip_from 172.64.0.0/13;
  set_real_ip_from 173.245.48.0/20;
  set_real_ip_from 188.114.96.0/20;
  set_real_ip_from 190.93.240.0/20;
  set_real_ip_from 197.234.240.0/22;
  set_real_ip_from 198.41.128.0/17;
  set_real_ip_from 2400:cb00::/32;
  set_real_ip_from 2405:8100::/32;
  set_real_ip_from 2405:b500::/32;
  set_real_ip_from 2606:4700::/32;
  set_real_ip_from 2803:f800::/32;
  set_real_ip_from 2a06:98c0::/29;
  set_real_ip_from 2c0f:f248::/32;

  real_ip_header X-Forwarded-For;

  proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock:;

  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header Host $http_host;
  proxy_set_header X-Forwarded-Proto $scheme;

  proxy_http_version 1.1;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto https;
}

```

- Extra info: [Restoring original visitor IPs Â· Cloudflare Support docs](https://developers.cloudflare.com/support/troubleshooting/restoring-visitor-ips/restoring-original-visitor-ips/#nginx-1)
- The IPs are taken from here: [IP Ranges | Cloudflare](https://www.cloudflare.com/ips/)

---

<div class="post-metadata">

### Author: ![Lilly](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/lilly/32/575047_2.png) [@Lilly](https://meta.discourse.org/u/Lilly)
#### Post date: [June 29, 2026, 4:01pm UTC](https://meta.discourse.org/t/commit-b4a3389-ip/406267/3 "2026-06-29T16:01:19Z")

</div>

hello @CLOUD_PHT - welcome to Meta 🙂

i assume you are running more than one website on the same machine configuration? (like a wordpress site + discourse)

the issue is that you are routing traffic through docker’s internal network (port mapping), which masks all incoming requests as the docker gateway ip (`172.17.0.1`). because internal nginx doesn’t recognize `172.17.0.1` as a cloudflare ip, it drops the `CF-Connecting-IP` header for security.

to fix this, you need to switch your setup to use a unix socket - this allows your outer nginx to pass the traffic (and the headers) directly into Discourse without docker’s network borking the ip addresses.

follow this official guide, and make sure you keep `cloudflare.template.yml` in your `app.yml` file when you rebuild.

> [@Run other websites on the same machine as Discourse](https://meta.discourse.org/t/run-other-websites-on-the-same-machine-as-discourse/17247):
>
> @pfaffman edited this heavily 2022.02.24. Blame me if it’s broken. If you want to run other websites on the same machine as Discourse, you need to set up an extra NGINX or HAProxy proxy in front of the Docker container. NOTE: This is for advanced admins This guide assumes you already have Discourse working - if you don’t, it may be hard to tell whether or not the configuration is working. You cannot use ./discourse-setup to set up Discourse if another server is using port 80 or 443. You will…

---

<div class="post-metadata">

### Author: ![supermathie](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/supermathie/32/507518_2.png) [@supermathie](https://meta.discourse.org/u/supermathie)
#### Post date: [June 29, 2026, 5:13pm UTC](https://meta.discourse.org/t/commit-b4a3389-ip/406267/4 "2026-06-29T17:13:06Z")

</div>

That commit fixed a configuration error that you were relying on, but also that might have allowed any end user to spoof their IP address by setting that header.

> [@Lilly](#):
>
> to fix this, you need to switch your setup to use a unix socket

If you are confident nothing else can talk to your container, there is actually an easier way that doesn’t require the use of a socket - I have [just written](https://meta.discourse.org/t/handling-the-chain-of-trust-of-the-end-users-real-ip/406372) a guide on how to do this.

> [@CLOUD\_PHT](#):
>
> Cloudflare → VPS Nginx → Discourse Docker Nginx → Discourse

> [@Lilly](#):
>
> internal nginx doesn’t recognize `172.17.0.1`

For your setup @CLOUD_PHT you should add this to your container definition (if a `run` section already exists, add these directives to it, else add the `run` section):

```yaml
run:
  - 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-host.conf
      chmod: 644
      contents: |
        set_real_ip_from 172.17.0.1;

```

You _may_ also need the following:

```yaml
  - file:
      # we need to turn on recursive since we'll have at least two entries; one from the host, one from CloudFlare
      path: /etc/nginx/conf.d/outlets/server/real-ip-recursive.conf
      chmod: 644
      contents: |
        real_ip_recursive on;

```

depending on whether the nginx running on your server is itself processing the Cloudflare header to determine the end user’s real IP (this is suggested) or just adding its own on top. See [https://meta.discourse.org/t/handling-the-chain-of-trust-of-the-end-users-real-ip/406372#p-2001772-more-than-one-proxy-7](https://meta.discourse.org/t/handling-the-chain-of-trust-of-the-end-users-real-ip/406372#p-2001772-more-than-one-proxy-7) for more details.

* * *

**Other readers** : be aware this this directive

```yaml
run:
  - file:
      path: /etc/nginx/conf.d/outlets/server/set-real-ip-from-host.conf
      chmod: 644
      contents: |
        set_real_ip_from 172.17.0.1;

```

is _ **not appropriate for all setups** _. Only do this if _all connections to the Discourse container from this IP are trusted_.

Specifically, a known problem with IPv6 setups is that IPv6 connections to the server are _forwarded by docker over IPv4_ - the way that it’s done make all connections look like they’re coming from the host’s `docker0` IP address. If you apply the above directive to your setup, it’ll allow all users connecting over IPv6 to spoof their IP address at leisure.

---

<div class="post-metadata">

### Author: ![supermathie](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/supermathie/32/507518_2.png) [@supermathie](https://meta.discourse.org/u/supermathie)
#### Post date: [June 30, 2026, 10:57pm UTC](https://meta.discourse.org/t/commit-b4a3389-ip/406267/5 "2026-06-30T22:57:16Z")

</div>

4 posts were merged into an existing topic: [Handling the “chain of trust” of the end user’s real IP](https://meta.discourse.org/t/handling-the-chain-of-trust-of-the-end-users-real-ip/406372/2)

---

<div class="post-metadata">

### Author: ![system](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/system/32/443519_2.png) [@system](https://meta.discourse.org/u/system)
#### Post date: [July 30, 2026, 10:57pm UTC](https://meta.discourse.org/t/commit-b4a3389-ip/406267/6 "2026-07-30T22:57:21Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
