[GH-ISSUE #4936] Allow traffic from Network Resource to Netbird Clients #10391

Open
opened 2026-08-05 01:25:44 -04:00 by saavagebueno · 15 comments
Owner

Originally created by @osunit on GitHub (Dec 11, 2025).
Original GitHub issue: https://github.com/netbirdio/netbird/issues/4936

Is your feature request related to a problem? Please describe.
I can't route traffic from an internal resource (no netbird client installed) to a netbird client using a subnet router

Describe the solution you'd like
A feature which allows routing of traffic from an internal resource to a netbird client via a subnet router

Describe alternatives you've considered
Putting the internal resource into AWS so that it can have the netbird client installed.
We have tried to install the Netbird client onto the internal resource however this does not work for us as U-TURN NAT does not work.

@stan-smith

Originally created by @osunit on GitHub (Dec 11, 2025). Original GitHub issue: https://github.com/netbirdio/netbird/issues/4936 **Is your feature request related to a problem? Please describe.** I can't route traffic from an internal resource (no netbird client installed) to a netbird client using a subnet router **Describe the solution you'd like** A feature which allows routing of traffic from an internal resource to a netbird client via a subnet router **Describe alternatives you've considered** Putting the internal resource into AWS so that it can have the netbird client installed. We have tried to install the Netbird client onto the internal resource however this does not work for us as U-TURN NAT does not work. @stan-smith
saavagebueno added the feature-request label 2026-08-05 01:25:44 -04:00
Author
Owner

@mpoonuru commented on GitHub (Dec 11, 2025):

Same issue.

<!-- gh-comment-id:3642582233 --> @mpoonuru commented on GitHub (Dec 11, 2025): Same issue.
Author
Owner

@Gauss23 commented on GitHub (Dec 13, 2025):

That's where I was struggling, too. This was working in the past. It works with Masquerading/NAT, but I don't want to NAT. I want to see the real IP.
My setup:

  • OPNsense with Netbird 0.59.8, offering a network (i.e. 10.10.1.0/24)
  • VPS with Netbird client, 0.60.7, without any other networks to route

The VPS gets the route and is able to ping ressouces in the 10.10.1.0/24 network directly.
But the other way around simply won't work. I can see the packets on the OPNsense leaving through the wt0 interface, all looks fine. When I enable NAT for this connection, it starts to work. But at the cost, that I don't see the real client IP on the VPS, only the 100.x address from the OPNsense.

Tried both ways: Network routes and networks.

And there is no policy option to select the network resource as source, only as destination. Maybe that's the missing piece in the puzzle?

<!-- gh-comment-id:3649294142 --> @Gauss23 commented on GitHub (Dec 13, 2025): That's where I was struggling, too. This was working in the past. It works with Masquerading/NAT, but I don't want to NAT. I want to see the real IP. My setup: - OPNsense with Netbird 0.59.8, offering a network (i.e. 10.10.1.0/24) - VPS with Netbird client, 0.60.7, without any other networks to route The VPS gets the route and is able to ping ressouces in the 10.10.1.0/24 network directly. But the other way around simply won't work. I can see the packets on the OPNsense leaving through the wt0 interface, all looks fine. When I enable NAT for this connection, it starts to work. But at the cost, that I don't see the real client IP on the VPS, only the 100.x address from the OPNsense. Tried both ways: Network routes and networks. And there is no policy option to select the network resource as source, only as destination. Maybe that's the missing piece in the puzzle?
Author
Owner

@Fr0g-Not-Found commented on GitHub (Dec 13, 2025):

Same issue, we set up a route to the routing peer for the subnet the netbird clients use... but avail. This is with mascaraing disabled for the specific network resource vlan... We need to respond to the IP we receive the request from, its sent to a different udp port than the original request is sent at.

<!-- gh-comment-id:3649969732 --> @Fr0g-Not-Found commented on GitHub (Dec 13, 2025): Same issue, we set up a route to the routing peer for the subnet the netbird clients use... but avail. This is with mascaraing disabled for the specific network resource vlan... We need to respond to the IP we receive the request from, its sent to a different udp port than the original request is sent at.
Author
Owner

@KingSteve032 commented on GitHub (Dec 23, 2025):

I'm currently using the 0.59.5 client on the users that need resources to be able to reach them. Apparently it was a bug which allowed resources to reach vpn clients direct and got fixed in a newer release.

<!-- gh-comment-id:3686455837 --> @KingSteve032 commented on GitHub (Dec 23, 2025): I'm currently using the 0.59.5 client on the users that need resources to be able to reach them. Apparently it was a bug which allowed resources to reach vpn clients direct and got fixed in a newer release.
Author
Owner

@Gauss23 commented on GitHub (Dec 23, 2025):

Maybe that was a bug in the past but there should be a flag or option to re-enable that on peer-level. It’s a missing function at the moment

<!-- gh-comment-id:3686509426 --> @Gauss23 commented on GitHub (Dec 23, 2025): Maybe that was a bug in the past but there should be a flag or option to re-enable that on peer-level. It’s a missing function at the moment
Author
Owner

@gamerslouis commented on GitHub (Jan 22, 2026):

After analyzing the code, I found that PR https://github.com/netbirdio/netbird/pull/4653, released in v0.59.7, removed client-side ACL rule squashing, which had previously caused network resources to be able to access the NetBird client in certain edge cases.

<!-- gh-comment-id:3782685895 --> @gamerslouis commented on GitHub (Jan 22, 2026): After analyzing the code, I found that PR https://github.com/netbirdio/netbird/pull/4653, released in v0.59.7, removed client-side ACL rule squashing, which had previously caused network resources to be able to access the NetBird client in certain edge cases.
Author
Owner

@KingSteve032 commented on GitHub (Jan 22, 2026):

After analyzing the code, I found that PR https://github.com/netbirdio/netbird/pull/4653, released in v0.59.7, removed client-side ACL rule squashing, which had previously caused network resources to be able to access the NetBird client in certain edge cases.

Yep, 59.7 is when started running into issues with how I had stuff setup.

<!-- gh-comment-id:3783804729 --> @KingSteve032 commented on GitHub (Jan 22, 2026): > After analyzing the code, I found that PR https://github.com/netbirdio/netbird/pull/4653, released in v0.59.7, removed client-side ACL rule squashing, which had previously caused network resources to be able to access the NetBird client in certain edge cases. > Yep, 59.7 is when started running into issues with how I had stuff setup.
Author
Owner

@gamerslouis commented on GitHub (Jan 22, 2026):

an acceptable approach we have considered is to disable the NetBird Agent’s firewall functionality and delegate security control back to iptables.

<!-- gh-comment-id:3783832045 --> @gamerslouis commented on GitHub (Jan 22, 2026): an acceptable approach we have considered is to disable the NetBird Agent’s firewall functionality and delegate security control back to iptables.
Author
Owner

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

I'll be honest. I would actually consider this a bug, rather than whatever the original "bugfix" tried to fix.

My whole homelab network is basically unusable now, I'll need to rollback several machines.

And I have like 20 machines connected through it. (Multiple friends that have their own homelab) all connected together, which means it's also all non-commercial and is burning through my time and non-existent money...

Great. Just Great. Oh well, another software that is going to get privately forked and probably never gonna get updated again until i feel like it

<!-- gh-comment-id:3837556619 --> @mempler commented on GitHub (Feb 2, 2026): I'll be honest. I would actually consider this a bug, rather than whatever the original "bugfix" tried to fix. My whole homelab network is basically unusable now, I'll need to rollback several machines. And I have like 20 machines connected through it. (Multiple friends that have their own homelab) all connected together, which means it's also all non-commercial and is burning through my time and non-existent money... Great. Just Great. Oh well, another software that is going to get privately forked and probably never gonna get updated again until i feel like it
Author
Owner

@ByteHD commented on GitHub (Feb 3, 2026):

Can confirm the same issue after hours of debugging: the removal of client-side ACL rule squashing broke routing for this use case.

Disabling firewall restores routing but bypasses all ACL policies, which creates potential security issues and likely renders policies from the panel ineffective.

Linux workaround:

  • Edit /var/lib/netbird/default.json
  • Set "DisableFirewall": true
  • Restart NetBird client

(tested on v0.64.4)

A fix should allow bidirectional traffic through subnet routers while maintaining ACL security, without requiring firewall disabling on every client because thats not sustainable imo.

<!-- gh-comment-id:3842836780 --> @ByteHD commented on GitHub (Feb 3, 2026): Can confirm the same issue after hours of debugging: the removal of client-side ACL rule squashing broke routing for this use case. Disabling firewall restores routing but bypasses all ACL policies, which creates potential security issues and likely renders policies from the panel ineffective. **Linux workaround:** - Edit `/var/lib/netbird/default.json` - Set `"DisableFirewall": true` - Restart NetBird client (tested on v0.64.4) A fix should allow bidirectional traffic through subnet routers while maintaining ACL security, without requiring firewall disabling on every client because thats not sustainable imo.
Author
Owner

@Fr0g-Not-Found commented on GitHub (Feb 3, 2026):

Can confirm the same issue after hours of debugging: the removal of client-side ACL rule squashing broke routing for this use case.

Disabling firewall restores routing but bypasses all ACL policies, which creates potential security issues and likely renders policies from the panel ineffective.

Linux workaround:

  • Edit /var/lib/netbird/default.json
  • Set "DisableFirewall": true
  • Restart NetBird client

(tested on v0.64.4)

A fix should allow bidirectional traffic through subnet routers while maintaining ACL security, without requiring firewall disabling on every client because thats not sustainable imo.

Agreed. I'm also impacted, same results.

<!-- gh-comment-id:3842910475 --> @Fr0g-Not-Found commented on GitHub (Feb 3, 2026): > Can confirm the same issue after hours of debugging: the removal of client-side ACL rule squashing broke routing for this use case. > > Disabling firewall restores routing but bypasses all ACL policies, which creates potential security issues and likely renders policies from the panel ineffective. > > **Linux workaround:** > > * Edit `/var/lib/netbird/default.json` > * Set `"DisableFirewall": true` > * Restart NetBird client > > (tested on v0.64.4) > > A fix should allow bidirectional traffic through subnet routers while maintaining ACL security, without requiring firewall disabling on every client because thats not sustainable imo. Agreed. I'm also impacted, same results.
Author
Owner

@KingSteve032 commented on GitHub (Mar 5, 2026):

an acceptable approach we have considered is to disable the NetBird Agent’s firewall functionality and delegate security control back to iptables.

Do you know if there is any plans to allow resources and other traffic to reach out to a vpn client?

<!-- gh-comment-id:4006166057 --> @KingSteve032 commented on GitHub (Mar 5, 2026): > an acceptable approach we have considered is to disable the NetBird Agent’s firewall functionality and delegate security control back to iptables. Do you know if there is any plans to allow resources and other traffic to reach out to a vpn client?
Author
Owner

@KingSteve032 commented on GitHub (Apr 20, 2026):

@jnfrati do you think we could get something like this added in the future? I would like to update my group past 0.59.5 since the network based hf radios doesn't work past that version. They have to be the one that starts the traffic flow for them to work properly. I know other people in this feature request would like it as well.

<!-- gh-comment-id:4285485357 --> @KingSteve032 commented on GitHub (Apr 20, 2026): @jnfrati do you think we could get something like this added in the future? I would like to update my group past 0.59.5 since the network based hf radios doesn't work past that version. They have to be the one that starts the traffic flow for them to work properly. I know other people in this feature request would like it as well.
Author
Owner

@notherealmarco commented on GitHub (May 23, 2026):

I hope this is going to be addressed soon by netbird team as I think that being able to set up site2vpn and site2site without NAT is important.

Meanwhile, I developed a script that inserts a rule at the top of the netbird table as soon as netbird removes it (when netbird restarts) allowing incoming traffic from one or more specified subnets. I attached the script at the end of this comment


Anyway, I think this should be manageable from the netbird dashboard and it should be able to define ACLs where the source is a network resource.

If masquerading is enabled, then the netbird client should install both source and destination nat rules (which may already be the case, I didn't test as I don't use masquerade at all)

Otherwise, if masquerade is disabled, it could be designed in two ways.
Here, we assume a site2vpn scenario where a host Alice (that does not run netbird) wants to reach the peer Bob, and we also assume that an ACL rule allows Alice (either her IP or her subnet) to reach Bob:

  1. Bob can reach Alice's IP (it is allowed from ACL), then the border gateway should forward the packets to Bob without performing any NAT (current beavior), and Bob's firewall should allow packets from Alice as defined in the ACL

  2. Bob can not reach Alice's IP (not allowed from ACL). In this case, with the current behavior no route is installed on Bob. So if the border router forwards packets from Alice to Bob, then Bob wouldn't be able to forward them back. This can be solved in two ways:

  3. if someone should be able to reach Bob, then Bob should have a route installed to be able to reply. But then if Bob initiates the connection first, the border router's firewall should drop the packets. So we are compliant with the ACL

  4. otherwise, this could be solved by using NAT. So only in this case, the border router could source-nat the IP of Alice, so Bob thinks the traffic is coming from the border router and will be able to reply. This approach will work but may break some applications that expect the real IP address, also, it still performs masquerading even if the option is disabled. So probably approach 1 makes more sense here (?)

I think this can also be easily applied to site2site scenarios, allowing ACL rules to have network resources to be configured both as a source and as a destination.

Anyway, here is my script. This runs on the peer that should be reachable from a host. In the following example, when this is executed on a peer, any host from 192.168.188.0/24 can initiate connections to that peer, without NAT. This of course assumes that masquerade is disabled for that subnet in the netbird control plane.

script:

#!/bin/bash

# Define your subnets inside the array (space or newline separated)
RULE_SUBNETS=(
    "192.168.188.0/24"
)

inject_rules() {
    # Small delay to ensure NetBird finishes its flush/rebuild cycle
    sleep 0.5

    # Cache current chain state to minimize redundant subshell execution inside the loop
    local current_rules
    current_rules=$(nft list chain ip netbird netbird-acl-input-rules 2>/dev/null)

    for subnet in "${RULE_SUBNETS[@]}"; do
        if ! echo "$current_rules" | grep -q "$subnet accept"; then
            nft insert rule ip netbird netbird-acl-input-rules ip saddr "$subnet" accept 2>/dev/null
        fi
    done
}

# Inject immediately on script startup in case NetBird is already up
inject_rules

# Continuously monitor nftables lifecycle events via netlink
nft monitor | while read -r line; do
    if echo "$line" | grep -q "netbird-acl-input-rules"; then
        inject_rules
    fi
done

systemd service (assumes you placed the script in /opt/netbird-fw-hook.sh and gave execution permissions to it):

[Unit]
Description=NetBird NFTables Rule Persistence Hook
After=network.target

[Service]
Type=simple
ExecStart=/opt/netbird-fw-hook.sh
Restart=always
RestartSec=2

[Install]
WantedBy=multi-user.target
<!-- gh-comment-id:4525799909 --> @notherealmarco commented on GitHub (May 23, 2026): I hope this is going to be addressed soon by netbird team as I think that being able to set up site2vpn and site2site without NAT is important. Meanwhile, I developed a script that inserts a rule at the top of the netbird table as soon as netbird removes it (when netbird restarts) allowing incoming traffic from one or more specified subnets. I attached the script at the end of this comment --- Anyway, I think this should be manageable from the netbird dashboard and it should be able to define ACLs where the source is a network resource. If masquerading is **enabled**, then the netbird client should install both source and destination nat rules (which may already be the case, I didn't test as I don't use masquerade at all) Otherwise, if masquerade is **disabled**, it could be designed in two ways. Here, we assume a site2vpn scenario where a host Alice (that does not run netbird) wants to reach the peer Bob, and we also assume that an ACL rule allows Alice (either her IP or her subnet) to reach Bob: 1. Bob can reach Alice's IP (it is allowed from ACL), then the border gateway should forward the packets to Bob without performing any NAT (current beavior), and Bob's firewall should allow packets from Alice as defined in the ACL 2. Bob can **not** reach Alice's IP (not allowed from ACL). In this case, with the current behavior no route is installed on Bob. So if the border router forwards packets from Alice to Bob, then Bob wouldn't be able to forward them back. This can be solved in two ways: 1. if someone should be able to reach Bob, then Bob should have a route installed to be able to reply. But then if Bob initiates the connection first, the border router's firewall should drop the packets. So we are compliant with the ACL 2. otherwise, this could be solved by using NAT. So only in this case, the border router could source-nat the IP of Alice, so Bob thinks the traffic is coming from the border router and will be able to reply. This approach will work but may break some applications that expect the real IP address, also, it still performs masquerading even if the option is disabled. So probably approach 1 makes more sense here (?) I think this can also be easily applied to site2site scenarios, allowing ACL rules to have network resources to be configured both as a source and as a destination. Anyway, here is my script. This runs on the peer that should be reachable from a host. In the following example, when this is executed on a peer, any host from `192.168.188.0/24` can initiate connections to that peer, without NAT. This of course assumes that masquerade is disabled for that subnet in the netbird control plane. script: ``` #!/bin/bash # Define your subnets inside the array (space or newline separated) RULE_SUBNETS=( "192.168.188.0/24" ) inject_rules() { # Small delay to ensure NetBird finishes its flush/rebuild cycle sleep 0.5 # Cache current chain state to minimize redundant subshell execution inside the loop local current_rules current_rules=$(nft list chain ip netbird netbird-acl-input-rules 2>/dev/null) for subnet in "${RULE_SUBNETS[@]}"; do if ! echo "$current_rules" | grep -q "$subnet accept"; then nft insert rule ip netbird netbird-acl-input-rules ip saddr "$subnet" accept 2>/dev/null fi done } # Inject immediately on script startup in case NetBird is already up inject_rules # Continuously monitor nftables lifecycle events via netlink nft monitor | while read -r line; do if echo "$line" | grep -q "netbird-acl-input-rules"; then inject_rules fi done ``` systemd service (assumes you placed the script in `/opt/netbird-fw-hook.sh` and gave execution permissions to it): ``` [Unit] Description=NetBird NFTables Rule Persistence Hook After=network.target [Service] Type=simple ExecStart=/opt/netbird-fw-hook.sh Restart=always RestartSec=2 [Install] WantedBy=multi-user.target ```
Author
Owner

@KingSteve032 commented on GitHub (May 23, 2026):

Following their new processes for requesting features and reporting bugs I've made a discussion post. Go upvote and comment there. https://github.com/netbirdio/netbird/discussions/6186

<!-- gh-comment-id:4526482972 --> @KingSteve032 commented on GitHub (May 23, 2026): Following their new processes for requesting features and reporting bugs I've made a discussion post. Go upvote and comment there. https://github.com/netbirdio/netbird/discussions/6186
Sign in to join this conversation.
No Label feature-request
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: DYNR/netbird#10391