[GH-ISSUE #5120] Exit node with Access Control Groups doesn't seem to work #10573

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

Originally created by @araemo on GitHub (Jan 16, 2026).
Original GitHub issue: https://github.com/netbirdio/netbird/issues/5120

Describe the problem

Exit node configuration is not correctly configuring iptables on the exit node. There is no fwd accept rule for traffic to 0.0.0.0/0 without related/established ctstate.

If I remove the access control group, it gets created.

To compare, when I create a manual network/subnet rule for my internal network (or for 0.0.0.0/0), it gets created, and I see that the iptables includes rules for each individual peer that is in the access control group.

If I use the same access control group for the exit node, iptables does not include a forward rule for 0.0.0.0/0 with no ctstate. If I remove the access control group, a wildcard forward rule for 0.0.0.0/0 with no ctstate is created.

Without this rule, no routed traffic can be initiated by the endpoints that are trying to use the exit node.

Examples:
Exit node with no access control group

Chain NETBIRD-RT-FWD-IN (1 references)
 pkts bytes target     prot opt in     out     source               destination
 9174 1362K ACCEPT     0    --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
    4  3944 ACCEPT     0    --  *      *       0.0.0.0/0            0.0.0.0/0

Exit node with access control group

Chain NETBIRD-RT-FWD-IN (1 references)
 pkts bytes target     prot opt in     out     source               destination
 9174 1362K ACCEPT     0    --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED

Manual network route to 0.0.0.0/0 with access control group

Chain NETBIRD-RT-FWD-IN (1 references)
 pkts bytes target     prot opt in     out     source               destination
 9225 1380K ACCEPT     0    --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
    3  2665 ACCEPT     0    --  *      *       100.73.187.231       0.0.0.0/0

To Reproduce

Steps to reproduce the behavior:

  1. Create an exit node using an access control group
  2. view the iptables -L -vn output on the exit node to verify the ctstate RELATED,ESTABLISHED rules are created, but the traffic initiation rule (without ctstate related/established) is missing.
  3. Change the exit node to remove the access control group
  4. view the iptables output again and see that the traffic initiation rule is created.

Expected behavior

The exit node rule should create iptables rules similarly to how manual network routes do - if an access control group is assigned, create a rule to accept traffic initiation from each endpoint in that group (or group them however is normally done - I only have a single client endpoint so far).

Are you using NetBird Cloud?

self-hosted

NetBird version

0.62.3

Is any other VPN software installed?

No

Debug output

To help us resolve the problem, please attach the following anonymized status output

Peers detail:
 client1.netbird.selfhosted:
  NetBird IP: 100.73.187.231
  Public key: 0Ebd82UJzC0/Nj36mDXQvpnWzM8FUO2RGxEvk66z7jc=
  Status: Connected
  -- detail --
  Connection type: Relayed
  ICE candidate (Local/Remote): -/-
  ICE candidate endpoints (Local/Remote): -/-
  Relay server address: rels://netbird.anon-G6kwa.domain:443
  Last connection update: 34 minutes, 4 seconds ago
  Last WireGuard handshake: 1 minute, 1 second ago
  Transfer status (received/sent) 1.9 MiB/10.8 MiB
  Quantum resistance: false
  Networks: -
  Latency: 0s

Events:
  [INFO] SYSTEM (56ff1fa8-5804-43c3-871b-d57c0bc40dac)
    Message: Network map updated
    Time: 4 minutes, 45 seconds ago
  [INFO] SYSTEM (a9683124-9ec3-4256-9f2e-2e71acb9505c)
    Message: Network map updated
    Time: 4 minutes, 41 seconds ago
  [INFO] SYSTEM (505b4ba2-9e7e-45f5-93c4-52c97c50e54f)
    Message: Network map updated
    Time: 4 minutes, 40 seconds ago
  [INFO] SYSTEM (850fbe5d-d63a-4771-96b7-caee6d57fde0)
    Message: Network map updated
    Time: 3 minutes, 50 seconds ago
  [INFO] SYSTEM (ed866f91-0ec7-4f70-8487-2f1eaabfb719)
    Message: Network map updated
    Time: 3 minutes, 24 seconds ago
  [INFO] SYSTEM (b8bf894d-3d7d-47e9-9f0c-dc4a25f57d57)
    Message: Network map updated
    Time: 30 seconds ago
  [INFO] SYSTEM (bc786b74-a445-4ced-9a78-40b35e62ac1e)
    Message: Network map updated
    Time: 29 seconds ago
  [INFO] SYSTEM (db550908-3dcc-4365-8348-1d0100844bad)
    Message: Network map updated
    Time: 26 seconds ago
  [INFO] SYSTEM (86a35fcf-74c0-49e2-9635-7cf4e6b90a68)
    Message: Network map updated
    Time: 22 seconds ago
  [INFO] SYSTEM (1b98be5c-1893-49dc-9a4e-7895560e0529)
    Message: Network map updated
    Time: 5 seconds ago
OS: linux/amd64
Daemon version: 0.62.3
CLI version: 0.62.3
Profile: default
Management: Connected to https://netbird.anon-G6kwa.domain:443
Signal: Connected to https://netbird.anon-G6kwa.domain:443
Relays:
  [stun:netbird.anon-G6kwa.domain:3478] is Available
  [rels://netbird.anon-G6kwa.domain:443] is Available
Nameservers:
FQDN: netbird0.netbird.selfhosted
NetBird IP: 100.73.147.51/16
Interface type: Kernel
Quantum resistance: false
Lazy connection: false
SSH Server: Disabled
Networks: 0.0.0.0/0
Forwarding rules: 0
Peers count: 1/1 Connected

Debug bundle file key:
a00eb4fc9fbd77fd6c1688adc60de4fba250151db1cc02f743905b7fd2695aa3/15ac54e6-a6b3-441b-82ae-5a74940ccd21

Additional context

Add any other context about the problem here.

Have you tried these troubleshooting steps?

  • Reviewed client troubleshooting (if applicable)
  • Checked for newer NetBird versions
  • Searched for similar issues on GitHub (including closed ones)
  • Restarted the NetBird client
  • Disabled other VPN software
  • Checked firewall settings
Originally created by @araemo on GitHub (Jan 16, 2026). Original GitHub issue: https://github.com/netbirdio/netbird/issues/5120 **Describe the problem** Exit node configuration is not correctly configuring iptables on the exit node. There is no fwd accept rule for traffic to 0.0.0.0/0 without related/established ctstate. If I remove the access control group, it gets created. To compare, when I create a manual network/subnet rule for my internal network (or for 0.0.0.0/0), it gets created, and I see that the iptables includes rules for each individual peer that is in the access control group. If I use the same access control group for the exit node, iptables does not include a forward rule for 0.0.0.0/0 with no ctstate. If I remove the access control group, a wildcard forward rule for 0.0.0.0/0 with no ctstate is created. Without this rule, no routed traffic can be initiated by the endpoints that are trying to use the exit node. Examples: ***Exit node with no access control group*** ``` Chain NETBIRD-RT-FWD-IN (1 references) pkts bytes target prot opt in out source destination 9174 1362K ACCEPT 0 -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED 4 3944 ACCEPT 0 -- * * 0.0.0.0/0 0.0.0.0/0 ``` ***Exit node with access control group*** ``` Chain NETBIRD-RT-FWD-IN (1 references) pkts bytes target prot opt in out source destination 9174 1362K ACCEPT 0 -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED ``` ***Manual network route to 0.0.0.0/0 with access control group*** ``` Chain NETBIRD-RT-FWD-IN (1 references) pkts bytes target prot opt in out source destination 9225 1380K ACCEPT 0 -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED 3 2665 ACCEPT 0 -- * * 100.73.187.231 0.0.0.0/0 ``` **To Reproduce** Steps to reproduce the behavior: 1. Create an exit node using an access control group 2. view the `iptables -L -vn` output on the exit node to verify the `ctstate RELATED,ESTABLISHED` rules are created, but the traffic initiation rule (without ctstate related/established) is missing. 3. Change the exit node to remove the access control group 4. view the iptables output again and see that the traffic initiation rule is created. **Expected behavior** The exit node rule should create iptables rules similarly to how manual network routes do - if an access control group is assigned, create a rule to accept traffic initiation from each endpoint in that group (or group them however is normally done - I only have a single client endpoint so far). **Are you using NetBird Cloud?** self-hosted **NetBird version** 0.62.3 **Is any other VPN software installed?** No **Debug output** To help us resolve the problem, please attach the following anonymized status output ``` Peers detail: client1.netbird.selfhosted: NetBird IP: 100.73.187.231 Public key: 0Ebd82UJzC0/Nj36mDXQvpnWzM8FUO2RGxEvk66z7jc= Status: Connected -- detail -- Connection type: Relayed ICE candidate (Local/Remote): -/- ICE candidate endpoints (Local/Remote): -/- Relay server address: rels://netbird.anon-G6kwa.domain:443 Last connection update: 34 minutes, 4 seconds ago Last WireGuard handshake: 1 minute, 1 second ago Transfer status (received/sent) 1.9 MiB/10.8 MiB Quantum resistance: false Networks: - Latency: 0s Events: [INFO] SYSTEM (56ff1fa8-5804-43c3-871b-d57c0bc40dac) Message: Network map updated Time: 4 minutes, 45 seconds ago [INFO] SYSTEM (a9683124-9ec3-4256-9f2e-2e71acb9505c) Message: Network map updated Time: 4 minutes, 41 seconds ago [INFO] SYSTEM (505b4ba2-9e7e-45f5-93c4-52c97c50e54f) Message: Network map updated Time: 4 minutes, 40 seconds ago [INFO] SYSTEM (850fbe5d-d63a-4771-96b7-caee6d57fde0) Message: Network map updated Time: 3 minutes, 50 seconds ago [INFO] SYSTEM (ed866f91-0ec7-4f70-8487-2f1eaabfb719) Message: Network map updated Time: 3 minutes, 24 seconds ago [INFO] SYSTEM (b8bf894d-3d7d-47e9-9f0c-dc4a25f57d57) Message: Network map updated Time: 30 seconds ago [INFO] SYSTEM (bc786b74-a445-4ced-9a78-40b35e62ac1e) Message: Network map updated Time: 29 seconds ago [INFO] SYSTEM (db550908-3dcc-4365-8348-1d0100844bad) Message: Network map updated Time: 26 seconds ago [INFO] SYSTEM (86a35fcf-74c0-49e2-9635-7cf4e6b90a68) Message: Network map updated Time: 22 seconds ago [INFO] SYSTEM (1b98be5c-1893-49dc-9a4e-7895560e0529) Message: Network map updated Time: 5 seconds ago OS: linux/amd64 Daemon version: 0.62.3 CLI version: 0.62.3 Profile: default Management: Connected to https://netbird.anon-G6kwa.domain:443 Signal: Connected to https://netbird.anon-G6kwa.domain:443 Relays: [stun:netbird.anon-G6kwa.domain:3478] is Available [rels://netbird.anon-G6kwa.domain:443] is Available Nameservers: FQDN: netbird0.netbird.selfhosted NetBird IP: 100.73.147.51/16 Interface type: Kernel Quantum resistance: false Lazy connection: false SSH Server: Disabled Networks: 0.0.0.0/0 Forwarding rules: 0 Peers count: 1/1 Connected ``` Debug bundle file key: a00eb4fc9fbd77fd6c1688adc60de4fba250151db1cc02f743905b7fd2695aa3/15ac54e6-a6b3-441b-82ae-5a74940ccd21 **Additional context** Add any other context about the problem here. **Have you tried these troubleshooting steps?** - [x] Reviewed [client troubleshooting](https://docs.netbird.io/how-to/troubleshooting-client) (if applicable) - [x] Checked for newer NetBird versions - [x] Searched for similar issues on GitHub (including closed ones) - [x] Restarted the NetBird client - [x] Disabled other VPN software - [x] Checked firewall settings
saavagebueno added the triage-needed label 2026-08-05 01:26:26 -04:00
Author
Owner

@araemo commented on GitHub (Jan 16, 2026):

It's possible that my assumptions above are not how this is supposed to work.

I had another route for my local network set up, with masquerading. I ended up disabling all my manual network configs, deleting my exit node config, and recreating the exit node. Now I see a very different iptables result, and somehow netbird is still doing masquerading, but I don't see a masquerade rule in iptables:

Peers detail:
 client1.netbird.selfhosted:
  NetBird IP: 100.73.187.231
  Public key: 0Ebd82UJzC0/Nj36mDXQvpnWzM8FUO2RGxEvk66z7jc=
  Status: Connected
  -- detail --
  Connection type: P2P
  ICE candidate (Local/Remote): host/prflx
  ICE candidate endpoints (Local/Remote): 10.0.0.253:51820/10.0.0.183:51820
  Relay server address: rels://netbird.anon-SmZsm.domain:443
  Last connection update: 2 minutes, 31 seconds ago
  Last WireGuard handshake: Now
  Transfer status (received/sent) 242.0 KiB/425.9 KiB
  Quantum resistance: false
  Networks: -
  Latency: 7.050726ms

Events:
  [INFO] SYSTEM (a31ad480-3836-4d8a-9040-17b2d83d0785)
    Message: Network map updated
    Time: 15 minutes, 26 seconds ago
  [INFO] SYSTEM (dd44e6eb-df17-450e-abd3-9786178951b2)
    Message: Network map updated
    Time: 14 minutes, 38 seconds ago
  [INFO] SYSTEM (32122205-815b-4973-88a7-fb9103bafedd)
    Message: Network map updated
    Time: 14 minutes, 10 seconds ago
  [INFO] SYSTEM (fa71c65f-dfb4-4c36-b386-a5c975b5ec6a)
    Message: Network map updated
    Time: 13 minutes, 50 seconds ago
  [INFO] SYSTEM (c2079048-f828-4bb3-a440-7e4d390e813a)
    Message: Network map updated
    Time: 11 minutes, 22 seconds ago
  [INFO] SYSTEM (21d90e44-76b7-4fab-81bc-b95a8ebfa082)
    Message: Network map updated
    Time: 10 minutes, 47 seconds ago
  [INFO] SYSTEM (7cadb79e-cb5e-4a5a-9456-713d47b1850f)
    Message: Network map updated
    Time: 10 minutes, 28 seconds ago
  [INFO] SYSTEM (11a32cfa-bc33-4fd7-aa2e-3de6bb0d6c8f)
    Message: Network map updated
    Time: 6 minutes, 43 seconds ago
  [INFO] SYSTEM (2cb0be4b-502d-4b87-b82e-9c594dce6f4d)
    Message: Network map updated
    Time: 6 minutes, 31 seconds ago
  [INFO] SYSTEM (1e945721-3801-41fd-ba7c-bd1c7cee78d8)
    Message: Network map updated
    Time: 5 minutes, 59 seconds ago
OS: linux/amd64
Daemon version: 0.62.3
CLI version: 0.62.3
Profile: default
Management: Connected to https://netbird.anon-SmZsm.domain:443
Signal: Connected to https://netbird.anon-SmZsm.domain:443
Relays:
  [stun:netbird.anon-SmZsm.domain:3478] is Available
  [rels://netbird.anon-SmZsm.domain:443] is Available
Nameservers:
FQDN: netbird0.netbird.selfhosted
NetBird IP: 100.73.147.51/16
Interface type: Kernel
Quantum resistance: false
Lazy connection: false
SSH Server: Disabled
Networks: 0.0.0.0/0
Forwarding rules: 0
Peers count: 1/1 Connected

iptables -L -vn:

Chain INPUT (policy ACCEPT 67451 packets, 24M bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 ACCEPT     0    --  wt0    *       0.0.0.0/0            0.0.0.0/0

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
 3368 1502K ACCEPT     0    --  *      wt0     0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
 3232  896K ACCEPT     0    --  wt0    *       0.0.0.0/0            0.0.0.0/0

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

iptables -L -vnt nat

Chain PREROUTING (policy ACCEPT 7004 packets, 2042K bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 1209 packets, 98349 bytes)
 pkts bytes target     prot opt in     out     source               destination

Compare to my iptables when I had more routes configured in the admin console:
iptables -L -vn:

Chain INPUT (policy ACCEPT 25229 packets, 2793K bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 ACCEPT     0    --  wt0    *       0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
   50  4200 NETBIRD-ACL-INPUT  0    --  wt0    *       0.0.0.0/0            0.0.0.0/0
    0     0 DROP       0    --  wt0    *       0.0.0.0/0            0.0.0.0/0

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
 1626  417K NETBIRD-RT-FWD-IN  0    --  wt0    *       0.0.0.0/0            0.0.0.0/0
    0     0 ACCEPT     0    --  *      *       0.0.0.0/0            0.0.0.0/0            mark match 0x1bd20
   73  5940 NETBIRD-RT-FWD-OUT  0    --  *      wt0     0.0.0.0/0            0.0.0.0/0
 1561  411K DROP       0    --  wt0    *       0.0.0.0/0            0.0.0.0/0

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain NETBIRD-ACL-INPUT (1 references)
 pkts bytes target     prot opt in     out     source               destination
   50  4200 ACCEPT     0    --  *      *       0.0.0.0/0            0.0.0.0/0            match-set nb0000001 src

Chain NETBIRD-RT-FWD-IN (1 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 ACCEPT     0    --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
    0     0 ACCEPT     0    --  *      *       100.73.187.231       10.0.0.0/8

Chain NETBIRD-RT-FWD-OUT (1 references)
 pkts bytes target     prot opt in     out     source               destination
   65  5460 ACCEPT     0    --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED

iptables -L -vnt nat:

Chain PREROUTING (policy ACCEPT 14583 packets, 4665K bytes)
 pkts bytes target     prot opt in     out     source               destination
14583 4665K NETBIRD-RT-RDR  0    --  *      *       0.0.0.0/0            0.0.0.0/0

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 297 packets, 21859 bytes)
 pkts bytes target     prot opt in     out     source               destination
  362 27319 NETBIRD-RT-NAT  0    --  *      *       0.0.0.0/0            0.0.0.0/0

Chain NETBIRD-RT-NAT (1 references)
 pkts bytes target     prot opt in     out     source               destination
   65  5460 MASQUERADE  0    --  *      !lo     0.0.0.0/0            0.0.0.0/0            mark match 0x1bd21
    0     0 MASQUERADE  0    --  *      wt0     0.0.0.0/0            0.0.0.0/0            mark match 0x1bd22

Chain NETBIRD-RT-RDR (1 references)
 pkts bytes target     prot opt in     out     source               destination

So, is the real problem I was having that an exit node should not also be a router for specific subnets?

<!-- gh-comment-id:3760918259 --> @araemo commented on GitHub (Jan 16, 2026): It's possible that my assumptions above are not how this is supposed to work. I had another route for my local network set up, with masquerading. I ended up disabling all my manual network configs, deleting my exit node config, and recreating the exit node. Now I see a very different iptables result, and somehow netbird is still doing masquerading, but I don't see a masquerade rule in iptables: ``` Peers detail: client1.netbird.selfhosted: NetBird IP: 100.73.187.231 Public key: 0Ebd82UJzC0/Nj36mDXQvpnWzM8FUO2RGxEvk66z7jc= Status: Connected -- detail -- Connection type: P2P ICE candidate (Local/Remote): host/prflx ICE candidate endpoints (Local/Remote): 10.0.0.253:51820/10.0.0.183:51820 Relay server address: rels://netbird.anon-SmZsm.domain:443 Last connection update: 2 minutes, 31 seconds ago Last WireGuard handshake: Now Transfer status (received/sent) 242.0 KiB/425.9 KiB Quantum resistance: false Networks: - Latency: 7.050726ms Events: [INFO] SYSTEM (a31ad480-3836-4d8a-9040-17b2d83d0785) Message: Network map updated Time: 15 minutes, 26 seconds ago [INFO] SYSTEM (dd44e6eb-df17-450e-abd3-9786178951b2) Message: Network map updated Time: 14 minutes, 38 seconds ago [INFO] SYSTEM (32122205-815b-4973-88a7-fb9103bafedd) Message: Network map updated Time: 14 minutes, 10 seconds ago [INFO] SYSTEM (fa71c65f-dfb4-4c36-b386-a5c975b5ec6a) Message: Network map updated Time: 13 minutes, 50 seconds ago [INFO] SYSTEM (c2079048-f828-4bb3-a440-7e4d390e813a) Message: Network map updated Time: 11 minutes, 22 seconds ago [INFO] SYSTEM (21d90e44-76b7-4fab-81bc-b95a8ebfa082) Message: Network map updated Time: 10 minutes, 47 seconds ago [INFO] SYSTEM (7cadb79e-cb5e-4a5a-9456-713d47b1850f) Message: Network map updated Time: 10 minutes, 28 seconds ago [INFO] SYSTEM (11a32cfa-bc33-4fd7-aa2e-3de6bb0d6c8f) Message: Network map updated Time: 6 minutes, 43 seconds ago [INFO] SYSTEM (2cb0be4b-502d-4b87-b82e-9c594dce6f4d) Message: Network map updated Time: 6 minutes, 31 seconds ago [INFO] SYSTEM (1e945721-3801-41fd-ba7c-bd1c7cee78d8) Message: Network map updated Time: 5 minutes, 59 seconds ago OS: linux/amd64 Daemon version: 0.62.3 CLI version: 0.62.3 Profile: default Management: Connected to https://netbird.anon-SmZsm.domain:443 Signal: Connected to https://netbird.anon-SmZsm.domain:443 Relays: [stun:netbird.anon-SmZsm.domain:3478] is Available [rels://netbird.anon-SmZsm.domain:443] is Available Nameservers: FQDN: netbird0.netbird.selfhosted NetBird IP: 100.73.147.51/16 Interface type: Kernel Quantum resistance: false Lazy connection: false SSH Server: Disabled Networks: 0.0.0.0/0 Forwarding rules: 0 Peers count: 1/1 Connected ``` iptables -L -vn: ``` Chain INPUT (policy ACCEPT 67451 packets, 24M bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT 0 -- wt0 * 0.0.0.0/0 0.0.0.0/0 Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 3368 1502K ACCEPT 0 -- * wt0 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED 3232 896K ACCEPT 0 -- wt0 * 0.0.0.0/0 0.0.0.0/0 Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination ``` iptables -L -vnt nat ``` Chain PREROUTING (policy ACCEPT 7004 packets, 2042K bytes) pkts bytes target prot opt in out source destination Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 1209 packets, 98349 bytes) pkts bytes target prot opt in out source destination ``` Compare to my iptables when I had more routes configured in the admin console: iptables -L -vn: ``` Chain INPUT (policy ACCEPT 25229 packets, 2793K bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT 0 -- wt0 * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED 50 4200 NETBIRD-ACL-INPUT 0 -- wt0 * 0.0.0.0/0 0.0.0.0/0 0 0 DROP 0 -- wt0 * 0.0.0.0/0 0.0.0.0/0 Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 1626 417K NETBIRD-RT-FWD-IN 0 -- wt0 * 0.0.0.0/0 0.0.0.0/0 0 0 ACCEPT 0 -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0x1bd20 73 5940 NETBIRD-RT-FWD-OUT 0 -- * wt0 0.0.0.0/0 0.0.0.0/0 1561 411K DROP 0 -- wt0 * 0.0.0.0/0 0.0.0.0/0 Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain NETBIRD-ACL-INPUT (1 references) pkts bytes target prot opt in out source destination 50 4200 ACCEPT 0 -- * * 0.0.0.0/0 0.0.0.0/0 match-set nb0000001 src Chain NETBIRD-RT-FWD-IN (1 references) pkts bytes target prot opt in out source destination 0 0 ACCEPT 0 -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED 0 0 ACCEPT 0 -- * * 100.73.187.231 10.0.0.0/8 Chain NETBIRD-RT-FWD-OUT (1 references) pkts bytes target prot opt in out source destination 65 5460 ACCEPT 0 -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED ``` iptables -L -vnt nat: ``` Chain PREROUTING (policy ACCEPT 14583 packets, 4665K bytes) pkts bytes target prot opt in out source destination 14583 4665K NETBIRD-RT-RDR 0 -- * * 0.0.0.0/0 0.0.0.0/0 Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 297 packets, 21859 bytes) pkts bytes target prot opt in out source destination 362 27319 NETBIRD-RT-NAT 0 -- * * 0.0.0.0/0 0.0.0.0/0 Chain NETBIRD-RT-NAT (1 references) pkts bytes target prot opt in out source destination 65 5460 MASQUERADE 0 -- * !lo 0.0.0.0/0 0.0.0.0/0 mark match 0x1bd21 0 0 MASQUERADE 0 -- * wt0 0.0.0.0/0 0.0.0.0/0 mark match 0x1bd22 Chain NETBIRD-RT-RDR (1 references) pkts bytes target prot opt in out source destination ``` So, is the real problem I was having that an exit node should not also be a router for specific subnets?
Author
Owner

@kyuuk commented on GitHub (Jan 20, 2026):

@araemo, you may be doing the same mistake as me,

i didn't understand the purpose of this field correctly, had to read & reread the documentation for that.

i was putting the source group in that field (assuming that it meant that only that group can access this exit-node)

but what should be set in that field is a group that should be used as a destination in the Access Control Policies while having a policy that allow traffic from a source group to this group to be able to route traffic

<!-- gh-comment-id:3775245637 --> @kyuuk commented on GitHub (Jan 20, 2026): @araemo, you may be doing the same mistake as me, i didn't understand the purpose of this field correctly, had to read & reread the documentation for that. i was putting the source group in that field (assuming that it meant that only that group can access this exit-node) but what should be set in that field is a group that should be used as a **destination** in the `Access Control` Policies while having a policy that allow traffic from a source group to this group to be able to route traffic
Author
Owner

@araemo commented on GitHub (Jan 20, 2026):

Thank you. I think I see now how that is what the docs describe, but only after I think of the exit node policy as 'just another routing policy'.

The way it is presented in-console makes it seem different, and thus it doesn't seem like the docs that talk about access control groups should apply to the exit node / default route.

Particularly since the point of the exit node/default route is to allow traffic to reach non-netbird endpoints, you cannot put those endpoints in the ACL as the destination. So having the ACL field be defining the destination... seems counter-productive for exit nodes in most cases. (I can see a use case where you want an exit node but still want to restrict traffic out of it...... but again, if the traffic's destination can exist in netbird as a peer, what's the point of the exit group?)

<!-- gh-comment-id:3775841145 --> @araemo commented on GitHub (Jan 20, 2026): Thank you. I think I see now how that is what the docs describe, but only after I think of the exit node policy as 'just another routing policy'. The way it is presented in-console makes it seem different, and thus it doesn't seem like the docs that talk about access control groups should apply to the exit node / default route. Particularly since the point of the exit node/default route is to allow traffic to reach non-netbird endpoints, you cannot put those endpoints in the ACL as the destination. So having the ACL field be defining the destination... seems counter-productive for exit nodes in most cases. (I can see a use case where you want an exit node but still want to restrict traffic out of it...... but again, if the traffic's destination can exist in netbird as a peer, what's the point of the exit group?)
Author
Owner

@kyuuk commented on GitHub (Jan 21, 2026):

i mostly agree with you, and i think it not intended, it's just that exit-node is a special case of a network route where the destination network is 0.0.0.0/0 so it inherits the network routes config fields.

personally i see only a few usecases where this could be usefull, for example you want some peer to access only web traffic via your exit-node (port 80 and 443) and other that can access everything and this would be achievable using ACLs

<!-- gh-comment-id:3778311649 --> @kyuuk commented on GitHub (Jan 21, 2026): i mostly agree with you, and i think it not intended, it's just that exit-node is a special case of a network route where the destination network is `0.0.0.0/0` so it inherits the network routes config fields. personally i see only a few usecases where this could be usefull, for example you want some peer to access only web traffic via your exit-node (port 80 and 443) and other that can access everything and this would be achievable using ACLs
Author
Owner

@heypete commented on GitHub (Jan 30, 2026):

personally i see only a few usecases where this could be usefull, for example you want some peer to access only web traffic via your exit-node (port 80 and 443) and other that can access everything and this would be achievable using ACLs

In my case, I’d like for traffic being routed by the exit node to only be able to connect to public IPs addresses by default (no NetBird IPs, no private IP ranges, etc.). In such a scenario, access to private IP space and resources could then be defined through policies.

Currently it appears that peers with access to an exit node (even if it’s not selected in the client to redirect all traffic) have access to all network destinations the exit node itself (including in private IP space) does regardless of ACLs.

I’ve only recently discovered this and am still investigating if this is as-designed or if it’s some quirk with my configuration.

<!-- gh-comment-id:3825737791 --> @heypete commented on GitHub (Jan 30, 2026): > personally i see only a few usecases where this could be usefull, for example you want some peer to access only web traffic via your exit-node (port 80 and 443) and other that can access everything and this would be achievable using ACLs In my case, I’d like for traffic being routed by the exit node to only be able to connect to public IPs addresses by default (no NetBird IPs, no private IP ranges, etc.). In such a scenario, access to private IP space and resources could then be defined through policies. Currently it appears that peers with access to an exit node (even if it’s not selected in the client to redirect all traffic) have access to all network destinations the exit node itself (including in private IP space) does regardless of ACLs. I’ve only recently discovered this and am still investigating if this is as-designed or if it’s some quirk with my configuration.
Author
Owner

@kyuuk commented on GitHub (Feb 1, 2026):

Hello @heypete, there actually is a flag specially for that, it can be used to block all LAN from being routed from an exit-node

netbird up --block-lan-access (on the exit-node peer)

details can be found with netbird up --help

<!-- gh-comment-id:3831827803 --> @kyuuk commented on GitHub (Feb 1, 2026): Hello @heypete, there actually is a flag specially for that, it can be used to block all LAN from being routed from an exit-node `netbird up --block-lan-access` (on the exit-node peer) details can be found with `netbird up --help`
Author
Owner

@heypete commented on GitHub (Feb 1, 2026):

Thanks @kyuuk, that’s very helpful indeed!

Alas, that option completely overrides the access policies but to the other extreme: it seems to prohibit all LAN access entirely, even if policies exist to allow it, and only allows access to public IPs.

A client that’s connected to a variety of internal resources will lose access to those resources when enabling the route to the exit node with —block-lan-access set.

I wish the exit node could behave in a more configurable way: by default allow access to public addresses only, but allow NetBird settings (like networks and policies) to permit local access as specified.

That may be sufficiently different from this issue that I should open a separate issue.

<!-- gh-comment-id:3832362103 --> @heypete commented on GitHub (Feb 1, 2026): Thanks @kyuuk, that’s very helpful indeed! Alas, that option completely overrides the access policies but to the other extreme: it seems to prohibit all LAN access entirely, even if policies exist to allow it, and only allows access to public IPs. A client that’s connected to a variety of internal resources will lose access to those resources when enabling the route to the exit node with `—block-lan-access` set. I wish the exit node could behave in a more configurable way: by default allow access to public addresses only, but allow NetBird settings (like networks and policies) to permit local access as specified. That may be sufficiently different from this issue that I should open a separate issue.
Author
Owner

@kyuuk commented on GitHub (Feb 2, 2026):

I wish the exit node could behave in a more configurable way: by default allow access to public addresses only, but allow NetBird settings (like networks and policies) to permit local access as specified.

I totally agree with you,

i also think this shoud be a new issue.

but something i just discovered and that may help you achieve what you want, is that you can create drop policies, but it can be created only with the API
https://docs.netbird.io/api/resources/policies#create-a-policy

<!-- gh-comment-id:3835304336 --> @kyuuk commented on GitHub (Feb 2, 2026): > I wish the exit node could behave in a more configurable way: by default allow access to public addresses only, but allow NetBird settings (like networks and policies) to permit local access as specified. > I totally agree with you, i also think this shoud be a new issue. but something i just discovered and that may help you achieve what you want, is that you can create drop policies, but it can be created only with the API https://docs.netbird.io/api/resources/policies#create-a-policy
Author
Owner

@JCBird1012 commented on GitHub (Feb 21, 2026):

@heypete - you might be able to do what you want by strategically using a few DROP policies for - if the goal is just Internet access...

RFC1918:
    10.0.0.0/8
    172.16.0.0/12
    192.168.0.0/16

Netbird (CGNAT):
    100.64.0.0/16

In my opinion, exit nodes in Netbird are one of the biggest security footguns it has - the correct design should be: an exit node route should NOT override any ACPs or interact with ACPs in any way - it should just be a default route with all traffic dropped, and then allowed explicitly via ACPs - no immediate carte blanche 0.0.0.0/0 access. There needs to exist something like autogroup:internet within ACPs - it would be easy to say something like "exit nodes for these peers are just for Internet traffic, nothing else".

Exit nodes should be a routing-only concept, not a routing + ACP concept. Netbird has conflated the two for convenience, and doesn't make that clear via the UI. Exit node traffic should 100% still be subject to ACPs.
Yes, it might get confusing for users if they enable exit nodes and then have to manually allow traffic to the Internet via an ACP - but you want a little confusion over steamrolling existing ACPs just because a peer is allowed to use an exit node.

<!-- gh-comment-id:3938559641 --> @JCBird1012 commented on GitHub (Feb 21, 2026): @heypete - you might be able to do what you want by strategically using a few DROP policies for - if the goal is just Internet access... ``` RFC1918: 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 Netbird (CGNAT): 100.64.0.0/16 ``` In my opinion, exit nodes in Netbird are one of the biggest security footguns it has - the correct design should be: an exit node route should NOT override any ACPs or interact with ACPs in any way - it should just be a default route with all traffic dropped, and then allowed explicitly via ACPs - no immediate carte blanche `0.0.0.0/0` access. There needs to exist something like [`autogroup:internet`](https://tailscale.com/docs/reference/targets-and-selectors#autogroupinternet) within ACPs - it would be easy to say something like "exit nodes for these peers are just for Internet traffic, nothing else". Exit nodes should be a routing-only concept, not a routing + ACP concept. Netbird has conflated the two for convenience, and doesn't make that clear via the UI. **Exit node traffic should 100% still be subject to ACPs.** Yes, it might get confusing for users if they enable exit nodes and then have to manually allow traffic to the Internet via an ACP - but you want a little confusion over steamrolling existing ACPs just because a peer is allowed to use an exit node.
Author
Owner

@fuomag9 commented on GitHub (Mar 22, 2026):

I have the same issue, exit node is definitely not working correctly with access control groups

<!-- gh-comment-id:4105725666 --> @fuomag9 commented on GitHub (Mar 22, 2026): I have the same issue, exit node is definitely not working correctly with access control groups
Author
Owner

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

same issue on my side, exit node with ACL does not work

<!-- gh-comment-id:4214203789 --> @NaolShow commented on GitHub (Apr 9, 2026): same issue on my side, exit node with ACL does not work
Author
Owner

@kyuuk commented on GitHub (Apr 10, 2026):

@araemo, you may be doing the same mistake as me,

i didn't understand the purpose of this field correctly, had to read & reread the documentation for that.

i was putting the source group in that field (assuming that it meant that only that group can access this exit-node)

but what should be set in that field is a group that should be used as a destination in the Access Control Policies while having a policy that allow traffic from a source group to this group to be able to route traffic

did you read this ?

<!-- gh-comment-id:4227294648 --> @kyuuk commented on GitHub (Apr 10, 2026): > [@araemo](https://github.com/araemo), you may be doing the same mistake as me, > > i didn't understand the purpose of this field correctly, had to read & reread the documentation for that. > > i was putting the source group in that field (assuming that it meant that only that group can access this exit-node) > > but what should be set in that field is a group that should be used as a **destination** in the `Access Control` Policies while having a policy that allow traffic from a source group to this group to be able to route traffic did you read this ?
Author
Owner

@NaolShow commented on GitHub (Apr 11, 2026):

@araemo, you may be doing the same mistake as me,
i didn't understand the purpose of this field correctly, had to read & reread the documentation for that.
i was putting the source group in that field (assuming that it meant that only that group can access this exit-node)
but what should be set in that field is a group that should be used as a destination in the Access Control Policies while having a policy that allow traffic from a source group to this group to be able to route traffic

did you read this ?

my bad, I've crossed read and did not see that.. Configuration is not intuitive but it works perfectly now, thank you!

<!-- gh-comment-id:4229352433 --> @NaolShow commented on GitHub (Apr 11, 2026): > > [@araemo](https://github.com/araemo), you may be doing the same mistake as me, > > i didn't understand the purpose of this field correctly, had to read & reread the documentation for that. > > i was putting the source group in that field (assuming that it meant that only that group can access this exit-node) > > but what should be set in that field is a group that should be used as a **destination** in the `Access Control` Policies while having a policy that allow traffic from a source group to this group to be able to route traffic > > did you read this ? my bad, I've crossed read and did not see that.. Configuration is not intuitive but it works perfectly now, thank you!
Author
Owner

@fuomag9 commented on GitHub (Apr 13, 2026):

@araemo, you may be doing the same mistake as me,
i didn't understand the purpose of this field correctly, had to read & reread the documentation for that.
i was putting the source group in that field (assuming that it meant that only that group can access this exit-node)
but what should be set in that field is a group that should be used as a destination in the Access Control Policies while having a policy that allow traffic from a source group to this group to be able to route traffic

did you read this ?

my bad, I've crossed read and did not see that.. Configuration is not intuitive but it works perfectly now, thank you!

For me it works but breaks after one day, which is kinda weird...

<!-- gh-comment-id:4240056559 --> @fuomag9 commented on GitHub (Apr 13, 2026): > > > [@araemo](https://github.com/araemo), you may be doing the same mistake as me, > > > i didn't understand the purpose of this field correctly, had to read & reread the documentation for that. > > > i was putting the source group in that field (assuming that it meant that only that group can access this exit-node) > > > but what should be set in that field is a group that should be used as a **destination** in the `Access Control` Policies while having a policy that allow traffic from a source group to this group to be able to route traffic > > > > > > did you read this ? > > my bad, I've crossed read and did not see that.. Configuration is not intuitive but it works perfectly now, thank you! For me it works but breaks after one day, which is kinda weird...
Sign in to join this conversation.
No Label triage-needed
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: DYNR/netbird#10573