From e52301bbf4cb0367c9e631ef9c6c590c19da3a5a Mon Sep 17 00:00:00 2001
From: Jack Carter <128555021+SunsetDrifter@users.noreply.github.com>
Date: Wed, 13 May 2026 14:06:54 +0200
Subject: [PATCH 01/16] docs: add Masquerade configuration page
Documents persistent return-route setup on the destination host when
masquerade is disabled on a routing peer. Covers Netplan, systemd-networkd,
NetworkManager, ifupdown, and RHEL legacy network-scripts, plus verification
and a security note. Resolves the previously dangling "Related" tile in
how-routing-peers-work.mdx.
---
src/components/NavigationDocs.jsx | 4 +
.../networks/how-routing-peers-work.mdx | 2 +-
src/pages/manage/networks/masquerade.mdx | 158 ++++++++++++++++++
3 files changed, 163 insertions(+), 1 deletion(-)
create mode 100644 src/pages/manage/networks/masquerade.mdx
diff --git a/src/components/NavigationDocs.jsx b/src/components/NavigationDocs.jsx
index 05226995b..32873de11 100644
--- a/src/components/NavigationDocs.jsx
+++ b/src/components/NavigationDocs.jsx
@@ -191,6 +191,10 @@ export const docsNavigation = [
title: 'How Routing Peers Work',
href: '/manage/networks/how-routing-peers-work',
},
+ {
+ title: 'Masquerade',
+ href: '/manage/networks/masquerade',
+ },
{
title: 'Use Cases',
isOpen: false,
diff --git a/src/pages/manage/networks/how-routing-peers-work.mdx b/src/pages/manage/networks/how-routing-peers-work.mdx
index 67ad06148..8bdd48659 100644
--- a/src/pages/manage/networks/how-routing-peers-work.mdx
+++ b/src/pages/manage/networks/how-routing-peers-work.mdx
@@ -225,7 +225,7 @@ Specifics:
description: 'Use ACL Groups to restrict who reaches a routed network',
},
{
- href: '/manage/network-routes/advanced-configuration',
+ href: '/manage/networks/masquerade',
name: 'Masquerade',
description: 'When to enable or disable source IP rewriting on a route',
},
diff --git a/src/pages/manage/networks/masquerade.mdx b/src/pages/manage/networks/masquerade.mdx
new file mode 100644
index 000000000..01f475184
--- /dev/null
+++ b/src/pages/manage/networks/masquerade.mdx
@@ -0,0 +1,158 @@
+import { Note, Warning } from '@/components/mdx'
+import { Tiles } from '@/components/Tiles'
+
+# Masquerade
+
+Masquerade is on by default. The routing peer SNATs forwarded traffic to its own LAN-side IP, so the destination network does not need any awareness of NetBird. Turn it off when you need:
+
+- Source IP visibility for auditing, compliance, or application logic.
+- The destination network's existing firewalls to filter NetBird peers by their overlay IP.
+
+## What changes when masquerade is off
+
+- The original NetBird overlay IP is preserved end-to-end.
+- The destination network must have a return route for the NetBird CIDR (default `100.64.0.0/10`) pointing at the routing peer's LAN IP.
+- High availability stops working — return traffic must flow back through one specific routing peer, so the destination network has no way to follow a failover. See [How Routing Peers Work — Masquerade](/manage/networks/how-routing-peers-work#masquerade).
+
+
+Masquerade can only be turned off on Linux routing peers.
+
+
+## Inputs to substitute
+
+The examples below use placeholders. Swap in:
+
+- `100.64.0.0/10` — default NetBird CIDR. Substitute your account's range if it's narrower.
+- `` — the routing peer's IP on the destination subnet.
+- `` — the LAN interface on the destination host. Use `ip -br addr` to identify it.
+
+## Test the route before making it persistent
+
+Add the route temporarily on the destination host:
+
+```bash
+sudo ip route add 100.64.0.0/10 via
+```
+
+Verify reachability from a NetBird peer, then remove the test route before committing the persistent version:
+
+```bash
+sudo ip route del 100.64.0.0/10
+```
+
+## Persistent configuration
+
+Pick the section matching how the destination host manages its network.
+
+### Netplan (Ubuntu 18.04+)
+
+Edit the existing yaml in `/etc/netplan/` (e.g. `01-netcfg.yaml` or `50-cloud-init.yaml`):
+
+```yaml
+network:
+ version: 2
+ ethernets:
+ :
+ routes:
+ - to: 100.64.0.0/10
+ via:
+```
+
+Apply:
+
+```bash
+sudo netplan apply
+```
+
+
+Recent netplan versions require `0600` permissions on yaml files under `/etc/netplan/`. Set with `sudo chmod 0600 /etc/netplan/*.yaml` if `netplan apply` warns.
+
+
+### systemd-networkd
+
+Either append to the relevant `.network` file in `/etc/systemd/network/`, or drop a snippet into `/etc/systemd/network/.network.d/100-netbird.conf`:
+
+```ini
+[Route]
+Destination=100.64.0.0/10
+Gateway=
+```
+
+Apply:
+
+```bash
+sudo networkctl reload
+```
+
+### NetworkManager (RHEL, Rocky, Alma, Fedora, Ubuntu desktop)
+
+Find the connection name:
+
+```bash
+nmcli connection show
+```
+
+Add the route to that connection profile:
+
+```bash
+sudo nmcli connection modify "" +ipv4.routes "100.64.0.0/10 "
+sudo nmcli connection up ""
+```
+
+The route is stored in `/etc/NetworkManager/system-connections/.nmconnection` and survives reboots.
+
+### ifupdown (legacy Debian, older Ubuntu)
+
+In `/etc/network/interfaces`, under the interface stanza:
+
+```
+post-up ip route add 100.64.0.0/10 via
+pre-down ip route del 100.64.0.0/10 via
+```
+
+### RHEL legacy network-scripts
+
+For RHEL 7 hosts still on the `network` service (rare on modern systems), create or edit `/etc/sysconfig/network-scripts/route-`:
+
+```
+100.64.0.0/10 via
+```
+
+## Verify after reboot
+
+```bash
+ip route show 100.64.0.0/10
+```
+
+Expect output like:
+
+```
+100.64.0.0/10 via 192.168.1.50 dev eth0
+```
+
+## Security considerations
+
+
+The return route exposes the destination subnet to the full `100.64.0.0/10` overlay range. The OS-level route does no filtering on its own — source IP transparency is the whole reason masquerade is off, so tighten access at the NetBird policy layer with source groups, ports, and posture checks. If only a subset of the destination subnet should reach NetBird peers, add host-level firewall rules (iptables, nftables, firewalld) alongside the route.
+
+
+
From 50cc898885fd4252791084d1a0d4f7c08cd746b5 Mon Sep 17 00:00:00 2001
From: Jack Carter <128555021+SunsetDrifter@users.noreply.github.com>
Date: Wed, 13 May 2026 15:06:09 +0200
Subject: [PATCH 02/16] docs: clarify masquerade page and trim persistent
recipes
- Netplan: show as a fragment with addresses/default route context so readers
don't paste it as a standalone file
- systemd-networkd: note the drop-in needs a matching .network file and
point at networkctl status to find it
- Test section: add ping/curl reachability examples
- Verify section: call out that proto/onlink/metric fields are normal
- Remove NetworkManager, ifupdown, and RHEL legacy sections
---
src/pages/manage/networks/masquerade.mdx | 47 ++++++------------------
1 file changed, 11 insertions(+), 36 deletions(-)
diff --git a/src/pages/manage/networks/masquerade.mdx b/src/pages/manage/networks/masquerade.mdx
index 01f475184..5c162e7eb 100644
--- a/src/pages/manage/networks/masquerade.mdx
+++ b/src/pages/manage/networks/masquerade.mdx
@@ -34,7 +34,7 @@ Add the route temporarily on the destination host:
sudo ip route add 100.64.0.0/10 via
```
-Verify reachability from a NetBird peer, then remove the test route before committing the persistent version:
+From a NetBird peer, confirm reachability — for example `ping ` or `curl http://:`. Then remove the test route before committing the persistent version:
```bash
sudo ip route del 100.64.0.0/10
@@ -46,15 +46,18 @@ Pick the section matching how the destination host manages its network.
### Netplan (Ubuntu 18.04+)
-Edit the existing yaml in `/etc/netplan/` (e.g. `01-netcfg.yaml` or `50-cloud-init.yaml`):
+Edit the existing yaml in `/etc/netplan/` (e.g. `01-netcfg.yaml` or `50-cloud-init.yaml`) and add a `routes:` entry to the interface stanza. Keep the existing `addresses:` / `dhcp4:` lines — this is a fragment, not a standalone file:
```yaml
network:
version: 2
ethernets:
:
+ addresses: [192.168.1.50/24] # existing
routes:
- - to: 100.64.0.0/10
+ - to: default # existing
+ via: 192.168.1.1
+ - to: 100.64.0.0/10 # add this
via:
```
@@ -84,39 +87,9 @@ Apply:
sudo networkctl reload
```
-### NetworkManager (RHEL, Rocky, Alma, Fedora, Ubuntu desktop)
-
-Find the connection name:
-
-```bash
-nmcli connection show
-```
-
-Add the route to that connection profile:
-
-```bash
-sudo nmcli connection modify "" +ipv4.routes "100.64.0.0/10 "
-sudo nmcli connection up ""
-```
-
-The route is stored in `/etc/NetworkManager/system-connections/.nmconnection` and survives reboots.
-
-### ifupdown (legacy Debian, older Ubuntu)
-
-In `/etc/network/interfaces`, under the interface stanza:
-
-```
-post-up ip route add 100.64.0.0/10 via
-pre-down ip route del 100.64.0.0/10 via
-```
-
-### RHEL legacy network-scripts
-
-For RHEL 7 hosts still on the `network` service (rare on modern systems), create or edit `/etc/sysconfig/network-scripts/route-`:
-
-```
-100.64.0.0/10 via
-```
+
+The drop-in path only takes effect when a `.network` file already matches the interface. Run `networkctl status ` and check the **Network File** line to confirm which one — on netplan-managed hosts it's generated under `/run/systemd/network/`.
+
## Verify after reboot
@@ -130,6 +103,8 @@ Expect output like:
100.64.0.0/10 via 192.168.1.50 dev eth0
```
+Trailing fields such as `proto static`, `onlink`, or `metric 100` may appear depending on the network manager — those are normal.
+
## Security considerations
From 560538e45271e48b3147ebadee47e4a325bc149c Mon Sep 17 00:00:00 2001
From: Jack Carter <128555021+SunsetDrifter@users.noreply.github.com>
Date: Wed, 13 May 2026 15:10:59 +0200
Subject: [PATCH 03/16] docs: clarify netplan section when /etc/netplan is
empty
Lead with the common case (cloud-init / installer yaml already exists),
and call out the placeholders in the example. Add a fallback path for
the rare case where /etc/netplan/ is empty.
---
src/pages/manage/networks/masquerade.mdx | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/pages/manage/networks/masquerade.mdx b/src/pages/manage/networks/masquerade.mdx
index 5c162e7eb..fca817dde 100644
--- a/src/pages/manage/networks/masquerade.mdx
+++ b/src/pages/manage/networks/masquerade.mdx
@@ -46,7 +46,7 @@ Pick the section matching how the destination host manages its network.
### Netplan (Ubuntu 18.04+)
-Edit the existing yaml in `/etc/netplan/` (e.g. `01-netcfg.yaml` or `50-cloud-init.yaml`) and add a `routes:` entry to the interface stanza. Keep the existing `addresses:` / `dhcp4:` lines — this is a fragment, not a standalone file:
+On Ubuntu Server, `/etc/netplan/` usually already has a yaml from cloud-init (`50-cloud-init.yaml`) or the installer (`00-installer-config.yaml`). Add a `routes:` entry to the interface stanza. The `addresses:` and default-route values shown below are placeholders for whatever is already in your file — not values to copy as-is:
```yaml
network:
@@ -61,6 +61,8 @@ network:
via:
```
+If `/etc/netplan/` is empty (uncommon, but possible on minimal installs or when netplan was just `apt install`ed), create `/etc/netplan/01-netbird.yaml` with the full stanza, substituting real values for `addresses:` and the default gateway.
+
Apply:
```bash
From 3f30a810a463a329fcb23cf8fc8f321334eb419a Mon Sep 17 00:00:00 2001
From: Jack Carter <128555021+SunsetDrifter@users.noreply.github.com>
Date: Wed, 13 May 2026 15:11:41 +0200
Subject: [PATCH 04/16] docs: comment placeholder in netplan example
---
src/pages/manage/networks/masquerade.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pages/manage/networks/masquerade.mdx b/src/pages/manage/networks/masquerade.mdx
index fca817dde..68a4d0b37 100644
--- a/src/pages/manage/networks/masquerade.mdx
+++ b/src/pages/manage/networks/masquerade.mdx
@@ -52,7 +52,7 @@ On Ubuntu Server, `/etc/netplan/` usually already has a yaml from cloud-init (`5
network:
version: 2
ethernets:
- :
+ : # your interface, e.g. eth0
addresses: [192.168.1.50/24] # existing
routes:
- to: default # existing
From 5f02df4cc1094d672fb39727bb020cede936f0ee Mon Sep 17 00:00:00 2001
From: Jack Carter <128555021+SunsetDrifter@users.noreply.github.com>
Date: Wed, 13 May 2026 15:13:24 +0200
Subject: [PATCH 05/16] docs: clarify is the destination's LAN
interface
---
src/pages/manage/networks/masquerade.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pages/manage/networks/masquerade.mdx b/src/pages/manage/networks/masquerade.mdx
index 68a4d0b37..39aa45474 100644
--- a/src/pages/manage/networks/masquerade.mdx
+++ b/src/pages/manage/networks/masquerade.mdx
@@ -52,7 +52,7 @@ On Ubuntu Server, `/etc/netplan/` usually already has a yaml from cloud-init (`5
network:
version: 2
ethernets:
- : # your interface, e.g. eth0
+ : # destination's LAN interface, e.g. eth0
addresses: [192.168.1.50/24] # existing
routes:
- to: default # existing
From 8755e136dd327f0745826d863c43064f23af8496 Mon Sep 17 00:00:00 2001
From: Jack Carter <128555021+SunsetDrifter@users.noreply.github.com>
Date: Wed, 13 May 2026 15:17:53 +0200
Subject: [PATCH 06/16] docs: comment placeholder in netplan
example
---
src/pages/manage/networks/masquerade.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pages/manage/networks/masquerade.mdx b/src/pages/manage/networks/masquerade.mdx
index 39aa45474..f51680992 100644
--- a/src/pages/manage/networks/masquerade.mdx
+++ b/src/pages/manage/networks/masquerade.mdx
@@ -58,7 +58,7 @@ network:
- to: default # existing
via: 192.168.1.1
- to: 100.64.0.0/10 # add this
- via:
+ via: # routing peer's IP on this subnet
```
If `/etc/netplan/` is empty (uncommon, but possible on minimal installs or when netplan was just `apt install`ed), create `/etc/netplan/01-netbird.yaml` with the full stanza, substituting real values for `addresses:` and the default gateway.
From f0f4867d0ca07d505fdac8feea433dc0100a4740 Mon Sep 17 00:00:00 2001
From: Jack Carter <128555021+SunsetDrifter@users.noreply.github.com>
Date: Wed, 13 May 2026 15:18:40 +0200
Subject: [PATCH 07/16] docs: tighten comment to 'local IP on
this subnet'
---
src/pages/manage/networks/masquerade.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pages/manage/networks/masquerade.mdx b/src/pages/manage/networks/masquerade.mdx
index f51680992..cfe73e143 100644
--- a/src/pages/manage/networks/masquerade.mdx
+++ b/src/pages/manage/networks/masquerade.mdx
@@ -58,7 +58,7 @@ network:
- to: default # existing
via: 192.168.1.1
- to: 100.64.0.0/10 # add this
- via: # routing peer's IP on this subnet
+ via: # routing peer's local IP on this subnet
```
If `/etc/netplan/` is empty (uncommon, but possible on minimal installs or when netplan was just `apt install`ed), create `/etc/netplan/01-netbird.yaml` with the full stanza, substituting real values for `addresses:` and the default gateway.
From f536a3b70b668f235f0d4ed53cb6be2d96f780cc Mon Sep 17 00:00:00 2001
From: Jack Carter <128555021+SunsetDrifter@users.noreply.github.com>
Date: Wed, 13 May 2026 15:23:35 +0200
Subject: [PATCH 08/16] docs: make 'pick one' explicit for the
persistent-config methods
Replace the weak one-liner with a bold "pick one" callout and a
two-bullet decision criterion (ls /etc/netplan/) so readers don't
mistake the two H3 sections for sequential steps.
---
src/pages/manage/networks/masquerade.mdx | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/pages/manage/networks/masquerade.mdx b/src/pages/manage/networks/masquerade.mdx
index cfe73e143..2110d3467 100644
--- a/src/pages/manage/networks/masquerade.mdx
+++ b/src/pages/manage/networks/masquerade.mdx
@@ -42,7 +42,10 @@ sudo ip route del 100.64.0.0/10
## Persistent configuration
-Pick the section matching how the destination host manages its network.
+Pick **one** of the methods below — your host uses one network manager, not both:
+
+- **Netplan** if `/etc/netplan/` already has yaml files (most Ubuntu hosts).
+- **systemd-networkd** otherwise (Debian Server, minimal installs, or hosts using systemd-networkd directly without a netplan frontend).
### Netplan (Ubuntu 18.04+)
From c86c69c182c1b50de28023da7c739a36ddb880cf Mon Sep 17 00:00:00 2001
From: Jack Carter <128555021+SunsetDrifter@users.noreply.github.com>
Date: Wed, 13 May 2026 15:29:27 +0200
Subject: [PATCH 09/16] docs: add 'Find your account's NetBird range' to the
masquerade page
Mirror the section already on the site-to-vpn page so readers learn to
use their account's /16 block rather than pinning the whole /10. Same
prose and netbird status recipe; trailing line adapted to reference
100.64.0.0/10 (the placeholder used elsewhere on this page).
---
src/pages/manage/networks/masquerade.mdx | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/src/pages/manage/networks/masquerade.mdx b/src/pages/manage/networks/masquerade.mdx
index 2110d3467..ddc1f7729 100644
--- a/src/pages/manage/networks/masquerade.mdx
+++ b/src/pages/manage/networks/masquerade.mdx
@@ -26,6 +26,20 @@ The examples below use placeholders. Swap in:
- `` — the routing peer's IP on the destination subnet.
- `` — the LAN interface on the destination host. Use `ip -br addr` to identify it.
+## Find your account's NetBird range
+
+NetBird assigns each account a single `/16` block from inside the `100.64.0.0/10` CGNAT range (one of 64 possible blocks such as `100.64.0.0/16`, `100.121.0.0/16`, `100.127.0.0/16`, …). The block is chosen randomly per account and can be customised. Use that `/16` for the return route below — not the whole `/10` — so you don't funnel unrelated CGNAT ranges through your routing peer.
+
+Read it off any enrolled peer:
+
+```bash
+$ netbird status | grep "NetBird IP"
+NetBird IP: 100.121.195.4/16
+# → this account's block is 100.121.0.0/16
+```
+
+Substitute that `/16` for `100.64.0.0/10` in every example below.
+
## Test the route before making it persistent
Add the route temporarily on the destination host:
From 1328e82e989dd1c8a846bb2d519dc8cbfe34e6f2 Mon Sep 17 00:00:00 2001
From: Jack Carter <128555021+SunsetDrifter@users.noreply.github.com>
Date: Wed, 13 May 2026 15:31:52 +0200
Subject: [PATCH 10/16] docs: remove 'Related' Tiles block from masquerade page
---
src/pages/manage/networks/masquerade.mdx | 22 ----------------------
1 file changed, 22 deletions(-)
diff --git a/src/pages/manage/networks/masquerade.mdx b/src/pages/manage/networks/masquerade.mdx
index ddc1f7729..d6b2f3a0d 100644
--- a/src/pages/manage/networks/masquerade.mdx
+++ b/src/pages/manage/networks/masquerade.mdx
@@ -1,5 +1,4 @@
import { Note, Warning } from '@/components/mdx'
-import { Tiles } from '@/components/Tiles'
# Masquerade
@@ -129,24 +128,3 @@ Trailing fields such as `proto static`, `onlink`, or `metric 100` may appear dep
The return route exposes the destination subnet to the full `100.64.0.0/10` overlay range. The OS-level route does no filtering on its own — source IP transparency is the whole reason masquerade is off, so tighten access at the NetBird policy layer with source groups, ports, and posture checks. If only a subset of the destination subnet should reach NetBird peers, add host-level firewall rules (iptables, nftables, firewalld) alongside the route.
-
-
From 9fd574adbc414436b63dca5c3a7d0d76d25d0172 Mon Sep 17 00:00:00 2001
From: Jack Carter <128555021+SunsetDrifter@users.noreply.github.com>
Date: Wed, 13 May 2026 15:32:37 +0200
Subject: [PATCH 11/16] docs: align security warning with the recommended /16
range
---
src/pages/manage/networks/masquerade.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pages/manage/networks/masquerade.mdx b/src/pages/manage/networks/masquerade.mdx
index d6b2f3a0d..c8fc52395 100644
--- a/src/pages/manage/networks/masquerade.mdx
+++ b/src/pages/manage/networks/masquerade.mdx
@@ -126,5 +126,5 @@ Trailing fields such as `proto static`, `onlink`, or `metric 100` may appear dep
## Security considerations
-The return route exposes the destination subnet to the full `100.64.0.0/10` overlay range. The OS-level route does no filtering on its own — source IP transparency is the whole reason masquerade is off, so tighten access at the NetBird policy layer with source groups, ports, and posture checks. If only a subset of the destination subnet should reach NetBird peers, add host-level firewall rules (iptables, nftables, firewalld) alongside the route.
+The return route exposes the destination subnet to whatever NetBird range you configured — your account's `/16` if you narrowed it (recommended), otherwise the full `100.64.0.0/10`. The OS-level route does no filtering on its own — source IP transparency is the whole reason masquerade is off, so tighten access at the NetBird policy layer with source groups, ports, and posture checks. If only a subset of the destination subnet should reach NetBird peers, add host-level firewall rules (iptables, nftables, firewalld) alongside the route.
From 9a44ceabd3b686d7e11acda424a3e4ea54d5a547 Mon Sep 17 00:00:00 2001
From: Jack Carter <128555021+SunsetDrifter@users.noreply.github.com>
Date: Wed, 13 May 2026 15:37:47 +0200
Subject: [PATCH 12/16] docs: restore cross-link from advanced-configuration to
masquerade
---
src/pages/manage/network-routes/advanced-configuration.mdx | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/pages/manage/network-routes/advanced-configuration.mdx b/src/pages/manage/network-routes/advanced-configuration.mdx
index b9d27721d..04dee9edf 100644
--- a/src/pages/manage/network-routes/advanced-configuration.mdx
+++ b/src/pages/manage/network-routes/advanced-configuration.mdx
@@ -20,6 +20,8 @@ For the basics — masquerade behavior, ACL Groups, HA — see [Network Routes C
- Required if your compliance regime needs source-IP visibility on the remote network
- Requires a return route on the remote network's infrastructure back to the NetBird CIDR
+See [Masquerade](/manage/networks/masquerade) for persistent return-route configuration on the destination host.
+
Without masquerade, traffic from unknown source IPs is rejected by NetBird's policy engine. You cannot use ACL Groups or Network Resources with masquerade disabled.
From 56d85933c97940c971c04dcea48f98bd59d14c34 Mon Sep 17 00:00:00 2001
From: Jack Carter <128555021+SunsetDrifter@users.noreply.github.com>
Date: Wed, 13 May 2026 15:43:47 +0200
Subject: [PATCH 13/16] docs: drop ping from the test-route example
ping would fail for ACL reasons (not routing reasons) on policies
scoped to specific TCP ports, misdirecting troubleshooting. Use curl or
nc against an allowed port instead.
---
src/pages/manage/networks/masquerade.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pages/manage/networks/masquerade.mdx b/src/pages/manage/networks/masquerade.mdx
index c8fc52395..19bb71b0f 100644
--- a/src/pages/manage/networks/masquerade.mdx
+++ b/src/pages/manage/networks/masquerade.mdx
@@ -47,7 +47,7 @@ Add the route temporarily on the destination host:
sudo ip route add 100.64.0.0/10 via
```
-From a NetBird peer, confirm reachability — for example `ping ` or `curl http://:`. Then remove the test route before committing the persistent version:
+From a NetBird peer, confirm reachability with a protocol/port your NetBird policy allows — for example `curl http://:`, or `nc -zv ` for a non-HTTP service. Then remove the test route before committing the persistent version:
```bash
sudo ip route del 100.64.0.0/10
From 805da3f441bd588dc38cdb0d1803db84ad52c635 Mon Sep 17 00:00:00 2001
From: Jack Carter <128555021+SunsetDrifter@users.noreply.github.com>
Date: Tue, 19 May 2026 14:56:58 +0200
Subject: [PATCH 14/16] docs: apply review findings to masquerade page and
legacy warning
masquerade.mdx
- add "Disable masquerade on the routing peer" section (dashboard +
API path), so the page actually documents the toggle, not just
the prerequisite
- "What changes when masquerade is off": say the route lives on the
destination host (or its gateway for multi-hop)
- forward-ref "Find your account's NetBird range" from the inputs
list to remove the substitute-then-rewind loop
- ip route del: include via so the test takedown is
unambiguous
- netplan prose: spell out that you append to the existing routes:
list, not add a second routes: key (YAML rejects that)
- verify output: use 192.168.1.10 for the routing peer so it stops
colliding with the 192.168.1.50 used as the destination's own IP
in the netplan example
- add an end-to-end verification step (curl + tcpdump) so a reader
confirms source IPs are actually preserved, not just that a route
exists in the table
advanced-configuration.mdx
- rewrite the contradictory Warning so it scopes correctly to legacy
Network Routes (which match peer NetBird IPs only) and points
readers to the Networks path when they want policy-layer ACLs
with masquerade off
---
.../network-routes/advanced-configuration.mdx | 2 +-
src/pages/manage/networks/masquerade.mdx | 39 ++++++++++++++++---
2 files changed, 34 insertions(+), 7 deletions(-)
diff --git a/src/pages/manage/network-routes/advanced-configuration.mdx b/src/pages/manage/network-routes/advanced-configuration.mdx
index 04dee9edf..508a76e4c 100644
--- a/src/pages/manage/network-routes/advanced-configuration.mdx
+++ b/src/pages/manage/network-routes/advanced-configuration.mdx
@@ -23,7 +23,7 @@ For the basics — masquerade behavior, ACL Groups, HA — see [Network Routes C
See [Masquerade](/manage/networks/masquerade) for persistent return-route configuration on the destination host.
-Without masquerade, traffic from unknown source IPs is rejected by NetBird's policy engine. You cannot use ACL Groups or Network Resources with masquerade disabled.
+ACL Groups on **Network Routes** (this page) match against peer NetBird IPs only, which limits source-IP-preserving access control on this path. For masquerade-off deployments with policy-layer ACLs, use the newer **Networks** path — see [Masquerade](/manage/networks/masquerade).
### Choosing the right approach
diff --git a/src/pages/manage/networks/masquerade.mdx b/src/pages/manage/networks/masquerade.mdx
index 19bb71b0f..b21bc1970 100644
--- a/src/pages/manage/networks/masquerade.mdx
+++ b/src/pages/manage/networks/masquerade.mdx
@@ -10,18 +10,33 @@ Masquerade is on by default. The routing peer SNATs forwarded traffic to its own
## What changes when masquerade is off
- The original NetBird overlay IP is preserved end-to-end.
-- The destination network must have a return route for the NetBird CIDR (default `100.64.0.0/10`) pointing at the routing peer's LAN IP.
+- The destination host (or, if it sits in a different subnet, its gateway) must have a return route for the NetBird CIDR (default `100.64.0.0/10`) pointing at the routing peer's LAN IP.
- High availability stops working — return traffic must flow back through one specific routing peer, so the destination network has no way to follow a failover. See [How Routing Peers Work — Masquerade](/manage/networks/how-routing-peers-work#masquerade).
Masquerade can only be turned off on Linux routing peers.
+## Disable masquerade on the routing peer
+
+In the dashboard: **Networks** → your network → the **routing peer** row → toggle **Masquerade** off. The change takes effect within seconds; the routing peer stops SNATing forwarded traffic for this network.
+
+You can also flip it through the API:
+
+```bash
+curl -X PUT https://api.netbird.io/api/networks//routers/ \
+ -H "Authorization: Token " \
+ -H "Content-Type: application/json" \
+ -d '{"peer": "", "masquerade": false, "metric": 9999, "enabled": true}'
+```
+
+The rest of this page covers the return-route prerequisite the destination network needs once masquerade is off.
+
## Inputs to substitute
The examples below use placeholders. Swap in:
-- `100.64.0.0/10` — default NetBird CIDR. Substitute your account's range if it's narrower.
+- `100.64.0.0/10` — default NetBird CIDR. See [Find your account's NetBird range](#find-your-accounts-netbird-range) below for the narrower `/16` you should use in practice.
- `` — the routing peer's IP on the destination subnet.
- `` — the LAN interface on the destination host. Use `ip -br addr` to identify it.
@@ -50,7 +65,7 @@ sudo ip route add 100.64.0.0/10 via
From a NetBird peer, confirm reachability with a protocol/port your NetBird policy allows — for example `curl http://:`, or `nc -zv ` for a non-HTTP service. Then remove the test route before committing the persistent version:
```bash
-sudo ip route del 100.64.0.0/10
+sudo ip route del 100.64.0.0/10 via
```
## Persistent configuration
@@ -62,7 +77,7 @@ Pick **one** of the methods below — your host uses one network manager, not bo
### Netplan (Ubuntu 18.04+)
-On Ubuntu Server, `/etc/netplan/` usually already has a yaml from cloud-init (`50-cloud-init.yaml`) or the installer (`00-installer-config.yaml`). Add a `routes:` entry to the interface stanza. The `addresses:` and default-route values shown below are placeholders for whatever is already in your file — not values to copy as-is:
+On Ubuntu Server, `/etc/netplan/` usually already has a yaml from cloud-init (`50-cloud-init.yaml`) or the installer (`00-installer-config.yaml`). Append a new entry to the interface's `routes:` list (don't add a second `routes:` key — YAML won't accept that). The `addresses:` and default-route values shown below are placeholders for whatever is already in your file — not values to copy as-is:
```yaml
network:
@@ -115,14 +130,26 @@ The drop-in path only takes effect when a `.network` file already matches the in
ip route show 100.64.0.0/10
```
-Expect output like:
+Expect output like (where `192.168.1.10` stands for the routing peer's LAN IP — not the destination's own address):
```
-100.64.0.0/10 via 192.168.1.50 dev eth0
+100.64.0.0/10 via 192.168.1.10 dev eth0
```
Trailing fields such as `proto static`, `onlink`, or `metric 100` may appear depending on the network manager — those are normal.
+Then send a request from a NetBird peer and confirm the destination logs the original overlay IP:
+
+```bash
+# from a NetBird peer
+curl http://:
+
+# on the destination, tail the relevant log or capture briefly:
+sudo tcpdump -ni "src net 100.64.0.0/10 and port "
+```
+
+The source IP should fall inside your account's `/16` (e.g. `100.121.x.x`), not the routing peer's LAN IP.
+
## Security considerations
From 30037c9d70b1b931d238729e7ea6ca68598e41a7 Mon Sep 17 00:00:00 2001
From: Jack Carter <128555021+SunsetDrifter@users.noreply.github.com>
Date: Tue, 19 May 2026 15:01:42 +0200
Subject: [PATCH 15/16] docs: promote the /16 substitution reminder to a Note
callout
---
src/pages/manage/networks/masquerade.mdx | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/pages/manage/networks/masquerade.mdx b/src/pages/manage/networks/masquerade.mdx
index b21bc1970..26f9c80d1 100644
--- a/src/pages/manage/networks/masquerade.mdx
+++ b/src/pages/manage/networks/masquerade.mdx
@@ -52,7 +52,9 @@ NetBird IP: 100.121.195.4/16
# → this account's block is 100.121.0.0/16
```
+
Substitute that `/16` for `100.64.0.0/10` in every example below.
+
## Test the route before making it persistent
From 827ab56a5a2167c4b24a4a2fb36e2e292412dbbb Mon Sep 17 00:00:00 2001
From: Jack Carter <128555021+SunsetDrifter@users.noreply.github.com>
Date: Tue, 19 May 2026 15:03:02 +0200
Subject: [PATCH 16/16] docs: clearer wording for the /16 substitution Note
---
src/pages/manage/networks/masquerade.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pages/manage/networks/masquerade.mdx b/src/pages/manage/networks/masquerade.mdx
index 26f9c80d1..27a949fa5 100644
--- a/src/pages/manage/networks/masquerade.mdx
+++ b/src/pages/manage/networks/masquerade.mdx
@@ -53,7 +53,7 @@ NetBird IP: 100.121.195.4/16
```
-Substitute that `/16` for `100.64.0.0/10` in every example below.
+Wherever the examples below show `100.64.0.0/10`, use your account's `/16` instead.
## Test the route before making it persistent