openssh漏洞补丁
OpenSSH 又爆漏洞了。洞补丁这次是洞补丁 CVE-2024-6387,一个存在于 sshd 中的洞补丁信号处理竞争条件,攻击者能在特定条件下远程执行代码,洞补丁而且是洞补丁以 root 权限。Qualys 的洞补丁研究团队给它起了个名字叫 regreSSHion,听着挺唬人,洞补丁实际也确实够呛——毕竟 OpenSSH 几乎是洞补丁所有 Linux 服务器的默认远程登录入口,这东西出问题,洞补丁等于大门锁芯被人摸透了。洞补丁
我第一次看到这个漏洞细节的洞补丁时候,脑子里蹦出来的洞补丁第一个念头是:怎么又是信号处理。OpenSSH 的洞补丁 sshd 在处理 SIGALRM 时存在异步信号安全问题,这个坑其实 2006 年就修过一次,洞补丁结果 2020 年某个提交又把相关代码改回去了,洞补丁等于埋了颗定时炸弹。四年后才被人踩响。你说这事儿讽刺不讽刺,开源代码的 review 流程也不是铁板一块,一个看似无关的重构就能让老漏洞复活。
补丁本身倒不复杂。OpenSSH 9.8p1 已经修了,各大发行版也陆续 backport。Debian 和 Ubuntu 的用户直接 apt update && apt upgrade openssh-server 就行,RHEL 系走 dnf update openssh。但问题在于,很多生产环境里的 sshd 不是你想重启就能重启的——你正连着它呢。所以实际操作往往是先升级二进制,然后找个维护窗口重启服务,或者干脆等下次重启自动生效。这中间的窗口期,就是风险敞口。
临时缓解措施也有,在 /etc/ssh/sshd_config 里把 LoginGraceTime 设为 0。默认是 120 秒,设为 0 意味着 sshd 不再使用 SIGALRM 来强制断开未认证的连接。代价是未认证连接会一直挂着,可能被用来做资源耗尽攻击。这是个典型的权衡:堵一个洞,开另一个口。安全这事儿从来就没有银弹。
让我比较在意的是这个漏洞的利用条件。攻击者需要赢得一个竞争条件,大概要尝试约一万次才能成功一次,而且每次尝试都意味着一次完整的 TCP 连接建立和认证超时等待。Qualys 说在 32 位系统上大概 6-8 小时能打穿,64 位因为 ASLR 更强,可能要几天。听起来好像没那么紧急?但别忘了,这是远程无认证的 root 代码执行。对于暴露在公网上的 SSH 服务,攻击者有的是时间慢慢磨。我见过太多服务器把 SSH 端口直接怼在 0.0.0.0 上,连 fail2ban 都不装。
还有一个细节值得说:这个漏洞影响的是 glibc 的 syslog 实现路径。OpenSSH 在信号处理函数里调用了 syslog,而 syslog 不是异步信号安全的。如果你用的是 musl libc 或者某些 BSD 系统,可能不受影响。这就解释了为什么 Alpine Linux 的用户相对淡定。但主流发行版清一色 glibc,所以该打补丁还是得打。
我自己的做法是:先把所有能自动更新的机器跑一遍 unattended-upgrades,然后手动检查那些锁了版本号的关键服务器。对于实在不能重启 sshd 的,加一条防火墙规则,只允许特定 IP 段访问 22 端口。这招土,但管用。等下一个维护窗口再重启服务。
说到底,OpenSSH 的代码质量在开源项目里算上乘的,但再好的代码也架不住二十多年的历史包袱和无数次重构。regreSSHion 这个名字起得精准——它就是个回归漏洞。提醒我们一件事:安全不是一次性的工作,补丁打了不代表永远安全,老代码里的老问题随时可能换个马甲重新登场。