[GH-ISSUE #5683] Exit node masquerade overrides per-route masquerade=false setting #11861

Open
opened 2026-08-05 01:31:22 -04:00 by saavagebueno · 0 comments
Owner

Originally created by @tobsec on GitHub (Mar 24, 2026).
Original GitHub issue: https://github.com/netbirdio/netbird/issues/5683

Description

When a peer is configured as both an exit node (0.0.0.0/0) and a routing peer for specific subnets with masquerade disabled, the exit node's postrouting masquerade fires for all traffic — the per-route masquerade=false setting is silently ignored.

Steps to reproduce

  1. Peer B is a routing peer for subnet 192.168.0.0/24 with masquerade=OFF
  2. Peer A is also an exit node (0.0.0.0/0) — masquerade cannot be disabled for exit nodes
  3. From a client routed through peer A, send traffic to a host in 192.168.0.0/24

Expected: traffic arrives at destination with client's NetBird IP as source
Actual: traffic arrives masqueraded — source is peer B's WireGuard interface IP

Root cause

addNatRule() sets fwmark PreroutingFwmarkMasquerade (0x1BD21) on all wt0 traffic when adding the exit node route. addPostroutingRules() masquerades everything carrying that mark. There is no mechanism for a per-route masquerade=false to opt out of this blanket rule — the chain order means the exit node's rule always wins.

Impact

Any service relying on the original source IP is broken for clients behind an exit node:

  • Firewall rules matching the client's NetBird IP
  • IPsec policies with src-address matching
  • Per-device ACLs on the destination network

Environment

  • NetBird client (Linux, nftables and iptables backends both affected)
  • Exit node and per-subnet routing used simultaneously
Originally created by @tobsec on GitHub (Mar 24, 2026). Original GitHub issue: https://github.com/netbirdio/netbird/issues/5683 ## Description When a peer is configured as both an **exit node** (`0.0.0.0/0`) and a **routing peer** for specific subnets with masquerade disabled, the exit node's postrouting masquerade fires for all traffic — the per-route `masquerade=false` setting is silently ignored. ## Steps to reproduce 1. Peer B is a routing peer for subnet `192.168.0.0/24` with **masquerade=OFF** 2. Peer A is also an exit node (`0.0.0.0/0`) — masquerade cannot be disabled for exit nodes 3. From a client routed through peer A, send traffic to a host in `192.168.0.0/24` **Expected:** traffic arrives at destination with client's NetBird IP as source **Actual:** traffic arrives masqueraded — source is peer B's WireGuard interface IP ## Root cause `addNatRule()` sets fwmark `PreroutingFwmarkMasquerade` (`0x1BD21`) on **all** `wt0` traffic when adding the exit node route. `addPostroutingRules()` masquerades everything carrying that mark. There is no mechanism for a per-route `masquerade=false` to opt out of this blanket rule — the chain order means the exit node's rule always wins. ## Impact Any service relying on the original source IP is broken for clients behind an exit node: - Firewall rules matching the client's NetBird IP - IPsec policies with `src-address` matching - Per-device ACLs on the destination network ## Environment - NetBird client (Linux, nftables and iptables backends both affected) - Exit node and per-subnet routing used simultaneously ## Related - #2751 (closed, same root cause reported) - #4542 (open, related) - Fix proposed in PR #5682
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: DYNR/netbird#11861