[GH-ISSUE #5797] entire LAN subnet leak when connected to an exit-node #11085

Open
opened 2026-08-05 01:28:26 -04:00 by saavagebueno · 4 comments
Owner

Originally created by @dewpointau on GitHub (Apr 4, 2026).
Original GitHub issue: https://github.com/netbirdio/netbird/issues/5797

Originally assigned to: @jnfrati on GitHub.

Problem Description

When configuring a peer as an exit node (0.0.0.0/0 route), clients using that
exit node can unintentionally reach the entire LAN subnet of the routing peer,
even when:

  • The default All↔All policy is disabled
  • Custom ACL policies are scoped only to the exit node peers
  • No additional network routes (e.g. 192.168.x.x/24) are advertised
  • Distribution group is scoped to specific peers only

This is because the exit node's masquerade rules forward ALL traffic arriving
on wt0 to eth0 — including traffic destined for private RFC1918 ranges on the
routing peer's local network. NetBird's ACL policies operate at the peer
connection level and do not restrict what the routing peer's kernel forwards
at the network level.

Environment

  • NetBird client: 0.67.x (self-hosted)
  • Routing peer OS: Debian GNU/Linux 13 (nftables)
  • Client: iOS 16.x

Steps to Reproduce

  1. Set up a peer as an exit node with masquerade enabled (default)
  2. Disable the default All↔All policy
  3. Create a scoped ACL policy: mobile-clients → exit-node-group
  4. Connect a mobile client through the exit node
  5. From the mobile client, ping or access a LAN IP on the routing peer's
    subnet (e.g. 192.168.100.1, the router, or other LAN hosts)

Expected: LAN is not reachable — only internet traffic routes through
the exit node.

Actual: Full LAN access is available. The mobile client can reach any
host on the routing peer's local network, including router admin panels,
other servers, etc.

This was also reported (without a solution) in:

Workaround (Confirmed Working)

The solution is to use route-level Access Control Groups with an
empty group, which is documented in a separate page
(docs: Configuring Routes with Access Control) but not mentioned anywhere
on the Exit Nodes page.

Steps:

  1. In the dashboard, go to Groups → create a new group called
    blocked-lanadd no peers to it
  2. Go to Network Routes → edit your exit node route (0.0.0.0/0)
  3. Set Access Control Groups to blocked-lan
  4. Do NOT create any matching access policy for this group

This works because per the docs:

"If you assign an access control group to a route but no route access
policies exist or are enabled, all routed traffic will be dropped."

The empty group acts as a firewall — no peers match it, no policy exists
for it, so all traffic attempting to reach the routed network (LAN) via
the exit node is dropped. Internet traffic is unaffected because it is
handled by masquerade before the route ACL is evaluated.

Documentation Recommendations

This is a significant security concern that affects any user who:

  • Runs an exit node on a machine that also sits on a LAN
  • Has other devices on that LAN they do not want exposed
  • Assumes ACL policies between peers are sufficient to prevent LAN leakage

The current Exit Nodes documentation page
(docs.netbird.io/manage/network-routes/use-cases/by-scenario/exit-nodes)
makes no mention of this behavior or how to prevent it.

We recommend the following improvements:

  1. Add a Security Note callout on the Exit Nodes page warning that
    clients using an exit node can reach the routing peer's LAN by default

  2. Add a "Restricting LAN access" section on the Exit Nodes page
    explaining the empty Access Control Group workaround

  3. Consider adding a dedicated "Internet-only exit node" toggle in
    the Add Exit Node dialog that automatically applies this protection
    without requiring users to understand the underlying route ACL mechanism

This is a common real-world use case — many homelab and self-hosted users
run exit nodes on machines inside their home network and have no intention
of exposing their entire LAN to mobile clients.

Originally created by @dewpointau on GitHub (Apr 4, 2026). Original GitHub issue: https://github.com/netbirdio/netbird/issues/5797 Originally assigned to: @jnfrati on GitHub. ## Problem Description When configuring a peer as an exit node (0.0.0.0/0 route), clients using that exit node can unintentionally reach the entire LAN subnet of the routing peer, even when: - The default All↔All policy is disabled - Custom ACL policies are scoped only to the exit node peers - No additional network routes (e.g. 192.168.x.x/24) are advertised - Distribution group is scoped to specific peers only This is because the exit node's masquerade rules forward ALL traffic arriving on wt0 to eth0 — including traffic destined for private RFC1918 ranges on the routing peer's local network. NetBird's ACL policies operate at the peer connection level and do not restrict what the routing peer's kernel forwards at the network level. ## Environment - NetBird client: 0.67.x (self-hosted) - Routing peer OS: Debian GNU/Linux 13 (nftables) - Client: iOS 16.x ## Steps to Reproduce 1. Set up a peer as an exit node with masquerade enabled (default) 2. Disable the default All↔All policy 3. Create a scoped ACL policy: `mobile-clients → exit-node-group` 4. Connect a mobile client through the exit node 5. From the mobile client, ping or access a LAN IP on the routing peer's subnet (e.g. 192.168.100.1, the router, or other LAN hosts) **Expected:** LAN is not reachable — only internet traffic routes through the exit node. **Actual:** Full LAN access is available. The mobile client can reach any host on the routing peer's local network, including router admin panels, other servers, etc. ## Related Issues This was also reported (without a solution) in: - #2355 - #3812 ## Workaround (Confirmed Working) The solution is to use **route-level Access Control Groups** with an **empty group**, which is documented in a separate page (docs: Configuring Routes with Access Control) but not mentioned anywhere on the Exit Nodes page. ### Steps: 1. In the dashboard, go to **Groups** → create a new group called `blocked-lan` — **add no peers to it** 2. Go to **Network Routes** → edit your exit node route (0.0.0.0/0) 3. Set **Access Control Groups** to `blocked-lan` 4. Do NOT create any matching access policy for this group This works because per the docs: > "If you assign an access control group to a route but no route access > policies exist or are enabled, all routed traffic will be dropped." The empty group acts as a firewall — no peers match it, no policy exists for it, so all traffic attempting to reach the routed network (LAN) via the exit node is dropped. Internet traffic is unaffected because it is handled by masquerade before the route ACL is evaluated. ## Documentation Recommendations This is a significant security concern that affects any user who: - Runs an exit node on a machine that also sits on a LAN - Has other devices on that LAN they do not want exposed - Assumes ACL policies between peers are sufficient to prevent LAN leakage The current **Exit Nodes** documentation page (docs.netbird.io/manage/network-routes/use-cases/by-scenario/exit-nodes) makes no mention of this behavior or how to prevent it. We recommend the following improvements: 1. Add a **Security Note** callout on the Exit Nodes page warning that clients using an exit node can reach the routing peer's LAN by default 2. Add a **"Restricting LAN access"** section on the Exit Nodes page explaining the empty Access Control Group workaround 3. Consider adding a dedicated **"Internet-only exit node"** toggle in the Add Exit Node dialog that automatically applies this protection without requiring users to understand the underlying route ACL mechanism This is a common real-world use case — many homelab and self-hosted users run exit nodes on machines inside their home network and have no intention of exposing their entire LAN to mobile clients.
saavagebueno added the missing-docs label 2026-08-05 01:28:26 -04:00
Author
Owner

@dewpointau commented on GitHub (Apr 4, 2026):

The Proper Fix — Route-Level Access Control
When you assign an access control group to a route, only traffic that matches the defined policies can access the routed network. If you assign an access control group to a route but no route access policies exist or are enabled, all routed traffic will be dropped. netbird-docs
This is exactly what you need. Here's what to do:
Step 1: Create an empty group
Dashboard → Groups → Add Group, name it blocked-lan — add no peers to it.
Step 2: Assign it as Access Control Group on both exit node routes
Dashboard → Network Routes → edit Exit-node:

Find the Access Control Groups field
Set it to blocked-lan
Save

<!-- gh-comment-id:4187506963 --> @dewpointau commented on GitHub (Apr 4, 2026): The Proper Fix — Route-Level Access Control When you assign an access control group to a route, only traffic that matches the defined policies can access the routed network. If you assign an access control group to a route but no route access policies exist or are enabled, all routed traffic will be dropped. [netbird-docs](https://docs.netbird.io/manage/network-routes/use-cases/by-configuration/access-control) This is exactly what you need. Here's what to do: Step 1: Create an empty group Dashboard → Groups → Add Group, name it blocked-lan — add no peers to it. Step 2: Assign it as Access Control Group on both exit node routes Dashboard → Network Routes → edit Exit-node: Find the Access Control Groups field Set it to blocked-lan Save
Author
Owner

@lixmal commented on GitHub (Apr 5, 2026):

Expected: LAN is not reachable — only internet traffic routes through
the exit node

Why is that an expectation? It's a 0.0.0.0/0 route after all, naturally it contains everything ipv4.
Take a look at the netbird up --block-lan-access flag on the client

<!-- gh-comment-id:4188292904 --> @lixmal commented on GitHub (Apr 5, 2026): > Expected: LAN is not reachable — only internet traffic routes through the exit node Why is that an expectation? It's a 0.0.0.0/0 route after all, naturally it contains everything ipv4. Take a look at the `netbird up --block-lan-access` flag on the client
Author
Owner

@jnfrati commented on GitHub (Apr 7, 2026):

@dewpointau as @lixmal pointed out this should be solved by using the --block-lan-access flag to disable this. We're definitely missing docs for this flag, so I'll leave the issue open with missing-docs label.

Either way, feel free to answer to this if you don't think that the flag solves the problem!

<!-- gh-comment-id:4198487929 --> @jnfrati commented on GitHub (Apr 7, 2026): @dewpointau as @lixmal pointed out this should be solved by using the `--block-lan-access` flag to disable this. We're definitely missing docs for this flag, so I'll leave the issue open with `missing-docs` label. Either way, feel free to answer to this if you don't think that the flag solves the problem!
Author
Owner

@TonyBostonTB commented on GitHub (Apr 9, 2026):

If this is a flag that the user needs to add, how would this be done for managed clients in a corporate environment?

<!-- gh-comment-id:4213263520 --> @TonyBostonTB commented on GitHub (Apr 9, 2026): If this is a flag that the user needs to add, how would this be done for managed clients in a corporate environment?
Sign in to join this conversation.
No Label missing-docs
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: DYNR/netbird#11085