Files
netbird-docs/src/pages/manage/reverse-proxy/service-configuration.mdx
T
Maycon SantosandTechHutTV c2ccdf43e0 Documented NetBird-Only Access and Proxy Cluster features in reverse … (#767)
* Documented NetBird-Only Access and Proxy Cluster features in reverse proxy settings. Updated authentication methods, backend configuration guides, and cluster capability requirements.

* Expanded documentation for NetBird-Only services, updated Access Control baseline behavior, added details on Direct Upstream and Proxy Cluster features, and refined cluster capability descriptions.

* add private services diagrams and update auth screenshot

* Document ProxyService gRPC routes and expand reverse proxy configuration details

---------

Co-authored-by: TechHutTV <brandon@techhut.tv>
2026-06-05 08:16:03 -07:00

157 lines
8.9 KiB
Plaintext

import {Note, Warning} from "@/components/mdx"
export const description =
'Configure backend services like Jellyfin, Home Assistant, Plex, and Nextcloud to trust the NetBird reverse proxy IP range for correct client IP detection.'
# Backend Service Configuration
When a backend service sits behind a reverse proxy, it sees the proxy's IP address as the client IP instead of the real user's IP. Many self-hosted applications require you to configure a list of "trusted proxies" or "known proxies" so they can correctly read the real client IP from the `X-Forwarded-For` header.
With the NetBird Reverse Proxy, the proxy connects to your target service through a WireGuard tunnel. From the target's perspective, the source IP of incoming requests is the proxy's **NetBird IP** — an address from the `100.64.0.0/10` Carrier-Grade NAT range that NetBird uses for all peers.
<Warning>
**Do not hardcode a specific NetBird IP** (e.g., `100.64.0.47`) in your backend's trusted proxy configuration. NetBird IPs can change when the peer or service restarts, which would cause your backend to stop trusting the proxy and reject forwarded headers.
</Warning>
<Warning>
**Cloud-hosted usage limits:** NetBird's cloud-hosted Reverse Proxy is provided on a shared, best-effort basis. High-volume or sustained data transfers may be subject to bandwidth limits, rate limiting, and fair-use policies under the [NetBird Terms of Service](https://netbird.io/terms). These restrictions do not apply if you [self-host NetBird](/selfhosted/selfhosted-guide).
</Warning>
## Docker Bridge Networks
If the NetBird peer and the backend service run as containers on the **same Docker bridge network** (for example, when using the Home Assistant NetBird add-on), traffic between them does not traverse the WireGuard tunnel. In this case, the backend sees the NetBird container's **Docker bridge IP** (typically from `172.16.0.0/12`) rather than a NetBird IP.
When this applies, add the Docker bridge subnet to your trusted proxy list **in addition to** the NetBird range:
```
100.64.0.0/10
172.16.0.0/12
```
<Note>
The default Docker bridge subnet is `172.17.0.0/16`, but Docker and add-on managers may assign addresses from anywhere in the `172.16.0.0/12` range. Check your Docker network configuration (`docker network inspect <network>`) to find the exact subnet if you want a narrower entry.
</Note>
## Recommended Solution
Instead of specifying a single IP, configure your backend to trust the **entire NetBird CGNAT range**:
```
100.64.0.0/10
```
This covers all possible NetBird IPs regardless of reassignment. This is safe because only authorized peers within your NetBird network can reach the target through the encrypted WireGuard tunnel — no external traffic can originate from this range.
If the NetBird peer runs on the same Docker bridge network as the backend (see [above](#docker-bridge-networks)), also add the Docker bridge range `172.16.0.0/12`.
<Note>
If you prefer a narrower NetBird range, you can use your account's specific network range (typically `100.64.0.0/16`). Find your account's range via the API: `GET /api/accounts/{id}` — look for the `network_range` field. However, the full `/10` range is recommended for simplicity and resilience.
</Note>
## Service-specific Examples
Below are configuration examples for common self-hosted applications. Configuration options may vary by version — consult each application's official documentation for the most current syntax.
### Jellyfin
In the Jellyfin admin dashboard:
1. Go to **Dashboard** → **Networking**.
2. In the **Known Proxies** field, enter `100.64.0.0/10`.
3. Click **Save**.
<p>
<img src="/docs-static/img/manage/reverse-proxy/service-configuration/jellyfin-known-proxies.png" alt="Jellyfin Networking settings showing 100.64.0.0/10 in the Known Proxies field" className="imagewrapper-large"/>
</p>
This tells Jellyfin to trust forwarded headers from any NetBird IP, allowing it to see the real client IP. Additionally, Jellyfin supports adding a 'Base URL' this can be used in conjunction with setting a location while [configuring your service](https://docs.netbird.io/manage/reverse-proxy#step-2-configure-service-details) on the NetBird Reverse Proxy service.
### Home Assistant
In your `configuration.yaml`, add or update the `http` section. You can do this through the File Editor or Studio Code Server add-on, or via the command line if you have terminal access. If you want to learn more about Home Assistant checkout our [full guide on the Knowledge Hub](https://netbird.io/knowledge-hub/home-assistant-access).
```yaml
http:
use_x_forwarded_for: true
trusted_proxies:
- 100.64.0.0/10
```
If you are running the [NetBird add-on](https://github.com/netbirdio/addon-netbird) (which runs as a Docker container on the same host), also add the Docker bridge range. Click the button below to get this add-on.
[![Add NetBird add-on repository](/docs-static/img/manage/reverse-proxy/service-configuration/ha_add_addon_repository.svg)](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2Fglemsom%2Fhassio-netbird)
```yaml
http:
use_x_forwarded_for: true
trusted_proxies:
- 100.64.0.0/10
- 172.16.0.0/12
```
Restart Home Assistant after making this change. Without `use_x_forwarded_for` and a matching `trusted_proxies` entry, Home Assistant will block requests from the reverse proxy.
### Nextcloud
In your Nextcloud `config/config.php`, add the NetBird range to the `trusted_proxies` array:
```php
'trusted_proxies' => ['100.64.0.0/10'],
```
If you're running NextCloud AIO this should be configured automatically during setup, but if needed you can use `sudo docker exec -u 0 -it nextcloud-aio-nextcloud /bin/bash`.
Nextcloud supports CIDR notation for IPv4 ranges. When a request arrives from a trusted proxy, Nextcloud reads the real client IP from the `X-Forwarded-For` header instead of using the proxy's IP.
## NetBird identity headers
Services configured with [NetBird-Only Access](/manage/reverse-proxy/authentication#netbird-only-access-private-services) are private — every inbound request is authenticated against the WireGuard tunnel before it reaches your backend. The proxy attaches two headers to each upstream request identifying the caller:
| Header | Value |
|--------|-------|
| `X-NetBird-User` | The calling user's email (or peer name when the peer has no user owner). |
| `X-NetBird-Groups` | Comma-separated list of the user's group display names. Falls back to group IDs at positions where the display name was unavailable at session-mint time. |
Use these headers in your backend to drive per-user authorization, audit logging, or personalization without running your own login flow. Because the proxy has already verified the caller's WireGuard identity, the headers are trustworthy for any backend that sits behind a NetBird-Only service.
<Warning>
**Anti-spoof discipline.** The proxy strips any client-supplied `X-NetBird-User` or `X-NetBird-Groups` headers from the inbound request before stamping its own values. Your backend should still verify it is reachable only through a NetBird-Only service — anything that bypasses the proxy (e.g., direct connections from inside your Docker network) will reach the backend without these headers, and your code should treat their absence as "unauthenticated."
</Warning>
### Example: read the user in a backend
```python
from fastapi import FastAPI, Header, HTTPException
app = FastAPI()
@app.get("/me")
def me(
user: str | None = Header(default=None, alias="X-NetBird-User"),
groups: str | None = Header(default=None, alias="X-NetBird-Groups"),
):
if user is None:
raise HTTPException(403, "must be accessed through a NetBird private service")
return {
"user": user,
"groups": groups.split(",") if groups else [],
}
```
The same pattern works in any backend framework — read the two headers, refuse the request if `X-NetBird-User` is absent, and use the groups for per-user authorization decisions.
## Verifying your configuration
After updating your backend's trusted proxy settings:
1. Access your service through the NetBird reverse proxy URL.
2. Check the backend's access logs — the logged client IP should be the **real user's IP**, not a `100.64.x.x` address.
3. If the backend still shows a NetBird IP, verify that **Pass Host Header** is enabled in your reverse proxy service's [Settings tab](/manage/reverse-proxy#step-4-configure-advanced-settings) and that you have restarted the backend service after changing its configuration.
You can also monitor requests from the NetBird side using [Access Logs](/manage/reverse-proxy/access-logs).
## Related pages
- [Reverse Proxy Overview](/manage/reverse-proxy) — setup, concepts, and service management
- [Access Logs](/manage/reverse-proxy/access-logs) — monitor traffic to your reverse proxy services
- [How NetBird Works](/about-netbird/how-netbird-works) — details on IP assignment from the CGNAT range