Add backend service configuration guide trusted proxies and fix images (#639)
* Add backend service configuration guide for reverse proxy trusted proxies Many self-hosted services (Jellyfin, Home Assistant, Nextcloud, Plex) require a "trusted proxies" or "known hosts" setting when behind a reverse proxy. With NetBird, the proxy's IP is a dynamic NetBird IP from 100.64.0.0/10 that can change on restart, so hardcoding it breaks. This adds a new doc page with the recommended solution (trust the full CGNAT range), per-service config examples, Docker bridge network guidance, and a warning on the reverse proxy overview page. * Update service-configuration.mdx and move/add images * Fixing typos --------- Co-authored-by: Brandon Hopkins <brandon@techhut.tv>
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 107 KiB |
|
Before Width: | Height: | Size: 265 KiB After Width: | Height: | Size: 265 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="40" aria-label="Add app repository to My Home Assistant" style="border-radius:24px;width:auto" viewBox="0 0 639 96"><rect width="639" height="96" fill="#18BCF2" rx="48"/><path fill="#fff" d="M40.27 60.2h4.86l1.97-5.16h9.72l1.97 5.16h4.86l-9.24-23.45h-4.9Zm8.37-9.21 3.32-8.65 3.32 8.65Zm18.5 9.21h7.5c7.17 0 12.23-4.86 12.23-11.73 0-6.86-5.06-11.72-12.23-11.72h-7.5Zm7.5-19.16c4.29 0 7.54 3.21 7.54 7.43 0 4.23-3.25 7.44-7.54 7.44h-2.92V41.04ZM91.26 60.2h7.5c7.17 0 12.23-4.86 12.23-11.73 0-6.86-5.06-11.72-12.23-11.72h-7.5Zm7.5-19.16c4.29 0 7.54 3.21 7.54 7.43 0 4.23-3.25 7.44-7.54 7.44h-2.92V41.04Zm22.98 19.16h4.86l1.97-5.16h9.72l1.98 5.16h4.85l-9.24-23.45h-4.89Zm8.38-9.21 3.31-8.65 3.32 8.65Zm18.49 9.21h4.59v-7.77h4.49c4.72 0 8.07-3.29 8.07-7.87 0-4.59-3.48-7.88-8.44-7.84l-4.66.03h-4.05Zm8.61-19.26c2.27-.04 3.88 1.47 3.88 3.62 0 2.14-1.47 3.65-3.51 3.65h-4.39v-7.27Zm12.26 19.26h4.59v-7.77h4.49c4.72 0 8.07-3.29 8.07-7.87 0-4.59-3.48-7.88-8.44-7.84l-4.66.03h-4.05Zm8.61-19.26c2.28-.04 3.88 1.47 3.88 3.62 0 2.14-1.47 3.65-3.51 3.65h-4.39v-7.27Zm20.9 19.26h4.59v-8.31h3.52l4.79 8.31h5.19l-5.43-9.11c2.72-1.21 4.49-3.69 4.49-6.77 0-4.45-3.48-7.64-8.44-7.6l-4.66.03h-4.05Zm8.51-19.26c2.28 0 3.89 1.37 3.89 3.38 0 1.98-1.61 3.38-3.66 3.38h-4.15v-6.76Zm13.77 19.26h14.97v-4.19h-10.38v-5.66h8.84v-4.09h-8.84v-5.32h10.25v-4.19h-14.84Zm20.4 0h4.59v-7.77h4.49c4.72 0 8.07-3.29 8.07-7.87 0-4.59-3.48-7.88-8.44-7.84l-4.66.03h-4.05Zm8.61-19.26c2.28-.04 3.89 1.47 3.89 3.62 0 2.14-1.48 3.65-3.52 3.65h-4.39v-7.27Zm22.98 19.66c6.97 0 11.93-5.02 11.93-12.09 0-7.1-4.96-12.13-12.03-12.13-7.03 0-11.99 4.99-11.99 12.13 0 7.07 4.99 12.09 12.09 12.09m0-4.19c-4.35 0-7.4-3.28-7.4-7.9 0-4.66 3.01-7.94 7.3-7.94 4.32 0 7.34 3.28 7.34 7.94 0 4.62-2.98 7.9-7.24 7.9m24.19 4.19c5.46 0 8.54-2.75 8.54-6.93 0-3.12-2.31-5.9-6.36-6.9l-3.09-.77c-1.74-.44-2.81-1.24-2.81-2.72 0-1.84 1.34-2.95 3.58-2.95 2.18 0 3.66 1.24 4.19 2.75l4.46-1.37c-1.24-3.29-4.02-5.36-8.51-5.36-5.36 0-8.41 2.61-8.41 7.03 0 3.49 2.34 5.7 5.79 6.57l3.05.8c2.08.51 3.32 1.54 3.32 3.02 0 1.71-1.64 2.88-4.02 2.85-2.24-.04-3.75-1.28-4.32-2.82l-4.49 1.34c.67 2.88 4.32 5.46 9.08 5.46m13.13-.4h4.59V36.75h-4.59Zm15.31 0h4.59V40.94h7v-4.19h-18.63v4.19h7.04Zm26 .4c6.96 0 11.92-5.02 11.92-12.09 0-7.1-4.96-12.13-12.03-12.13-7.03 0-11.99 4.99-11.99 12.13 0 7.07 4.99 12.09 12.1 12.09m0-4.19c-4.36 0-7.41-3.28-7.41-7.9 0-4.66 3.02-7.94 7.3-7.94 4.33 0 7.34 3.28 7.34 7.94 0 4.62-2.98 7.9-7.23 7.9m16.31 3.79h4.59v-8.31h3.52l4.79 8.31h5.19l-5.43-9.11c2.72-1.21 4.49-3.69 4.49-6.77 0-4.45-3.48-7.64-8.44-7.6l-4.66.03h-4.05Zm8.51-19.26c2.28 0 3.88 1.37 3.88 3.38 0 1.98-1.6 3.38-3.65 3.38h-4.15v-6.76Zm19.76 19.26h4.59v-9.92l8.31-13.53h-5.22l-5.4 9.01-5.36-9.01h-5.22l8.3 13.57Zm29.95 0h4.59V40.94h7v-4.19h-18.62v4.19h7.03Zm26 .4c6.97 0 11.92-5.02 11.92-12.09 0-7.1-4.95-12.13-12.02-12.13-7.04 0-11.99 4.99-11.99 12.13 0 7.07 4.99 12.09 12.09 12.09m0-4.19c-4.36 0-7.4-3.28-7.4-7.9 0-4.66 3.01-7.94 7.3-7.94 4.32 0 7.33 3.28 7.33 7.94 0 4.62-2.98 7.9-7.23 7.9"/><g style="transform:translate(142px,0)"><rect width="137" height="64" x="344" y="16" fill="#F2F4F9" rx="32"/><path fill="#18BCF2" d="M394.419 37.047V60.5h-4.297V46.797L384.716 60.5h-4.157l-5.343-13.594V60.5h-4.188V37.047h4.188l7.422 18.36 7.484-18.36zm9.365 0 5.344 9.89 5.344-9.89h4.766l-7.969 14.14V60.5h-4.391v-9.312l-8.031-14.141zM457 60c0 1.65-1.35 3-3 3h-24c-1.65 0-3-1.35-3-3v-9c0-1.65.95-3.95 2.12-5.12l10.76-10.76a3 3 0 0 1 4.24 0l10.76 10.76c1.17 1.17 2.12 3.47 2.12 5.12z"/><path fill="#F2F4F9" stroke="#F2F4F9" d="M442 45.5a2 2 0 1 0 0-4 2 2 0 0 0 0 4Z"/><path fill="#F2F4F9" stroke="#F2F4F9" stroke-miterlimit="10" d="M449.5 53.5a2 2 0 1 0 0-4 2 2 0 0 0 0 4ZM434.5 57.5a2 2 0 1 0 0-4 2 2 0 0 0 0 4Z"/><path fill="none" stroke="#F2F4F9" stroke-miterlimit="10" stroke-width="2.25" d="M442 43.48V63l-7.5-7.5M449.5 51.46l-7.41 7.41"/></g></svg>
|
||||
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 131 KiB |
@@ -287,6 +287,10 @@ export const docsNavigation = [
|
||||
href: '/manage/reverse-proxy/authentication',
|
||||
},
|
||||
{ title: 'Access Logs', href: '/manage/reverse-proxy/access-logs' },
|
||||
{
|
||||
title: 'Service Configuration',
|
||||
href: '/manage/reverse-proxy/service-configuration',
|
||||
},
|
||||
{
|
||||
title: 'Expose from CLI',
|
||||
href: '/manage/reverse-proxy/expose-from-cli',
|
||||
|
||||
@@ -12,7 +12,7 @@ NetBird logs every request that passes through your reverse proxy services. Acce
|
||||
Access logs are available in the NetBird dashboard under **Activity** > **Proxy Events**. This view displays a table of all HTTP requests that have passed through your reverse proxy services, with filters to narrow down results by time range, status, or other fields.
|
||||
|
||||
<p>
|
||||
<img src="/docs-static/img/manage/reverse-proxy/access-logs-table.png" alt="Proxy Events table showing reverse proxy access log entries" className="imagewrapper"/>
|
||||
<img src="/docs-static/img/manage/reverse-proxy/access-logs/access-logs-table.png" alt="Proxy Events table showing reverse proxy access log entries" className="imagewrapper"/>
|
||||
</p>
|
||||
|
||||
You can also retrieve access logs programmatically using the API:
|
||||
|
||||
@@ -8,7 +8,7 @@ export const description =
|
||||
NetBird Reverse Proxy supports multiple authentication methods to control who can access your exposed services. You can enable one or more methods on each service, or leave a service completely public. Authentication is configured per service in the **Authentication** tab when creating or editing a service.
|
||||
|
||||
<p>
|
||||
<img src="/docs-static/img/manage/reverse-proxy/reverse-proxy-add-service-auth.png" alt="Authentication tab showing all available authentication methods" className="imagewrapper"/>
|
||||
<img src="/docs-static/img/manage/reverse-proxy/authentication/reverse-proxy-add-service-auth.png" alt="Authentication tab showing all available authentication methods" className="imagewrapper"/>
|
||||
</p>
|
||||
|
||||
## Authentication methods
|
||||
@@ -22,7 +22,7 @@ SSO authentication requires users to authenticate through your identity provider
|
||||
You can optionally restrict access to specific **distribution groups** from your IdP. When groups are configured, only users who belong to at least one of the selected groups are allowed through after authenticating.
|
||||
|
||||
<p>
|
||||
<img src="/docs-static/img/manage/reverse-proxy/auth-sso-modal.png" alt="SSO configuration modal with group selection" className="imagewrapper"/>
|
||||
<img src="/docs-static/img/manage/reverse-proxy/authentication/auth-sso-modal.png" alt="SSO configuration modal with group selection" className="imagewrapper"/>
|
||||
</p>
|
||||
|
||||
**Key details:**
|
||||
@@ -43,7 +43,7 @@ You can optionally restrict access to specific **distribution groups** from your
|
||||
Password authentication protects a service with a shared password that you define. When a user visits the service URL, they are prompted to enter the password before they can proceed. Passwords are securely hashed using **Argon2id** on the backend - the plaintext password is never stored.
|
||||
|
||||
<p>
|
||||
<img src="/docs-static/img/manage/reverse-proxy/auth-password-modal.png" alt="Password configuration modal" className="imagewrapper"/>
|
||||
<img src="/docs-static/img/manage/reverse-proxy/authentication/auth-password-modal.png" alt="Password configuration modal" className="imagewrapper"/>
|
||||
</p>
|
||||
|
||||
**Key details:**
|
||||
@@ -60,7 +60,7 @@ Password authentication protects a service with a shared password that you defin
|
||||
PIN code authentication works similarly to password authentication but is limited to numeric input. When a user visits the service URL, they are prompted to enter the PIN code. PINs are securely hashed using **Argon2id** on the backend, just like passwords.
|
||||
|
||||
<p>
|
||||
<img src="/docs-static/img/manage/reverse-proxy/auth-pin-modal.png" alt="PIN Code configuration modal" className="imagewrapper"/>
|
||||
<img src="/docs-static/img/manage/reverse-proxy/authentication/auth-pin-modal.png" alt="PIN Code configuration modal" className="imagewrapper"/>
|
||||
</p>
|
||||
|
||||
**Key details:**
|
||||
@@ -81,7 +81,7 @@ Services can also be configured without any authentication. When no authenticati
|
||||
</Note>
|
||||
|
||||
<p>
|
||||
<img src="/docs-static/img/manage/reverse-proxy/auth-no-auth-warning.png" alt="Warning dialog displayed when saving a service without authentication" className="imagewrapper"/>
|
||||
<img src="/docs-static/img/manage/reverse-proxy/authentication/auth-no-auth-warning.png" alt="Warning dialog displayed when saving a service without authentication" className="imagewrapper"/>
|
||||
</p>
|
||||
|
||||
**Best for:** Public-facing websites, APIs that handle their own authentication internally, or services that are intentionally open to the internet.
|
||||
|
||||
@@ -58,7 +58,7 @@ Follow these steps to add a custom domain to your account:
|
||||
5. Click **Save**.
|
||||
|
||||
<p>
|
||||
<img src="/docs-static/img/manage/reverse-proxy/custom-domains-add.png" alt="Add Domain modal showing domain name and proxy cluster fields" className="imagewrapper"/>
|
||||
<img src="/docs-static/img/manage/reverse-proxy/custom-domains/custom-domains-add.png" alt="Add Domain modal showing domain name and proxy cluster fields" className="imagewrapper"/>
|
||||
</p>
|
||||
|
||||
After saving, the domain appears in your list with a **Pending Verification** status. You must complete CNAME verification before you can use the domain with a service.
|
||||
@@ -93,13 +93,13 @@ The exact target value depends on the proxy cluster you selected when adding the
|
||||
After creating the DNS record, return to the **Reverse Proxy** > **Custom Domains** page and click **Verify Domain** next to the domain.
|
||||
|
||||
<p>
|
||||
<img src="/docs-static/img/manage/reverse-proxy/custom-domains-verification.png" alt="Domain verification modal showing CNAME record details" className="imagewrapper-big"/>
|
||||
<img src="/docs-static/img/manage/reverse-proxy/custom-domains/custom-domains-verification.png" alt="Domain verification modal showing CNAME record details" className="imagewrapper-big"/>
|
||||
</p>
|
||||
|
||||
Confirm that the dialog reflects CNAME record you added to your domain provider and click **Start Verification**.
|
||||
|
||||
<p>
|
||||
<img src="/docs-static/img/manage/reverse-proxy/custom-domains-start-verification.png" alt="Start Verification Dialog" className="imagewrapper"/>
|
||||
<img src="/docs-static/img/manage/reverse-proxy/custom-domains/custom-domains-start-verification.png" alt="Start Verification Dialog" className="imagewrapper"/>
|
||||
</p>
|
||||
|
||||
NetBird performs a CNAME lookup on `*.<your-domain>` and verifies that it resolves to a known proxy cluster. Once verification succeeds, the domain status changes to **Active** and it becomes available in the domain selector when creating or editing services.
|
||||
|
||||
@@ -225,6 +225,10 @@ Switch to the **Settings** tab to adjust advanced proxy behavior.
|
||||
- **Pass Host Header** - when enabled, the original `Host` header from the client request is forwarded to the backend service instead of the target's hostname. This is useful when the backend application needs to know the public domain it is being accessed through.
|
||||
- **Rewrite Redirects** - when enabled, `Location` headers in backend responses (used for HTTP redirects) are rewritten to use the public domain. This prevents users from being redirected to internal URLs that they cannot reach.
|
||||
|
||||
<Warning>
|
||||
**Backend configuration may be required.** If your backend service has a "trusted proxies", "known hosts", or "allowed networks" setting (common in Jellyfin, Home Assistant, Plex, Nextcloud, and others), you must configure it to trust the NetBird IP range. Without this, the backend may reject proxied requests or fail to read the real client IP. See [Backend Service Configuration](/manage/reverse-proxy/service-configuration) for details and per-service examples.
|
||||
</Warning>
|
||||
|
||||
### Step 5: Create the service
|
||||
|
||||
Click **Add Service** to create the reverse proxy service. NetBird will begin provisioning the TLS certificate and establishing the tunnel. Monitor the service status on the services list page until it shows `active`.
|
||||
|
||||
119
src/pages/manage/reverse-proxy/service-configuration.mdx
Normal file
@@ -0,0 +1,119 @@
|
||||
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.
|
||||
|
||||
[](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.
|
||||
|
||||
## 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
|
||||