Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/pages/selfhosted/external-reverse-proxy.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ This is not to be confused with the NetBird reverse proxy service that launched

Not all reverse proxies are supported as NetBird uses *gRPC* for various components. Your reverse proxy must support HTTP/2 and gRPC proxying.

<Note>
If the dashboard shows a peer's **Public IP** as the Docker network's gateway address (for example `172.30.0.1`), this is not a header or `trustedHTTPProxies` problem. On a dual-stack host, IPv6 traffic is re-originated from the bridge gateway before your reverse proxy sees it, so `X-Forwarded-For` and `X-Real-IP` cannot recover the real address. See [IPv6 and dual-stack hosts](/selfhosted/selfhosted-quickstart#i-pv6-and-dual-stack-hosts) for the fix.
</Note>

Starting with **v0.65.0**, new NetBird installations use a **combined container** (`netbirdio/netbird-server`) that merges management, signal, and relay into a single service. This simplifies reverse proxy configuration because all traffic routes to one backend. The templates on this page cover both setups:

- **[Combined container (v0.65.0+)](#combined-container-setup-v0-65-0)** -- the default for new installations. All backend services run in a single container on one port.
Expand Down
53 changes: 52 additions & 1 deletion src/pages/selfhosted/selfhosted-quickstart.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ This is the quickest way to try self-hosted NetBird. It should take around 5 min
## Infrastructure requirements
- A Linux VM with at least **1CPU** and **2GB** of memory.
- The VM must be publicly accessible on **TCP ports 80 and 443**, and **UDP port 3478**.
- A **public domain** name that resolves to the VM's public IP address (e.g. `netbird.example.com`).
- A **public domain** name that resolves to the VM's public IP address (e.g. `netbird.example.com`). On a dual-stack host, see [IPv6 and dual-stack hosts](#i-pv6-and-dual-stack-hosts) below.

## Software requirements

Expand Down Expand Up @@ -192,6 +192,57 @@ Once your NetBird instance is running, refer to these guides for ongoing mainten

Check that the connector is properly configured in **Settings** → **Identity Providers**. Ensure the redirect URL is correctly configured in your IdP.

### IPv6 and dual-stack hosts

On a host that is dual-stack and whose NetBird domain also has an `AAAA` record, peers that connect over IPv6 can be recorded with the Docker bridge gateway address (for example `172.30.0.1`) as their **Public IP** in the dashboard, shown with Region **Unknown**. The same peer shows its real public IP when it connects over IPv4, so the value appears to flip between logins.

This happens because the getting-started script creates an IPv4-only Docker network. IPv4 traffic reaches the containers through iptables NAT, which preserves the client's source IP, but IPv6 traffic has no path into the bridge and is handled by Docker's userland proxy. That proxy re-originates the connection over IPv4 from the bridge gateway, so management records the gateway address. It happens before any reverse proxy sees the request, so `X-Forwarded-For`, `X-Real-IP`, and `trustedHTTPProxies` settings cannot correct it.

To fix it, give the Docker network a real IPv6 path. Apply these steps together:

1. Enable IPv6 on the `netbird` network in `docker-compose.yml`, with a private (ULA) subnet:

```yaml
networks:
netbird:
enable_ipv6: true
ipam:
config:
- subnet: fd00:b14d::/64
```

2. Make sure Docker's `ip6tables` support is active, so Docker installs the IPv6 NAT and filter rules for the network. On **Docker Engine 27 and later** it is enabled by default, so no change is needed. On **older engines** it was experimental, so enable it in `/etc/docker/daemon.json` and restart Docker:

```json
{
"experimental": true,
"ip6tables": true
}
```

3. Recreate the `netbird` network so Docker applies the new options. Docker reads a network's settings only when it first creates the network, so an already-running deployment keeps its old IPv4-only network until you recreate it. From your NetBird directory:

```shell
docker compose down
docker compose up -d
```

`docker compose down` removes the containers and networks but keeps your named volumes, so no data is lost. Do not add the `-v` flag, which would delete the data volumes.

<Warning>
Enabling `enable_ipv6` without `ip6tables` can expose containers directly over IPv6, with no NAT and no Docker-managed filtering. Always apply the two together.
</Warning>

If you do not need IPv6 reachability, there is a simpler alternative: remove the `AAAA` record for your NetBird domain so every peer connects over IPv4.

<Note>
On hosts where IPv6 is disabled in the kernel (the `ipv6.disable=1` boot parameter), creating an IPv6-enabled network fails at `docker compose up`. Use the `AAAA`-removal alternative on those hosts.
</Note>

<Note>
This section is about the Docker network the NetBird server runs on, not the IPv6 addresses peers receive inside the NetBird network. For the latter, see [IPv6 Overlay Addressing](/manage/settings/ipv6).
</Note>

For more troubleshooting help, see the [Troubleshooting guide](/selfhosted/troubleshooting).

---
Expand Down
6 changes: 6 additions & 0 deletions src/pages/selfhosted/troubleshooting/dashboard.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,9 @@ Problems with the self-hosted dashboard. For other areas, start from [Troublesho
3. **Management can't validate the token.** Review `docker compose logs management` for token-validation errors.

**Confirm**: Re-run the action. It succeeds, and the Management logs show no auth errors.

## Peer Public IP shows a Docker or internal IP

**Symptom**: A peer's **Public IP** in the dashboard shows the Docker bridge gateway (for example `172.30.0.1`) with Region **Unknown**, and it changes back to the real public IP on the next login.

**Cause and fix**: On a dual-stack host whose NetBird domain has an `AAAA` record, IPv6 connections reach the containers through Docker's userland proxy, which rewrites the source to the bridge gateway before any reverse proxy sees it. Give the Docker network a real IPv6 path, or remove the `AAAA` record. See [IPv6 and dual-stack hosts](/selfhosted/selfhosted-quickstart#i-pv6-and-dual-stack-hosts) for the full fix.
Loading