Tailscale SSH 与 OpenSSH 密钥登录的认证差异实战
Tailscale SSH 与 OpenSSH 密钥登录的认证差异实战
同一台机器,两种 SSH 登录方式:Tailscale SSH 和 OpenSSH 密钥登录。它们看起来都是 ssh root@某地址,但认证模型完全不同——一个认身份,一个认密钥。2026 年 10 月 24 日,我在一台 sg188 机器上把这两种登录方式逐一验证了一遍,顺带踩了一个"Tailscale SSH 策略先筛连接"的坑。本文记录实测过程与结论。
一、两种登录方式的认证模型
先把结论摆出来:
- OpenSSH 密钥登录:认密钥。客户端拿私钥签名,服务端拿
~/.ssh/authorized_keys里的公钥验签,签对了就放行。谁拿着私钥,谁就能进;服务端不关心你是谁,只关心密钥对不对。 - Tailscale SSH:认身份。连接先过 tailnet 的访问控制(ACL),再决定是否交给机器上的 SSH 服务。你的 tailnet 身份(节点、用户、标签)就是凭证,
authorized_keys在这条路上不起作用。
这个差异直接决定了排障思路:OpenSSH 登不上,先查密钥、权限、sshd_config;Tailscale SSH 登不上,先查 ACL 里有没有放行这条连接的规则。
二、实测环境与两条密钥路径
测试对象是一台 sg188 机器。机主的明确要求:这台机器的 Tailscale SSH 保持关闭,只用 OpenSSH 密钥登录。验证时两条密钥路径都通了:
# 内网地址直连
ssh -i ~/.ssh/sg188 root@100.115.15.100 -p 22
# 公网地址直连
ssh -i ~/.ssh/sg188 root@188.239.19.102 -p 22
两条都一次成功。这说明:只要 sshd 在监听、密钥对得上,OpenSSH 路径与 Tailscale 完全无关——Tailscale SSH 关掉,不影响密钥登录。
这里有一个容易混淆的点:Tailscale SSH 开启时会接管 22 端口。同一台机器上,如果 Tailscale SSH 在跑,22 端口的连接先由 tailscaled 拦截、按 ACL 判定;OpenSSH 的 sshd 想继续提供密钥登录,就得另起端口(实测中另一台沙箱容器就是这么做的:sshd 改听 2222,Debian 12 下还要先 disable ssh.socket,否则 Port 改不动)。所以"22 端口登不上"时,先分清当前是谁在监听 22:
ss -tlnp | grep ':22'
看到 tailscaled 占着 22,就别再往 authorized_keys 里找原因了。
三、踩坑:经隧道连 RunSSH 目标被无 banner 秒断
同一天还遇到一个更隐蔽的案例。一台走 Tailscale userspace-networking 模式的沙箱容器,RunSSH 开着,我经 3130 隧道连它的 Tailscale SSH,连接被无 banner 秒断——连 SSH banner 都没拿到就关了。
一开始怀疑隧道本身有问题。但对照实验很快排除了这个方向:同一条隧道连真实 sshd 的另外两台机器(ydy、wabi)都正常,只有 RunSSH 目标不通。问题不在隧道,在 Tailscale SSH 的策略筛查上。
定性结论是:Tailscale 的 SSH 策略在把连接交给 SSH 服务之前先筛一遍。ACL 的 ssh 段里没有覆盖"源节点 → 目标节点"的规则时,连接会被静默关闭——不报错、不给 banner,直接断。这和 OpenSSH 的行为完全不同:OpenSSH 拒绝连接至少会给明确的报错(Permission denied (publickey) 之类),而 Tailscale SSH 的策略拒绝是静默的,很容易误判成网络问题。
解法是在 ACL 的 ssh 段里加一条明确放行的规则:
{
"action": "accept",
"src": ["100.112.115.41"],
"dst": ["autogroup:self"],
"users": ["root"]
}
src 是发起方的 tailnet IP,dst 用 autogroup:self 表示目标节点自身,users 是登录用的系统用户。加完这条规则,同一条隧道再连就能正常拿到 banner、完成身份认证。这个规则至今仍是判断"Tailscale SSH 通不通"的第一检查项:先看 ACL,再看网络。
四、userspace 模式下的端口转发限制
那台沙箱容器还暴露了另一个限制:tailscaled 跑在 userspace-networking 模式下,容器内其他进程不能把它当网卡用,Tailscale 只转发 22 端口和 tailscale serve 的端口。之前给容器 root 加的 2222 端口 sshd(配了专用密钥对,公钥已写入 authorized_keys)只在容器内可用,对外要走 tailscale serve 才能暴露——而这一步要动 prefs,须机主授权。
这意味着:userspace 模式的节点,Tailscale SSH 几乎是唯一的对外 SSH 入口。规划端口时别指望在它上面再开一个"备用 sshd 端口"对外服务。
五、两个细节:空密码与密钥对
同一天在容器上还发现一个安全细节,顺带记下来:沙箱镜像出厂的 sshd 配置是 PermitEmptyPasswords=yes,root 为空密码,2222 端口可以零凭证 root 登录(Accepted none)。发现后立即改成 no 并复测拒绝。这类沙箱到手第一件事就是查空密码——别默认它已经加固过。
另外,Tailscale SSH 本身不看 authorized_keys,所以给容器 root 加的专用密钥对(私钥在 ~/.ssh/today-sandbox)只是"标准 sshd 密钥登录"的兜底,和 Tailscale SSH 是两条完全独立的凭证体系,别混用。
六、结论:什么时候用哪种
- 要按人授权、按策略收放(比如只允许某几个节点以 root 登录某几台机器),用 Tailscale SSH,规则写在 ACL 里,改一条规则就全网生效,不用逐台改
authorized_keys。 - 要不依赖 tailnet 控制面、纯离线可用的登录,用 OpenSSH 密钥登录。Tailscale 挂了、ACL 配错了,密钥路径照样能进。
- 两条路可以共存,但端口要分开:Tailscale SSH 占 22 时,OpenSSH 另起端口;排障时先确认 22 的监听者是谁,再决定查 ACL 还是查密钥。
- Tailscale SSH 连不上且连 banner 都没有时,优先怀疑 ACL 的
ssh段没有放行规则——静默断开是策略拒绝的典型症状,不是网络故障。
一句话总结:OpenSSH 认密钥,Tailscale SSH 认身份;前者排障看密钥与配置,后者排障先看 ACL。
- 点赞
- 收藏
- 关注作者
评论(0)