[GH-ISSUE #5331] Dashboard UI displays Docker gateway address (172.30.0.1) as peer's "Public IP" when NetBird server is deployed behind Traefik reverse proxy in Docker bridge network #11015

Closed
opened 2026-08-05 01:28:10 -04:00 by saavagebueno · 5 comments
Owner

Originally created by @Martin-Winfred on GitHub (Feb 15, 2026).
Original GitHub issue: https://github.com/netbirdio/netbird/issues/5331

Describe the problem

When NetBird self-hosted control plane is deployed with Traefik reverse proxy in a Docker custom bridge network (172.30.0.0/24), the Dashboard UI incorrectly shows 172.30.0.1 (Docker network gateway) as the "Public IP" for all connected peers in the Peers list.

This occurs despite:

  • Peers connecting from distinct public IPv4 addresses (verified via curl ifconfig.me on client devices)
  • STUN service functioning correctly (peers establish direct WireGuard connections)
  • All NetBird connectivity features working as expected

The issue appears limited to UI display – peer connectivity and NAT traversal remain functional.


To Reproduce

  1. Deploy NetBird self-hosted stack using Docker Compose with custom bridge network (172.30.0.0/24, gateway 172.30.0.1)
  2. Configure Traefik v3.6 as reverse proxy in the same bridge network, publishing ports 80/443 to host
  3. Set exposedAddress: "https://<your-domain>:443" in config.yaml
  4. Connect multiple peers from different public networks (e.g., home broadband, mobile data)
  5. Log into Dashboard UI → Peers page
  6. Observe all peers display identical "Public IP": 172.30.0.1

Expected behavior

Dashboard UI should display each peer's actual public IPv4/IPv6 address (the source IP observed by the server when the peer initiates connection), matching the result of curl ifconfig.me executed on the peer device.


Actual behavior

All peers display 172.30.0.1 (RFC 1918 private address) as their "Public IP" in the Dashboard UI.


Environment

Component Version / Configuration
NetBird version netbirdio/netbird-server:latest (image pulled 2026-02-15), Management server version 0.65.1
Dashboard version netbirdio/dashboard:latest
Deployment Docker Compose on Linux
Network mode Custom bridge network (172.30.0.0/24, gateway 172.30.0.1)
Reverse proxy Traefik v3.6
TLS termination Traefik (Let's Encrypt ACME)
Public access Domain-based (https://netbird.p---------e.org:443)
STUN External STUN server (stun:nerelay.p---------er.online:3478)

Evidence

Traefik access logs

All gRPC requests from peers show source IP 172.30.0.1:

netbird-traefik | 172.30.0.1 - - [15/Feb/2026:06:08:43 +0000] "POST /management.ManagementService/Login HTTP/2.0" 200 345 ...
netbird-traefik | 172.30.0.1 - - [15/Feb/2026:06:08:48 +0000] "POST /management.ManagementService/Sync HTTP/2.0" 200 2080 ...
netbird-traefik | 172.30.0.1 - - [15/Feb/2026:06:08:48 +0000] "POST /signalexchange.SignalExchange/Send HTTP/2.0" 200 5 ...

External HTTP requests (non-gRPC) correctly preserve source IP:

netbird-traefik | 66.228.36.223 - - [15/Feb/2026:06:09:08 +0000] "GET / HTTP/1.0" 404 19 ...

NetBird server logs

netbird-server | 2026-02-15T06:08:13Z INFO combined/cmd/root.go:596:   Exposed address: https://netbird.p---------e.org:443

Impact

  • Loss of peer geolocation/audit capability in Dashboard UI
  • Inability to distinguish peers by network origin in UI
  • Peer connectivity unaffected (direct/hole-punched connections work)
  • STUN service correctly facilitates NAT traversal

Additional notes

  • Issue occurs with both netbirdio/netbird-server:latest and v0.65.1 tags
  • Peers connect successfully via domain name (exposedAddress)
  • STUN port (3478/udp) is published directly on host (not proxied)
  • No custom IP-related settings configured beyond exposedAddress
  • Even without setup the exterinal STUN and realy server, this issue maintains the same
  • This selfhosted instance was build by script in release version "v0.65.0", with default setting as
Do you want to enable the NetBird Proxy service?
The proxy exposes internal NetBird network resources to the internet.
Enable proxy? [y/N]:N
Originally created by @Martin-Winfred on GitHub (Feb 15, 2026). Original GitHub issue: https://github.com/netbirdio/netbird/issues/5331 ## Describe the problem When NetBird self-hosted control plane is deployed with Traefik reverse proxy in a Docker custom bridge network (`172.30.0.0/24`), the Dashboard UI incorrectly shows `172.30.0.1` (Docker network gateway) as the **"Public IP"** for all connected peers in the Peers list. This occurs despite: - Peers connecting from distinct public IPv4 addresses (verified via `curl ifconfig.me` on client devices) - STUN service functioning correctly (peers establish direct WireGuard connections) - All NetBird connectivity features working as expected The issue appears limited to UI display – peer connectivity and NAT traversal remain functional. --- ## To Reproduce 1. Deploy NetBird self-hosted stack using Docker Compose with custom bridge network (`172.30.0.0/24`, gateway `172.30.0.1`) 2. Configure Traefik v3.6 as reverse proxy in the same bridge network, publishing ports 80/443 to host 3. Set `exposedAddress: "https://<your-domain>:443"` in `config.yaml` 4. Connect multiple peers from different public networks (e.g., home broadband, mobile data) 5. Log into Dashboard UI → **Peers** page 6. Observe all peers display identical "Public IP": `172.30.0.1` --- ## Expected behavior Dashboard UI should display each peer's actual public IPv4/IPv6 address (the source IP observed by the server when the peer initiates connection), matching the result of `curl ifconfig.me` executed on the peer device. --- ## Actual behavior All peers display `172.30.0.1` (RFC 1918 private address) as their "Public IP" in the Dashboard UI. --- ## Environment | Component | Version / Configuration | |-----------|-------------------------| | NetBird version | `netbirdio/netbird-server:latest` (image pulled 2026-02-15), Management server version 0.65.1 | | Dashboard version | `netbirdio/dashboard:latest` | | Deployment | Docker Compose on Linux | | Network mode | Custom bridge network (`172.30.0.0/24`, gateway `172.30.0.1`) | | Reverse proxy | Traefik v3.6 | | TLS termination | Traefik (Let's Encrypt ACME) | | Public access | Domain-based (`https://netbird.p---------e.org:443`) | | STUN | External STUN server (`stun:nerelay.p---------er.online:3478`) | --- ## Evidence ### Traefik access logs All gRPC requests from peers show source IP `172.30.0.1`: ``` netbird-traefik | 172.30.0.1 - - [15/Feb/2026:06:08:43 +0000] "POST /management.ManagementService/Login HTTP/2.0" 200 345 ... netbird-traefik | 172.30.0.1 - - [15/Feb/2026:06:08:48 +0000] "POST /management.ManagementService/Sync HTTP/2.0" 200 2080 ... netbird-traefik | 172.30.0.1 - - [15/Feb/2026:06:08:48 +0000] "POST /signalexchange.SignalExchange/Send HTTP/2.0" 200 5 ... ``` External HTTP requests (non-gRPC) correctly preserve source IP: ``` netbird-traefik | 66.228.36.223 - - [15/Feb/2026:06:09:08 +0000] "GET / HTTP/1.0" 404 19 ... ``` ### NetBird server logs ``` netbird-server | 2026-02-15T06:08:13Z INFO combined/cmd/root.go:596: Exposed address: https://netbird.p---------e.org:443 ``` --- ## Impact - ❌ Loss of peer geolocation/audit capability in Dashboard UI - ❌ Inability to distinguish peers by network origin in UI - ✅ Peer connectivity unaffected (direct/hole-punched connections work) - ✅ STUN service correctly facilitates NAT traversal --- ## Additional notes - Issue occurs with both `netbirdio/netbird-server:latest` and `v0.65.1` tags - Peers connect successfully via domain name (`exposedAddress`) - STUN port (`3478/udp`) is published directly on host (not proxied) - No custom IP-related settings configured beyond `exposedAddress` - Even without setup the exterinal STUN and realy server, this issue maintains the same - This selfhosted instance was build by script in release version "v0.65.0", with default setting as ``` Do you want to enable the NetBird Proxy service? The proxy exposes internal NetBird network resources to the internet. Enable proxy? [y/N]:N ```
saavagebueno added the triage-needed label 2026-08-05 01:28:10 -04:00
Author
Owner

@Martin-Winfred commented on GitHub (Feb 15, 2026):

The issue is resolved by simply configuring NetBird's reverseProxy.trustedHTTPProxies in config.yaml:

management:
  reverseProxy:
    trustedHTTPProxies:
      - "172.30.0.0/24"
   trustedHTTPProxiesCount: 1

No changes to Traefik configuration are required, as Traefik automatically adds the X-Forwarded-For header by default.
The example config can be found in Example config

<!-- gh-comment-id:3904384936 --> @Martin-Winfred commented on GitHub (Feb 15, 2026): The issue is resolved by simply configuring NetBird's `reverseProxy.trustedHTTPProxies` in `config.yaml`: ```yaml management: reverseProxy: trustedHTTPProxies: - "172.30.0.0/24" trustedHTTPProxiesCount: 1 ``` No changes to Traefik configuration are required, as Traefik automatically adds the `X-Forwarded-For` header by default. The example config can be found in [Example config](https://github.com/netbirdio/netbird/blob/main/combined/config.yaml.example)
Author
Owner

@netsrot303 commented on GitHub (Apr 12, 2026):

I have the same issue on a fresh netbird Ui install. Some peers are shown with "Region unknown" and "Public IP 172.30.0.1". I changed the config.yaml with your example but with no success.

  reverseProxy:
    trustedHTTPProxies:
      - "172.30.0.0/24"
    trustedHTTPProxiesCount: 1
<!-- gh-comment-id:4231956121 --> @netsrot303 commented on GitHub (Apr 12, 2026): I have the same issue on a fresh netbird Ui install. Some peers are shown with "Region unknown" and "Public IP 172.30.0.1". I changed the config.yaml with your example but with no success. ``` reverseProxy: trustedHTTPProxies: - "172.30.0.0/24" trustedHTTPProxiesCount: 1 ```
Author
Owner

@Martin-Winfred commented on GitHub (Apr 16, 2026):

Have you tried to let clients restart? My issue could be fixed after restarting the client.
Down there is the running config I am using.

management:
  reverseProxy:
    # Tell NetBird: Trust comes from these CIDR proxies (i.e., the network where Traefik resides).
    trustedHTTPProxies:
      - "172.30.0.0/24"   # Your Docker custom bridge network segment
    #Alternatively, you could be even stricter and only trust the Traefik container IP (such as 17ectl.30.2).
    # trustedHTTPProxies:
    #   - "172.30.2.0/32"

    # If there are multiple layers of proxies (e.g., Cloudflare → Traefik), set the number of layers.
    # Typically, a single layer is set to 1.
    trustedHTTPProxiesCount: 1

    # Optional: Additional trusted peers (generally not used)
    #trustedPeers: []

I added some commits, so you might understand this section better. I am using the Traefik so I am not shure about other configs.

<!-- gh-comment-id:4260458697 --> @Martin-Winfred commented on GitHub (Apr 16, 2026): Have you tried to let clients restart? My issue could be fixed after restarting the client. Down there is the running config I am using. ```yaml management: reverseProxy: # Tell NetBird: Trust comes from these CIDR proxies (i.e., the network where Traefik resides). trustedHTTPProxies: - "172.30.0.0/24" # Your Docker custom bridge network segment #Alternatively, you could be even stricter and only trust the Traefik container IP (such as 17ectl.30.2). # trustedHTTPProxies: # - "172.30.2.0/32" # If there are multiple layers of proxies (e.g., Cloudflare → Traefik), set the number of layers. # Typically, a single layer is set to 1. trustedHTTPProxiesCount: 1 # Optional: Additional trusted peers (generally not used) #trustedPeers: [] ``` I added some commits, so you might understand this section better. I am using the `Traefik` so I am not shure about other configs.
Author
Owner

@Martin-Winfred commented on GitHub (Apr 16, 2026):

if this did not help, you can also try add those fonfig in docker-compose config

- "--entrypoints.websecure.forwardedHeaders.trustedIPs=172.30.0.0/24"

Middleware

- traefik.http.middlewares.netbird-headers.headers.customrequestheaders.X-Forwarded-Proto=https

Those configs might lead to other security issues, must review and evaluate it.

<!-- gh-comment-id:4260531941 --> @Martin-Winfred commented on GitHub (Apr 16, 2026): if this did not help, you can also try add those fonfig in docker-compose config ``` - "--entrypoints.websecure.forwardedHeaders.trustedIPs=172.30.0.0/24" ``` *Middleware* ``` - traefik.http.middlewares.netbird-headers.headers.customrequestheaders.X-Forwarded-Proto=https ``` Those configs might lead to other security issues, must review and evaluate it.
Author
Owner

@netsrot303 commented on GitHub (Apr 16, 2026):

I'm sorry I didn't mention this, but the problem has been resolved. It turned out that the clients were connecting via IPv6. I deleted the AAAA record so that the peers could only connect via IPv4, and after that, the correct public IP was always displayed.

<!-- gh-comment-id:4260968952 --> @netsrot303 commented on GitHub (Apr 16, 2026): I'm sorry I didn't mention this, but the problem has been resolved. It turned out that the clients were connecting via IPv6. I deleted the AAAA record so that the peers could only connect via IPv4, and after that, the correct public IP was always displayed.
Sign in to join this conversation.
No Label triage-needed
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: DYNR/netbird#11015