[GH-ISSUE #3430] [Feature request] Improve speed when one peer is behind NAT #7227

Closed
opened 2026-08-05 01:12:06 -04:00 by saavagebueno · 4 comments
Owner

Originally created by @hotfur on GitHub (Mar 4, 2025).
Original GitHub issue: https://github.com/netbirdio/netbird/issues/3430

Is your feature request related to a problem? Please describe.
When both peer have public IP addresses, they obviously can directly connect to each other and the speed would be very high. However, when one of the peer (let's call it Public peer) have public IP address with open ports but the other (let's call this one NATed peer) do not because it is behind a NAT without access to port forwarding for example, then NetBird fallback into relay mode. This cause an unnecessary load on NetBird relay servers and an abysmal speed (average 7Mbps) for both peers.

Describe the solution you'd like
Relay servers should be used only when both peers do not have access to port forwarding/DMZ settings. When there is a Public peer, the NATed peer should connect to the open ports and set up PersistentKeepalive in Wireguard config to traverse NAT. The public peer would then have the Endpoint field in Wireguard config wildcarded, so as to allow the NATed peer more flexibility in making the connection.

Doing this would make the speed go up to the limit of the connection, for me it is nearly 300Mbps.

Describe alternatives you've considered
It is unlikely that there is any other alternatives.

Additional context
Nope.

Originally created by @hotfur on GitHub (Mar 4, 2025). Original GitHub issue: https://github.com/netbirdio/netbird/issues/3430 **Is your feature request related to a problem? Please describe.** When both peer have public IP addresses, they obviously can directly connect to each other and the speed would be very high. However, when one of the peer (let's call it Public peer) have public IP address with open ports but the other (let's call this one NATed peer) do not because it is behind a NAT without access to port forwarding for example, then NetBird fallback into relay mode. This cause an unnecessary load on NetBird relay servers and an abysmal speed (average 7Mbps) for both peers. **Describe the solution you'd like** Relay servers should be used only when both peers do not have access to port forwarding/DMZ settings. When there is a Public peer, the NATed peer should connect to the open ports and set up PersistentKeepalive in Wireguard config to traverse NAT. The public peer would then have the Endpoint field in Wireguard config wildcarded, so as to allow the NATed peer more flexibility in making the connection. Doing this would make the speed go up to the limit of the connection, for me it is nearly 300Mbps. **Describe alternatives you've considered** It is unlikely that there is any other alternatives. **Additional context** Nope.
saavagebueno added the feature-request label 2026-08-05 01:12:06 -04:00
Author
Owner

@Gauss23 commented on GitHub (Mar 4, 2025):

I can't really verify your problem. For me it works perfectly as long as one side is reachable directly. Only when both sides are behind NAT the connection switches to relayed.

<!-- gh-comment-id:2698787869 --> @Gauss23 commented on GitHub (Mar 4, 2025): I can't really verify your problem. For me it works perfectly as long as one side is reachable directly. Only when both sides are behind NAT the connection switches to relayed.
Author
Owner

@1nerdyguy commented on GitHub (Mar 5, 2025):

Pretty sure this is exactly how it functions, already?

What you're running into, to my understanding, is a non-friendly NAT.

Basically, host A registers with the Management server that "Hey, I'm available on IP:PORT if anyone wants to talk".
HOst B Registers the same info, and goes "crap yeah, I wanna talk to HostA!"

The problem is, HOST A's nat is setup so all communication must initiate from HOST A before it will allow any traffic back inside. Since Host A has no idea that Host B wants to talk to it, Host B has no way to get traffic direct to Host A.

Hence the relay serving as a middle man.

While I hate using other products as descriptions, Tailscale did a fantastic blog on this that goes much further in depth. https://tailscale.com/blog/how-nat-traversal-works

<!-- gh-comment-id:2700923897 --> @1nerdyguy commented on GitHub (Mar 5, 2025): Pretty sure this is exactly how it functions, already? What you're running into, to my understanding, is a non-friendly NAT. Basically, host A registers with the Management server that "Hey, I'm available on IP:PORT if anyone wants to talk". HOst B Registers the same info, and goes "crap yeah, I wanna talk to HostA!" The problem is, HOST A's nat is setup so all communication must initiate from HOST A before it will allow any traffic back inside. Since Host A has no idea that Host B wants to talk to it, Host B has no way to get traffic direct to Host A. Hence the relay serving as a middle man. While I hate using other products as descriptions, Tailscale did a fantastic blog on this that goes much further in depth. https://tailscale.com/blog/how-nat-traversal-works
Author
Owner

@Gauss23 commented on GitHub (Mar 5, 2025):

@1nerdyguy thank you for the link. Great read! Very interesting.

<!-- gh-comment-id:2701395948 --> @Gauss23 commented on GitHub (Mar 5, 2025): @1nerdyguy thank you for the link. Great read! Very interesting.
Author
Owner

@hotfur commented on GitHub (Mar 5, 2025):

I forgot to allow incoming UDP traffic on the default wireguard port 51820, hence relay must be used. I added the required rule (or change the default port using --wireguard-port flag) and it worked properly.
Thanks @Gauss23 for you confirmation, which helped me to find the misconfiguration. @1nerdyguy I will read your article later, thanks for suggesting.

<!-- gh-comment-id:2701822663 --> @hotfur commented on GitHub (Mar 5, 2025): I forgot to allow incoming UDP traffic on the default wireguard port 51820, hence relay must be used. I added the required rule (or change the default port using --wireguard-port flag) and it worked properly. Thanks @Gauss23 for you confirmation, which helped me to find the misconfiguration. @1nerdyguy I will read your article later, thanks for suggesting.
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#7227