From fb47824d749c214ac74115a92f89256c0ee51bf9 Mon Sep 17 00:00:00 2001 From: Jonathan Nobels Date: Tue, 1 Apr 2025 13:20:46 -0400 Subject: [PATCH] wgengine: return explicit lo0 for loopback addrs on sandboxed macOS (#15493) fixes tailscale/corp#27506 The source address link selection on sandboxed macOS doesn't deal with loopback addresses correctly. This adds an explicit check to ensure we return the loopback interface for loopback addresses instead of the default empty interface. Specifically, this allows the dns resolver to route queries to a loopback IP which is a common tactic for local DNS proxies. Tested on both macos, macsys and tailscaled. Forwarded requests to 127/8 all bound to lo0. Signed-off-by: Jonathan Nobels --- wgengine/userspace.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/wgengine/userspace.go b/wgengine/userspace.go index b51b2c8ea..1200003f6 100644 --- a/wgengine/userspace.go +++ b/wgengine/userspace.go @@ -1580,6 +1580,12 @@ type fwdDNSLinkSelector struct { } func (ls fwdDNSLinkSelector) PickLink(ip netip.Addr) (linkName string) { + // sandboxed macOS does not automatically bind to the loopback interface so + // we must be explicit about it. + if runtime.GOOS == "darwin" && ip.IsLoopback() { + return "lo0" + } + if ls.ue.isDNSIPOverTailscale.Load()(ip) { return ls.tunName }