11 月 5 日 OpenSSH 放出 10.6p2,同一天 Alpine 发了一条安全公告,标题很直白:openssh-server 密码认证绕过。第二天 NVD 给了编号 CVE-2026-123158,CVSS 3.1 评 8.1(AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H),归类 CWE-394。

说人话:密码框随便填一长串,照样能登进去。 不用知道别人的密码,不用有别人的密钥,一条连接,每次都成,不靠重试。

前提条件有点绕,但凑齐一点都不难

要打得进去,得同时满足四条:

  • sshd 是用 musl libc 编译、且没走 PAM(Alpine 官方的 openssh-server 就是这个编法;用 openssh-server-pam 且 UsePAM yes 的不受影响,UsePAM no 就回到了受影响那一边)
  • PasswordAuthentication 是 yes —— 这是 OpenSSH 的默认值,没动过就是它
  • 机器上存在一个密码字段是 * 的账号。这个条件比听起来容易:Alpine 底座镜像里 root 就是 root:*(3.16 起),用 adduser 建纯密钥用户不设密码也是 *,走 nscd/sssd/winbind 进来的目录服务用户压根没有 shadow 条目
  • 还有至少一个本地账号带 $5$ 或 $6$ 哈希

四条齐了,攻击者往密码里塞一段 257 到 1024 字节的超长字符串就行。

根因一句话能说完:musl 下、又没 PAM 的时候,sshd 判断「这串东西到底是不是密码哈希」的判断出了错(CWE-394,对字符串意图的误判)。长串被当成一个 crypt 哈希拿去比对,撞上机器上另一个账号的 $5$/$6$ 哈希,就返回认证成功。

这里最反直觉的一点:真正开门的是那个没有密码的账号。一个设了密码的普通用户,"传染"了整台机器上所有密码字段为 * 的账号。root 有 PermitRootLogin prohibit-password 默认挡着,但如果装了 doas、又有能登的账号,这层也就只是个摆设。

影响面:Alpine 全分支

Alpine 公告写得很干脆:3.21 到 3.24 加 edge 逐条验过,全中;3.16 到 3.20 这些已经停更的老分支也一样。容器里不跑 sshd 的 Docker 用户不受牵连——但 K8s 节点、轻量云主机、把 sshd 塞进镜像当跳板的那类玩法,正好是重灾区。

时间线也值得记一笔:11 月 5 日披露,当天 alpine.org 的公告和两个公开的复现仓库(sshhole-lab、sshhole-repro)就一起挂出来了。从「有人写了个洞的报告」到「谁都能拿仓库去打」,中间不到一天。所谓补丁窗口,现在真的就是按小时算的。

怎么修

先升级,再重启。两句都不能省:

apk upgrade -U -a
rc-service sshd restart

Alpine 公告专门强调了一句:升级包不会替换正在跑的 daemon。apk 把二进制换掉了,内存里那个 sshd 还是旧的,漏洞照旧开着。这一步漏掉的人不会少。

版本对照(升到这个号以上才算修好):

分支修复版本
edge10.6_p2-r0
3.2410.3_p1-r2
3.2310.2_p1-r1
3.2210.0_p1-r11
3.219.9_p2-r1
3.209.7_p1-r6
3.199.6_p1-r3
3.189.3_p2-r4
3.179.1_p1-r7
3.169.0_p1-r6

暂时升不了的,把密码登录关掉就断了这条路:

mkdir -p /etc/ssh/sshd_config.d
echo 'PasswordAuthentication no' > /etc/ssh/sshd_config.d/00-no-passwords.conf
sshd -t && rc-service sshd restart
sshd -T | grep -i passwordauthentication

3.19 以前的分支不读那个 drop-in 目录,得直接改 /etc/ssh/sshd_config。改之前先确认密钥登录是通的,当前这个会话别关——这个顺序颠倒了就是把自己关在门外。

自查三条

ssh -V
ldd "$(command -v sshd)" | grep -i musl
awk -F: '$2=="" || $2=="*" {print $1}' /etc/shadow

三条都能命中,就是「现在就处理」的级别;再补一条 sshd -T | grep -i passwordauthentication,如果是 no,这条路已经是关的。

顺手说一句别搞错方向:glibc 系的 Debian / Ubuntu / RHEL 不在这个 CVE 范围内,折腾它们没意义。但「我用 Ubuntu 所以没事」也别当免死金牌——同期还有一堆在排队,比如Linux 那处 TCP 竞态,以及已经被打进 KEV 名单的 PHP2Shell。

落到运维动作上就两件:升级,重启 sshd。顺序别反。