关于Tailscale SSH漏洞:默认没事,但那个root进程值得再看一眼
Erica Windisch发布了针对Tailscale的11个安全发现,社区一边恐慌一边辟谣。默认配置确实不触发任何一条,但报告里有个被辟谣声盖过的设计问题:SSH服务器跑在root进程里,和OpenSSH的权限分离走了两条路。
周末的开发者时间线不太平。Erica Windisch 在 tailworm.com 挂了一份安全评估,对象是 Tailscale v1.104.2 和 headscale v0.29.5,测试窗口 10 月 22 日到 24 日,所有复现都在未修改的正式版上完成。一共 11 个发现,没有走协调披露,发布即公开。
最重的一组在 Tailscale SSH。tailscaled 以 root 权限运行,它的 SSH 服务器也在这个进程里。ssh -L 和 ssh -R 的 Unix socket 转发,路径校验和使用之间存在时间差:校验在 check 时通过,unlink、bind、dial 在之后发生,中间可以被 rename 竞争绕过。报告里实测:一个普通 SSH 会话能在目标机器上拿到 uid=0,目标包括 /run/docker.sock 和 /run/systemd/private。
消息传开后的样子和报告本身的措辞有温差。一边是“Tailscale SSH 漏洞可让攻击者获取 root”,另一边是 Jamieson O'Reilly 的辟谣:默认安装里这些功能全是关的。他说得没错。Tailscale SSH 是 opt-in 的,app connector 需要配置,serve 需要主动开,headscale 得自己部署。11 个发现没有一个能碰到默认的 tailscale up。O'Reilly 还写了个只读检查脚本 tailslop,逐条比对报告里的每个发现在你的机器上是否被触发。
但“默认没事”和“没问题”是两件事。报告里有个设计层面的观察,被辟谣的声音盖过去了:Tailscale SSH 不做用户级认证,WireGuard 认的是设备不是人,授权阶段直接 method none 通过。整个 SSH 会话的权限取决于那个 root 进程怎么处理转发请求。
对比 OpenSSH:认证之后子进程 setuid 到会话用户,之后的 streamlocal bind、unlink、dial 全以用户身份运行。上游 10 月提交的 b37c095a 更进一步,当 sshd 以 root 运行时直接禁用 streamlocal 和特权端口反向转发。Dropbear 有过同类的 CVE-2025-14282,修复方式是在 USERAUTH_SUCCESS 时提前 setuid。Tailscale 走的路线是把 SSH 服务器嵌进一个高权限常驻进程,路径检查再仔细,跑在 root 上下文里,竞争窗口的代价就比用户进程大得多。
还有一层容易漏掉的:check mode 管的是会话建立,不覆盖会话里的 -L 和 -R 转发。你浏览器里点过一次批准,窗口期内所有转发都跟着这个会话走。报告里写明了这一点,辟谣的贴文多数没提。
要动手的话,最直接的是 tailscale set --ssh=false,然后用普通 sshd 走 tailnet。RusticStack 提醒过一句:关之前确认 sshd 在跑,不然会把自己锁在外面。per-pair 的 SSH grant 是报告里唯一拦住实验室自动传播的控制项。serve 配置里如果有一条 --tcp 指向 unix socket,也得看一眼。
Tailscale 工程 VP Mike Shaver 在 Reddit 上回应了,说正在审查报告,已经独立发现一些问题并在修复,当前不建议所有人关闭 Tailscale SSH。他的原话是,部分问题发生在授权之后,涉及 Unix 权限和 SSH 转发怎么处理,和“未认证攻击者直接连任意机器”不是一回事。这个说法和报告里“前提是已有一个设备被拿下”一致。
Windisch 在 researchers note 里写了一句判断:设计选择在脱离纵深防御,用一个高权限进程替代做了权限分离的守护进程。这话不中听,但它指向的问题不在 11 个具体条目里,在架构选择上。恐慌没必要,但关掉报告之前,值得想想这个选择是不是你愿意接受的。
发布时间: 2026-10-26 06:38