From d438db50012b7abeeda0829c373abb0a41f0306e Mon Sep 17 00:00:00 2001 From: Viktor Liu Date: Tue, 14 Jul 2026 14:32:34 +0200 Subject: [PATCH] Run Rosenpass in permissive mode on the embedded proxy --- client/embed/embed.go | 7 ++++++ proxy/internal/roundtrip/netbird.go | 33 +++++++++++++++++++++++------ 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/client/embed/embed.go b/client/embed/embed.go index 99a6b8229..e3815eb3a 100644 --- a/client/embed/embed.go +++ b/client/embed/embed.go @@ -85,6 +85,11 @@ type Options struct { DisableIPv6 bool // BlockInbound blocks all inbound connections from peers BlockInbound bool + // EnableRosenpass enables the Rosenpass post-quantum key exchange. + EnableRosenpass bool + // RosenpassPermissive lets a Rosenpass-enabled peer still connect to peers + // that do not run Rosenpass (falling back to the plain WireGuard PSK). + RosenpassPermissive bool // BlockLANAccess blocks the embedded peer from reaching the host's // LAN (RFC 1918, link-local, loopback) when it's used as a routing // peer. Mirrors profilemanager.ConfigInput.BlockLANAccess. Useful @@ -203,6 +208,8 @@ func New(opts Options) (*Client, error) { DisableIPv6: &opts.DisableIPv6, BlockInbound: &opts.BlockInbound, BlockLANAccess: &opts.BlockLANAccess, + RosenpassEnabled: &opts.EnableRosenpass, + RosenpassPermissive: &opts.RosenpassPermissive, WireguardPort: opts.WireguardPort, MTU: opts.MTU, DNSLabels: parsedLabels, diff --git a/proxy/internal/roundtrip/netbird.go b/proxy/internal/roundtrip/netbird.go index cb2e7f930..ae3308a3e 100644 --- a/proxy/internal/roundtrip/netbird.go +++ b/proxy/internal/roundtrip/netbird.go @@ -30,6 +30,12 @@ import ( const deviceNamePrefix = "ingress-proxy-" +// envProxyRosenpass toggles Rosenpass (permissive) on the embedded proxy client. Defaults to on. +const envProxyRosenpass = "NB_PROXY_ROSENPASS" //nolint:gosec // env var name, not a credential + +// envProxyClientLogLevel sets the embedded NetBird client's log level. +const envProxyClientLogLevel = "NB_PROXY_CLIENT_LOG_LEVEL" + const clientStopTimeout = 30 * time.Second const createProxyPeerTimeout = 30 * time.Second @@ -353,11 +359,11 @@ func (n *NetBird) createClientEntry(ctx context.Context, accountID types.Account // NB_PROXY_CLIENT_LOG_LEVEL (e.g. "trace") to surface the embedded NetBird // client's relay / signal / handshake detail for local debugging. clientLogLevel := log.WarnLevel.String() - if v := strings.TrimSpace(os.Getenv("NB_PROXY_CLIENT_LOG_LEVEL")); v != "" { + if v := strings.TrimSpace(os.Getenv(envProxyClientLogLevel)); v != "" { if lvl, err := log.ParseLevel(v); err == nil { clientLogLevel = lvl.String() } else { - n.logger.Warnf("invalid NB_PROXY_CLIENT_LOG_LEVEL %q, using %q: %v", v, clientLogLevel, err) + n.logger.Warnf("invalid %s %q, using %q: %v", envProxyClientLogLevel, v, clientLogLevel, err) } } @@ -367,15 +373,26 @@ func (n *NetBird) createClientEntry(ctx context.Context, accountID types.Account } }) + // Rosenpass runs in permissive mode by default so the embedded proxy can + // establish connections with Rosenpass-enabled peers (which otherwise fail + // on a PSK mismatch) while still falling back to plain WireGuard for peers + // that do not run Rosenpass. Set NB_PROXY_ROSENPASS=false to disable it. + rosenpassEnabled := true + if v, ok := envBool(envProxyRosenpass, n.logger); ok { + rosenpassEnabled = v + } + // Create embedded NetBird client with the generated private key. // The peer has already been created via CreateProxyPeer RPC with the public key. wgPort := int(n.clientCfg.WGPort) embedOpts := embed.Options{ - DeviceName: deviceNamePrefix + n.proxyID, - ManagementURL: n.clientCfg.MgmtAddr, - PrivateKey: privateKey.String(), - LogLevel: clientLogLevel, - BlockInbound: n.clientCfg.BlockInbound, + DeviceName: deviceNamePrefix + n.proxyID, + ManagementURL: n.clientCfg.MgmtAddr, + PrivateKey: privateKey.String(), + LogLevel: clientLogLevel, + BlockInbound: n.clientCfg.BlockInbound, + EnableRosenpass: rosenpassEnabled, + RosenpassPermissive: rosenpassEnabled, // The embedded proxy peer must never be a stepping stone into // the proxy host's LAN: it only exists to reach NetBird mesh // targets or, when direct_upstream is set, the host network @@ -899,6 +916,8 @@ func logEmbedOptions(logger *log.Logger, accountID types.AccountID, serviceID ty "mtu": mtu, "block_inbound": opts.BlockInbound, "block_lan_access": opts.BlockLANAccess, + "rosenpass_enabled": opts.EnableRosenpass, + "rosenpass_permissive": opts.RosenpassPermissive, "disable_ipv6": opts.DisableIPv6, "disable_client_routes": opts.DisableClientRoutes, "no_userspace": opts.NoUserspace,