cmd/tailscaled, version/distro: default to userspace-networking on Crostini

cros-garcon NULL-derefs on cold-boot netlink enumeration when
tailscale0 is present, preventing the Crostini container and
ChromeOS Terminal from starting cleanly. This is an upstream
ChromiumOS bug in cros-garcon; tailscaled can work around it
by defaulting to userspace-networking mode on Crostini.

Tailscale SSH continues to work via tailscaled's netstack.
Users can override with --tun=tailscale0 on ChromeOS builds
where cros-garcon is fixed.

Crostini is detected via /opt/google/cros-containers/bin/garcon,
which is present in every Crostini penguin container.

ssh/tailssh extends the existing Debian default-PATH case to
cover Crostini, since Crostini is Debian-based and benefits
from the same SSH PATH defaults.

RELNOTE: Crostini now defaults to userspace-networking.

Fixes #19488
Updates #12090

Signed-off-by: ferrumclaudepilgrim <ferrumclaudepilgrim@users.noreply.github.com>
This commit is contained in:
ferrumclaudepilgrim
2026-06-01 17:40:07 -07:00
committed by Brad Fitzpatrick
parent a6ab7efa4f
commit 3f70abdc6f
3 changed files with 17 additions and 1 deletions
+6
View File
@@ -19,6 +19,7 @@ type Distro string
const (
Debian = Distro("debian")
Crostini = Distro("crostini") // ChromeOS Crostini Linux container; Debian-based
Arch = Distro("arch")
Synology = Distro("synology")
OpenWrt = Distro("openwrt")
@@ -84,6 +85,11 @@ func linuxDistro() Distro {
// Currently supported product families:
// - UDM (UniFi Dream Machine, UDM-Pro)
return UBNT
case have("/opt/google/cros-containers/bin/garcon"):
// ChromeOS Crostini ships /opt/google/cros-containers/bin/garcon
// in every penguin container. MUST be checked before Debian since
// Crostini is Debian-based.
return Crostini
case have("/etc/debian_version"):
return Debian
case have("/etc/arch-release"):