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