Tailscale SSH 与 OpenSSH 密钥登录的认证差异实战

举报
yd_225649965 发表于 2026/11/08 01:07:03 2026/11/08
【摘要】 Tailscale SSH 与 OpenSSH 密钥登录的认证差异实战同一台机器,两种 SSH 登录方式:Tailscale SSH 和 OpenSSH 密钥登录。它们看起来都是 ssh root@某地址,但认证模型完全不同——一个认身份,一个认密钥。2026 年 10 月 24 日,我在一台 sg188 机器上把这两种登录方式逐一验证了一遍,顺带踩了一个"Tailscale SSH 策略先...

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。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。