- Add WireguardPort option to embed.Options for custom port configuration
- Fix KernelInterface detection to account for netstack mode
- Skip SSH config updates when running in netstack mode
- Skip interface removal wait when running in netstack mode
- Use BindListener for netstack to avoid port conflicts on same host
* Add IPv6 support to UDP WireGuard proxy
Add IPv6 packet header support in UDP raw socket proxy
to handle both IPv4 and IPv6 source addresses.
Refactor error handling in proxy bind implementations
to validate endpoints before acquiring locks.
* [client] Add WGConfigurer interface
To allow Rosenpass to work both with kernel
WireGuard via wgctrl (default behavior) and
userspace WireGuard via IPC on Android/iOS
using WGUSPConfigurer
* [client] Remove Rosenpass debug logs
* [client] Return simpler peer configuration in outputKey method
ConfigureDevice, the method previously used in
outputKey via wgClient to update the device's
properties, is now defined in the WGConfigurer
interface and implemented both in kernel_unix and
usp configurers.
PresharedKey datatype was also changed from
boolean to [32]byte to compare it
to the original NetBird PSK, so that Rosenpass
may replace it with its own when necessary.
* [client] Remove unused field
* [client] Replace usage of WGConfigurer
Replaced with preshared key setter interface,
which only defines a method to set / update the preshared key.
Logic has been migrated from rosenpass/netbird_handler to client/iface.
* [client] Use same default peer keepalive value when setting preshared keys
* [client] Store PresharedKeySetter iface in rosenpass manager
To avoid no-op if SetInterface is called before generateConfig
* [client] Add mutex usage in rosenpass netbird handler
* [client] change implementation setting Rosenpass preshared key
Instead of providing a method to configure a device (device/interface.go),
it forwards the new parameters to the configurer (either
kernel_unix.go / usp.go).
This removes dependency on reading FullStats, and makes use of a common
method (buildPresharedKeyConfig in configurer/common.go) to build a
minimal WG config that only sets/updates the PSK.
netbird_handler.go now keeps s list of initializedPeers to choose whether
to set the value of "UpdateOnly" when calling iface.SetPresharedKey.
* [client] Address possible race condition
Between outputKey calls and peer removal; it
checks again if the peer still exists in the
peers map before inserting it in the
initializedPeers map.
* [client] Add psk Rosenpass-initialized check
On client/internal/peer/conn.go, the presharedKey
function would always return the current key
set in wgConfig.presharedKey.
This would eventually overwrite a key set
by Rosenpass if the feature is active.
The purpose here is to set a handler that will
check if a given peer has its psk initialized
by Rosenpass to skip updating the psk
via updatePeer (since it calls presharedKey
method in conn.go).
* Add missing updateOnly flag setup for usp peers
* Change common.go buildPresharedKeyConfig signature
PeerKey datatype changed from string to
wgTypes.Key. Callers are responsible for parsing
a peer key with string datatype.
* updates to client file writing
* numerous
* minor
* - Align OnLoginSuccess behavior with Android (only call on nil error)
- Remove verbose debug logging from WaitToken in device_flow.go
- Improve TUN FD=0 fallback comments and warning messages
- Document why config save after login differs from Android
* Add nolint directive for staticcheck SA1029 in login.go
* Fix CodeRabbit review issues for iOS/tvOS SDK
- Remove goroutine from OnLoginSuccess callback, invoke synchronously
- Stop treating PermissionDenied as success, propagate as permanent error
- Replace context.TODO() with bounded timeout context (30s) in RequestAuthInfo
- Handle DirectUpdateOrCreateConfig errors in IsLoginRequired and LoginForMobile
- Add permission enforcement to DirectUpdateOrCreateConfig for existing configs
- Fix variable shadowing in device_ios.go where err was masked by := in else block
* Address additional CodeRabbit review issues for iOS/tvOS SDK
- Make tunFd == 0 a hard error with exported ErrInvalidTunnelFD (remove dead fallback code)
- Apply defaults in ConfigFromJSON to prevent partially-initialized configs
- Add nil guards for listener/urlOpener interfaces in public SDK entry points
- Reorder config save before OnLoginSuccess to prevent teardown race
- Add explanatory comment for urlOpener.Open goroutine
* Make urlOpener.Open() synchronous in device auth flow
* When a peer disconnects, remove the endpoint address to avoid sending traffic to a non-existent address, but retain the status for the activity recorder.
The Relayed connection setup is optimistic. It does not have any confirmation of an established end-to-end connection. Peers start sending WireGuard handshake packets immediately after the successful offer-answer handshake.
Meanwhile, for successful P2P connection negotiation, we change the WireGuard endpoint address, but this change does not trigger new handshake initiation. Because the peer switched from Relayed connection to P2P, the packets from the Relay server are dropped and must wait for the next WireGuard handshake via P2P.
To avoid this scenario, the relayed WireGuard proxy no longer drops the packets. Instead, it rewrites the source address to the new P2P endpoint and continues forwarding the packets.
We still have one corner case: if the Relayed server negotiation chooses a server that has not been used before. In this case, one side of the peer connection will be slower to reach the Relay server, and the Relay server will drop the handshake packet.
If everything goes well we should see exactly 5 seconds improvements between the WireGuard configuration time and the handshake time.
- Move `util/grpc` and `util/net` to `client` so `internal` packages can be accessed
- Add methods to return the next best interface after the NetBird interface.
- Use `IP_UNICAST_IF` sock opt to force the outgoing interface for the NetBird `net.Dialer` and `net.ListenerConfig` to avoid routing loops. The interface is picked by the new route lookup method.
- Some refactoring to avoid import cycles
- Old behavior is available through `NB_USE_LEGACY_ROUTING=true` env var
Deduplicate STUN package sending.
Originally, because every peer shared the same UDP address, the library could not distinguish which STUN message was associated with which candidate. As a result, the Pion library responded from all candidates for every STUN message.
This will allow running netbird commands (including debugging) against the daemon and provide a flow similar to non-container usages.
It will by default both log to file and stderr so it can be handled more uniformly in container-native environments.
- Clients now subscribe to peer status changes.
- The server manages and maintains these subscriptions.
- Replaced raw string peer IDs with a custom peer ID type for better type safety and clarity.
This PR introduces a new inactivity package responsible for monitoring peer activity and notifying when peers become inactive.
Introduces a new Signal message type to close the peer connection after the idle timeout is reached.
Periodically checks the last activity of registered peers via a Bind interface.
Notifies via a channel when peers exceed a configurable inactivity threshold.
Default settings
DefaultInactivityThreshold is set to 15 minutes, with a minimum allowed threshold of 1 minute.
Limitations
This inactivity check does not support kernel WireGuard integration. In kernel–user space communication, the user space side will always be responsible for closing the connection.
With the lazy connection feature, the peer will connect to target peers on-demand. The trigger can be any IP traffic.
This feature can be enabled with the NB_ENABLE_EXPERIMENTAL_LAZY_CONN environment variable.
When the engine receives a network map, it binds a free UDP port for every remote peer, and the system configures WireGuard endpoints for these ports. When traffic appears on a UDP socket, the system removes this listener and starts the peer connection procedure immediately.
Key changes
Fix slow netbird status -d command
Move from engine.go file to conn_mgr.go the peer connection related code
Refactor the iface interface usage and moved interface file next to the engine code
Add new command line flag and UI option to enable feature
The peer.Conn struct is reusable after it has been closed.
Change connection states
Connection states
Idle: The peer is not attempting to establish a connection. This typically means it's in a lazy state or the remote peer is expired.
Connecting: The peer is actively trying to establish a connection. This occurs when the peer has entered an active state and is continuously attempting to reach the remote peer.
Connected: A successful peer-to-peer connection has been established and communication is active.
updates the logging implementation to use the netbird logger for both ICE and gRPC components. The key changes include:
- Introducing a gRPC logger configuration in util/log.go that integrates with the netbird logging setup.
- Updating the log hook in formatter/hook/hook.go to ensure a default caller is used when not set.
- Refactoring ICE agent and UDP multiplexers to use a unified logger via the new getLogger() method.
adds NetFlow functionality to track and log network traffic information between peers, with features including:
- Flow logging for TCP, UDP, and ICMP traffic
- Integration with connection tracking system
- Resource ID tracking in NetFlow events
- DNS and exit node collection configuration
- Flow API and Redis cache in management
- Memory-based flow storage implementation
- Kernel conntrack counters and userspace counters
- TCP state machine improvements for more accurate tracking
- Migration from net.IP to netip.Addr in the userspace firewall
- When a peer is connected with TURN and a Relay connection is established, do not force switching to Relay. Keep using TURN until disconnection.
-In the proxy preparation phase, the Bind Proxy does not set the remote conn as a fake address for Bind. When running the Work() function, the proper proxy instance updates the conn inside the Bind.