mirror of
https://github.com/tailscale/tailscale.git
synced 2025-12-01 17:49:02 +00:00
ipn/ipnlocal, net/netns: add node cap to disable netns interface binding on netext Apple clients
updates tailscale/corp#31571 It appears that on the latest macOS, iOS and tVOS versions, the work that netns is doing to bind outgoing connections to the default interface (and all of the trimmings and workarounds in netmon et al that make that work) are not needed. The kernel is extension-aware and doing nothing, is the right thing. This is, however, not the case for tailscaled (which is not a special process). To allow us to test this assertion (and where it might break things), we add a new node cap that turns this behaviour off only for network-extension equipped clients, making it possible to turn this off tailnet-wide, without breaking any tailscaled macos nodes. Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
This commit is contained in:
@@ -6177,9 +6177,10 @@ func (b *LocalBackend) setNetMapLocked(nm *netmap.NetworkMap) {
|
||||
b.setDebugLogsByCapabilityLocked(nm)
|
||||
}
|
||||
|
||||
// See the netns package for documentation on what this capability does.
|
||||
netns.SetBindToInterfaceByRoute(nm.HasCap(tailcfg.CapabilityBindToInterfaceByRoute))
|
||||
netns.SetDisableBindConnToInterface(nm.HasCap(tailcfg.CapabilityDebugDisableBindConnToInterface))
|
||||
// See the netns package for documentation on what these capability do.
|
||||
netns.SetBindToInterfaceByRoute(b.logf, nm.HasCap(tailcfg.CapabilityBindToInterfaceByRoute))
|
||||
netns.SetDisableBindConnToInterface(b.logf, nm.HasCap(tailcfg.CapabilityDebugDisableBindConnToInterface))
|
||||
netns.SetDisableBindConnToInterfaceAppleExt(b.logf, nm.HasCap(tailcfg.CapabilityDebugDisableBindConnToInterfaceAppleExt))
|
||||
|
||||
b.setTCPPortsInterceptedFromNetmapAndPrefsLocked(b.pm.CurrentPrefs())
|
||||
if buildfeatures.HasServe {
|
||||
|
||||
@@ -39,20 +39,35 @@ var bindToInterfaceByRoute atomic.Bool
|
||||
// setting the TS_BIND_TO_INTERFACE_BY_ROUTE.
|
||||
//
|
||||
// Currently, this only changes the behaviour on macOS and Windows.
|
||||
func SetBindToInterfaceByRoute(v bool) {
|
||||
func SetBindToInterfaceByRoute(logf logger.Logf, v bool) {
|
||||
logf("netns: bindToInterfaceByRoute to %v", v)
|
||||
bindToInterfaceByRoute.Store(v)
|
||||
}
|
||||
|
||||
var disableBindConnToInterface atomic.Bool
|
||||
|
||||
// SetDisableBindConnToInterface disables the (normal) behavior of binding
|
||||
// connections to the default network interface.
|
||||
// connections to the default network interface on Darwin nodes.
|
||||
//
|
||||
// Currently, this only has an effect on Darwin.
|
||||
func SetDisableBindConnToInterface(v bool) {
|
||||
// Unless you intended to disable this for tailscaled on macos (which is likely
|
||||
// to break things), you probably wanted to set
|
||||
// SetDisableBindConnToInterfaceAppleExt which will disable explicit interface
|
||||
// binding only when tailscaled is running inside a network extension process.
|
||||
func SetDisableBindConnToInterface(logf logger.Logf, v bool) {
|
||||
logf("netns: disableBindConnToInterface set to %v", v)
|
||||
disableBindConnToInterface.Store(v)
|
||||
}
|
||||
|
||||
var disableBindConnToInterfaceAppleExt atomic.Bool
|
||||
|
||||
// SetDisableBindConnToInterfaceAppleExt disables the (normal) behavior of binding
|
||||
// connections to the default network interface but only on Apple clients where
|
||||
// tailscaled is running inside a network extension.
|
||||
func SetDisableBindConnToInterfaceAppleExt(logf logger.Logf, v bool) {
|
||||
logf("netns: disableBindConnToInterfaceAppleExt set to %v", v)
|
||||
disableBindConnToInterfaceAppleExt.Store(v)
|
||||
}
|
||||
|
||||
// Listener returns a new net.Listener with its Control hook func
|
||||
// initialized as necessary to run in logical network namespace that
|
||||
// doesn't route back into Tailscale.
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"tailscale.com/net/netmon"
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/version"
|
||||
)
|
||||
|
||||
func control(logf logger.Logf, netMon *netmon.Monitor) func(network, address string, c syscall.RawConn) error {
|
||||
@@ -36,13 +37,11 @@ var errInterfaceStateInvalid = errors.New("interface state invalid")
|
||||
// controlLogf binds c to a particular interface as necessary to dial the
|
||||
// provided (network, address).
|
||||
func controlLogf(logf logger.Logf, netMon *netmon.Monitor, network, address string, c syscall.RawConn) error {
|
||||
if isLocalhost(address) {
|
||||
// Don't bind to an interface for localhost connections.
|
||||
if disableBindConnToInterface.Load() || (version.IsMacGUIVariant() && disableBindConnToInterfaceAppleExt.Load()) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if disableBindConnToInterface.Load() {
|
||||
logf("netns_darwin: binding connection to interfaces disabled")
|
||||
if isLocalhost(address) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -2465,6 +2465,10 @@ const (
|
||||
// of connections to the default network interface on Darwin nodes.
|
||||
CapabilityDebugDisableBindConnToInterface NodeCapability = "https://tailscale.com/cap/debug-disable-bind-conn-to-interface"
|
||||
|
||||
// CapabilityDebugDisableBindConnToInterface disables the automatic binding
|
||||
// of connections to the default network interface on Darwin nodes using network extensions
|
||||
CapabilityDebugDisableBindConnToInterfaceAppleExt NodeCapability = "https://tailscale.com/cap/debug-disable-bind-conn-to-interface-apple-ext"
|
||||
|
||||
// CapabilityTailnetLock indicates the node may initialize tailnet lock.
|
||||
CapabilityTailnetLock NodeCapability = "https://tailscale.com/cap/tailnet-lock"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user