Hacker News 中文摘要

RSS订阅

OpenSSH 10.6 发布 -- OpenSSH 10.6

开放安全外壳(OpenSSH)10.6/10.6p1 于 2026-10-06 发布,是 100% 完整的 SSH 2.0 协议实现,包含 sftp 客户端与服务器支持。近期团队收到大量安全漏洞报告,多来自 AI 模型或辅助。虽许多 AI 报告在现实威胁模型下无安全影响,团队仍欢迎,尤其结合人工分类与分析时。已见 AI 发现漏洞被他人独立复现,表明未报告的对手亦可发现。为此团队将更频繁发布以更快推送修复而非攒至下次计划。

正文

OpenSSH 10.6 / 10.6p1(2026-10-06)

OpenSSH 10.6 于 2026-10-06 发布,可从 https://www.openssh.com/ 列出的镜像获取。OpenSSH 是 100% 完整的 SSH 协议 2.0 实现,包含 sftp 客户端和服务器支持。

近期 OpenSSH 团队收到大量安全漏洞报告,许多来自 AI 模型或借助 AI 完成。虽然不少 AI 报告在真实威胁模型下并无安全影响,团队仍非常欢迎这类报告,尤其是结合了人工分诊、分析、测试用例,特别是附带修复方案的报告。

已出现多起 AI 工具发现的安全漏洞随后被其他研究者独立发现的情况。这说明不向开源项目报告漏洞的攻击者也可能发现这些漏洞。因此,OpenSSH 团队暂时会更频繁地发布版本,以便更快让用户拿到修复,而不是等到下一个计划版本再批量发布。

未来弃用通知

  • scp(1):开始弃用 -R 标志。该选项用于在远程主机上执行 scp 实现远程到远程复制,是一种脆弱的优化,需要远程主机上的凭据,而且如果远程系统的 shell 引号规则与客户端预期不同,还会带来安全风险。从 10.6 起该选项仍可用,但会向标准错误输出弃用警告。未来版本将忽略该选项,转而采用默认的远程到远程复制行为(经由运行 scp 的主机复制)。
  • sshd(8):未来版本将移除对不支持文件描述符传递、且分配 PTY 需要 root 权限的平台的支持。受影响平台包括 SCO OpenServer 5 和 QNX 6,也可能包括其他类似的老旧系统。如果这些平台的用户社区能帮助构建替代方案(例如避免 PTY 分配需要 root),可以避免弃用。

潜在不兼容变更

  • ssh(1)、sshd(8):由于下面“安全”部分所述变更,压缩的效果会降低。
  • ssh(1):命令行输入的目标用户名现在会被更严格检查,包含反斜杠和美元符号的用户名将被拒绝。配置文件里通过 User 指令指定的用户名不受此限制。
  • sshd(8):在不支持文件描述符传递且 PTY 分配需要 root 的平台上,GatewayPorts 和 StreamLocalForwarding 选项被强制禁用。

自 OpenSSH 10.5 以来的变更

本版本包含多项安全修复、若干新特性和一些小修复。

安全

  • sftp(1):更严格地验证服务器返回的路径,避免服务器返回的路径操纵递归复制、把文件写到目标目录之外。由 Junghoon Cho 报告并提供补丁。
  • sshd(8):使用 GSSAPIAuthentication 时,只在认证成功后存储 GSSAPI 凭据。避免失败的 GSSAPI 认证尝试留下的凭据在后续其他认证成功后仍被不当使用。由 Moritz Theile 报告并提供补丁。
  • sshd(8):在认证前重置 GSSAPIAuthentication,避免一次认证尝试的状态与之后的尝试混淆。Moritz Theile 报告并反馈。
  • sshd(8)、ssh(1):禁用 LZ77 字典编码器,以缓解 Fabian Bäumer 和 Marcus Brinkmann 论文《Crossing the Streams: SSH Plaintext Recovery via a Common Compression Context in Multiplexed Channels》(预印本 https://arxiv.org/abs/2609.07709,2026)中描述的信道侧泄漏。存在一种选择明文攻击,利用基于字典的压缩,通过另一条信道与 SSH 会话共享的压缩字典交互,从一条信道中恢复机密。攻击者控制的输入能通过 LZ77 把重复字符串替换为对 SSH 会话编码器搜索缓冲区的后向引用,从而可识别地反映到已传输密文的总长度中,而该缓冲区在所有信道间共享。因此文档此前已建议不要在同时承载可信与不可信流量的连接上启用压缩。此变更会降低 Compression 选项的效果。建议尽可能在 SSH 协议之上使用应用层压缩,通常更有效且完全不受此类攻击影响。
  • ssh(1):禁止命令行输入的用户名包含 '$' 和 '\',避免来自不可信来源的用户名通过 ProxyCommand、Match exec 等造成 shell 上下文注入。配置文件指定的用户名不受此限制。由腾讯 SecBuddyF KeenLab(CodeBuddy Security)报告。团队继续建议不要将 ssh(1) 及其他工具的命令行直接暴露给不可信输入。
  • ssh-keygen(1):修正日期转换时的夏令时处理。此前可能造成最多 ±1 小时误差(在南极洲/Troll 时区可达 ±2 小时),可能导致生成过期时间错误的证书。bz4004;来自 Khush Patel。
  • sshd(8)、ssh(1):确保压缩后的载荷不会膨胀超过支持的最大包长度。由 Oleh Konko 报告。
  • sshd(8):完整遵守 authorized_keys 的 "restrict" 关键字,此前未正确应用于隧道转发(PermitTunnel,默认禁用)。这与 10.5 中修复的问题不同。
  • sshd(8):正确处理某些接受 "none" 的选项。包括 AuthorizedPrincipalsFile 在内的一些选项文档说明可用 "none" 禁用,但当被 sshd_config 的 Match 关键字覆盖时,该参数会被错误解释为字面文件名。与 Chris Rohlf 合作,并借助 Claude 与 Anthropic Research。
  • sshd(8):在 OS X SDK >= 27 上不再支持沙箱,因为所依赖的 API 已被移除且没有明显的替代。
  • sshd(8):在不支持文件描述符传递且 PTY 分配需要 root 的平台上,认证后的 sshd-session 进程保留 root 权限,而在其他平台上该进程以登录用户的权限运行。以提升权限运行时,sshd-session 可以 root 身份执行某些操作,绕过通常对用户的限制,例如建立 Unix 域套接字连接或(通过 -R 转发)绑定低编号 TCP 端口。因此本版本禁用 GatewayPorts 和 StreamLocalForwarding,如果找不到替代方案,未来将移除对这些(少数)平台的支持。受影响平台包括 QNX 6、SCO OpenServer 5 以及使用 --disable-fd-passing 配置构建的版本。此问题由 sn0x-sharma 和 Dark River 分别报告。

新特性

  • 所有组件:启用混合后量子签名算法 ssh-mldsa44-ed25519。注意它不再使用此前实验性实现的 "@openssh.com" 厂商扩展后缀。用此前实验性支持生成的密钥必须重新生成和/或移除。
  • sshd(8):为 sshd_config 增加 WarnWeakCrypto 选项,此前仅客户端可用。默认启用,当客户端使用非后量子安全的密钥协商方案时会记录日志。
  • ssh-keygen(1)、ssh-add(1):通过检查凭据的 credProtect 策略,为从 FIDO 令牌加载的常驻密钥保留用户验证(PIN 或生物识别)要求。GHPR701,来自 Savely Krasovsky。
  • ssh(1):在 ~I 连接信息显示中包含本地和远程版本字符串。
  • ssh-add(1):增加 -P 标志,跳过不需要 PIN 的 FIDO 和 PKCS#11 令牌的 PIN 输入。
  • sftp(1):为 mkdir/lmkdir 增加 '-p' 标志,按需创建目录。用法类似 mkdir(1),已存在的目录不会报错。
  • ssh-keygen(1):增加 "hexdump" 密钥导出模式,以十六进制输出 SSH 线格式的密钥 blob。例如 ssh-keygen -em hexdump -f /key。
  • ssh(1)、sshd(8):ChannelTimeout 现在接受小数秒超时。
  • sshd(8):通过新的 AgentSocketPath 选项指定用于 agent 转发的 $SSHAUTHSOCK 位置。支持用户专属路径(默认是 $HOME 的子目录,如 "user:.ssh/agent")和此前允许的共享目录方式(如 "shared:/tmp")。在共享目录中创建的套接字会放在随机命名的子目录里。bz3860。
  • ssh-agent(1):用 -A 标志指定 agent 套接字目录,接受类似 sshd AgentSocketPath 的 "user:" 和 "shared:" 目录样式。
  • sshd(8):将公钥认证的 "key ok" 测试与认证尝试分开计数。增加 PubkeyOptions max-pk-ok:nnnn 选项,允许一定数量的 PK_OK 测试(询问服务器是否可能接受某公钥)不计入 MaxAuthTries,默认 6 次。用尽后,后续尝试计为失败认证。这让磁盘或 ssh-agent 中更多密钥有机会在服务器断开前被检查。
  • ssh(1)、sshd(8):扩展 TCPKeepAlive 选项,也可为转发连接创建的套接字设置 keepalive。TCPKeepAlive "yes" 或 "transport" 只为连接套接字启用;"TCPKeepAlive all" 还为转发的套接字启用。bz3921。

Bug 修复

  • sshd(8)、ssh(1):修复在更多突厥语系语言(具体是阿塞拜疆语和克里米亚鞑靼语,其有点和无点 i/I 字符分离)上的配置匹配。bz3991。
  • ssh(1)、sshd(8):不再尝试在非 IP/IPv6 套接字上设置 TCP_NODELAY,消除调试日志中的一些噪音。
  • ssh(1):修复 ssh -G 选项输出的大小写。bz4005。
  • ssh(1)、sshd(8):修复 ChannelTimeout 的匹配优先级;此前更具体的信道类型(如 "session:shell")可能覆盖用户指定的较不具体(如 "session")的 ChannelTimeout。某些情况下调试消息打印 0 而非有效超时。bz3994。
  • sftp(1):避免服务器 stat/lstat 操作失败时某些情况下的 NULL 解引用崩溃。GHPR707。
  • sshd(8):关闭一个竞态:服务器在处理 SIGHUP 重启请求期间收到 SIGTERM/SIGQUIT 会被忽略。bz3981。
  • sshd(8)、ssh(1):在密钥解析时尽早对照允许列表(PubkeyAcceptedAlgorithms 等)检查密钥和 CA 签名类型,减少被禁用算法带来的攻击面。由 Chris Rohlf 提出,并与 Claude 和 Anthropic Research 深入合作反馈。
  • 所有组件:禁用 libcrypto 时使用的 ed25519 签名算法回退实现从 SUPERCOP ed25519 切换为 libsodium。libsodium 实现包含比此前参考实现更多的严格性检查,API 也更易用。
  • ssh-add(1)、ssh(1)、ssh-keygen(1):修复程序在后台进程组中启动、无 TTY 且某些信号被忽略时读取口令的自旋问题。bz3995。
  • scp(1):禁止接收到的 scp -O 文件名包含 nul 字节。正常操作无法触发。由 Chua Wei Xun 报告。
  • ssh-keygen(1)、ssh(1)、sshd(8):对写入或加载 OpenSSH 格式私钥时可接受的 KDF 轮数实施上限。上限设为 1M,确保被传入轮数离谱的坏密钥的服务最终能完成解析。
  • ssh-keygen(1):默认 KDF 轮数从 24 提升到 32(线性增加,不同于 bcrypt(3) 的指数增长)。
  • ssh(1):使 StreamLocalBindMask 正确遵守 Host/Match 块,并按文档实现首次匹配优先。bz4013。
  • sshd(8):使 StreamLocalBindMask 正确首次匹配优先。

可移植性

  • 所有组件:移除 NetBSD BROKENREADCOMPARISON 变通,似乎已不再需要,且曾导致认证前 CPU 自旋。
  • sshd(8):启用 SELinux 支持时不再把 sshd 链接到 libselinux(sshd-auth 和 sshd-session 辅助二进制仍链接)。
  • sshd(8):允许 seccomp 沙箱中使用 madvise(..., MADVDONTNEEDLOCKED),GrapheneOS 的加固分配器需要。bz4001。
  • sshd(8):限制 seccomp 沙箱接受的 mremap(2) 标志,现在只接受 MREMAP_MAYMOVE,其他标志可能在攻击链中有用。由 Mohammad Hossein Abedini 报告。
  • sshd(8):允许 Match 中使用 PAMServiceName(10.4 中回归)。服务器选项解析重构时意外禁用了在 Match 块中设置 PAMServiceName 的能力。
  • sshd(8):移除 --disable-fd-passing 配置选项。

OpenSSH 10.5 / 10.5p1(2026-08-11)

OpenSSH 10.5 于 2026-08-11 发布。与 10.6 类似,团队说明了收到大量 AI 辅助的安全报告,并因 AI 发现的漏洞可能被攻击者独立发现而更频繁发布版本。

潜在不兼容变更

  • 可移植 OpenSSH 现在要求 libcrypto 提供 ECC(椭圆曲线密码)支持,包括 NISTP521 曲线。OpenSSH 当前支持的所有 libcrypto 实现(LibreSSL、OpenSSL、BoringSSL 和 AWS LC)的默认构建配置都包含 ECC。--without-openssl 构建配置不受影响。

自 OpenSSH 10.4 以来的变更

安全

  • ssh-agent(1):修复 agent 锁定与用于识别转发 agent 的 session-bind@openssh.com 扩展之间的交互问题。agent 被锁定时这些绑定请求被拒绝,导致本应仅限本地使用的操作可被远程执行,包括添加 PKCS#11 令牌和使用带目标限制的密钥。由 sn0x-sharma 报告。
  • ssh(1):避免在通过本地会话复用套接字添加远程转发、同时有远程转发打开请求待处理时,客户端出现潜在的 realloc 释放后使用。Brian Mingus(Cognatory)报告并修复。
  • sshd(8):使 authorized_keys 的 "restrict" 关键字也正确应用于隧道转发(管理上默认禁用)。由中国科学院计算技术研究所的 Erichen 报告。

新特性

  • ssh-keygen(1):重置私钥口令时,可设置或清除 FIDO 私钥的 touch-required 和 verify-required 标志。
  • ssh(1):调整公钥认证中证书尝试顺序,优先尝试不需要用户在场(触摸)的 FIDO 密钥,最后尝试需要 PIN 或生物识别验证的 FIDO 密钥,即先试低摩擦认证器。
  • ssh(1):增加 "ssh -Z user@host" 模式,按使用顺序打印将尝试的公钥认证密钥。
  • sshd(8):使用 setproctitle(3) 标识作为认证后监视器的 sshd-session。

Bug 修复

  • ssh-keyscan(1):将读取服务器 banner 改为非阻塞操作,防止卡住的服务器阻塞多主机扫描。
  • sshd(8):包代码错误时使用 sshpkt_fatal() 而非普通 fatal(),以提供失败对端(地址、端口、用户等)的上下文。
  • sshd(8):为客户端 UpdateHostKeys 请求签署 hostkey 证明时,允许每个 hostkey 最多执行一次签名操作。
  • sshd(8):修复 10.4 中 servconf.c 重构导致的 GSSAPI 选项名问题。bz3974。
  • ssh-keygen(1):回传 ed25519 密钥生成错误,该过程理论上可能失败。GHPR702。
  • sshd(8):在解析对端发送的密钥之前,先检查公钥类型是否在允许算法中,减少认证前攻击面。由 Anthropic 的 Christopher Paul Rohlf 提出。
  • ssh-keygen(1):修复双重释放,并在可能时使用 freezero。来自 Anthropic 的 Christopher Paul Rohlf。
  • sshd(8):修复 ChannelTimeout 和 RekeyLimit 在 sshd_config 的 Match 块中未被应用的问题。
  • sshd(8):sshd 配置导出模式下,所有指令以混合大小写写出以保持一致。

可移植性

  • sshd(8):重新允许在 Match 块中使用 PAMServiceName,10.4 重构时被误禁用。bz3987。

OpenSSH 10.4 / 10.4p1(2026-07-06)

OpenSSH 10.4 于 2026-07-06 发布。

潜在不兼容变更

  • sshd(8):配置导出模式("sshd -G")现在以混合大小写写出指令(如 "PubkeyAuthentication"),此前只输出小写。
  • sshd(8):在启用 seccomp 沙箱的 Linux 系统上,启用 SECCOMP 或 NONEWPRIVS 失败现在视为致命错误。此前 sshd 会记录错误并继续,以支持缺少这些特性的系统。现在这类系统应在配置时禁用沙箱。
  • ssh(1)、sshd(8):使传输协议更严格,如果对端在认证后密钥重新交换期间发送非 KEX 消息则断开。此前恶意对端可继续发送非密钥交换消息而不受惩罚,这些消息会被缓冲,浪费内存直到连接终止或达到内存限制。不按 RFC4253 第 7.1 节限制密钥交换期间消息的实现可能被断开。由 Marko Jevtic 报告。

自 OpenSSH 10.3 以来的变更

安全

  • sftp(1):命令行下载文件时("sftp host:/path ."),恶意服务器可使文件下载到意外位置。由 Swival Security Scanner 发现。
  • scp(1):在两个远程目标之间复制文件时,不允许恶意服务器把文件写到目标目录的父目录。由 Swival Security Scanner 发现。
  • sshd(8):使用 "internal-sftp" SFTP 服务器实现(非默认)时,长命令行此前会在第 9 个参数后静默截断。如果安全相关选项位于第 10 个或更后位置,会被丢弃。由 Steve Caffrey 报告。
  • sshd(8):增加文档说明:服务器加入 Windows Active Directory 时,GSSAPIStrictAcceptorCheck 选项无效。由 Safebreach 的 Yarin Aharoni 报告。
  • sshd(8):DisableForwarding=yes 未能如文档所述覆盖 PermitTunnel=yes(PermitTunnel 默认未启用)。由 Redhat 的 Huzaifa Sidhpurwala 和 Marko Jevtic 分别报告。
  • sshd(8):避免启用 GSSAPIAuthentication(默认关闭)时潜在的认证前拒绝服务。MaxAuthTries 无法缓解,但 PerSourcePenalties 会惩罚。由奥地利国防部 milCERT AT 的 Manfred Kaiser 报告。
  • sshd(8):修复多处未强制执行最小认证延迟的情况。由 Orange Cyberdefense 漏洞团队报告。
  • ssh(1):修复服务器在密钥重新交换期间更改主机密钥时客户端可能的释放后使用。由 Depthfirst 的 Zhenpeng (Leo) Lin 报告。

新特性

  • 所有组件:增加对 draft-miller-sshm-mldsa44-ed25519-composite-sigs 中指定的 ML-DSA 44 与 Ed25519 复合后量子签名方案的实验性支持。该方案默认不启用,需加入 HostKeyAlgorithms、PubkeyAcceptedAlgorithms 等。密钥可用 "ssh-keygen -t mldsa44-ed25519" 生成。
  • ssh(1)、sshd(8):用基于 NFA 的实现替换通配符模式匹配器,避免旧实现的指数级最坏情况。

Bug 修复

  • ssh-agent(1):修复对 "query" SSHAGENTCEXTENSION 请求的错误回复。bz3967。
  • sshd(8):避免在 GSSAPIAuthentication(默认禁用)中对有效和无效用户发送可观察到的不同消息。
  • ssh(1)、sshd(8):修复若干把批量流量错误归类为交互流量的 bug。bz3972、bz3958。
  • ssh-keygen(1)、ssh-add(1):从 FIDO 令牌下载常驻密钥时跳过不支持的类型,此前遇到一种会中止下载。GHPR657。
  • ssh(1):修复 cipher_init() 失败时错误路径上潜在的释放后使用。
  • sshd(8):对 sshd 特权分离子进程之间传递的传输状态进行更严格的编码和验证,进一步加固服务器以抵御对 sshd-auth 或 sshd-session 子进程的攻击。
  • ssh-agent(1):对密钥使用约束中的用户名长度施加限制,避免可能的运行时拒绝服务。
  • sftp(1):修复 SSH2FXPREALPATH 和批处理命令处理中两处单字节越界读取。
  • sftp-server(8):禁止使用 copy-data 扩展同时读写同一 inode。
  • ssh(1)、sshd(8):避免在发送 x11-req SSHMSGCHANNEL_REQUEST 之前创建 X11 信道时 strlen(NULL) 崩溃。GHPR679。
  • sftp(1)、scp(1):避免服务器在读取文件时反复返回零长度导致 sftp_download() 陷入循环。
  • ssh(1):避免 DNS0x20 大小写随机化名称泄漏到通过 CanonicalizePermittedCNAMEs 规范化的名称中。bz3966。
  • sftp-server(8):在 PATHMAX 并非实际最大值的系统上,避免 SSHFXP_REALPATH 处理中传给 lstat() 的路径名被截断。GHPR688。
  • ssh(1)、sshd(8):修正某些套接字类型信道的 poll(2) 事件掩码设置。GHPR660。
  • sshd(8):大规模重构 sshd_config 解析和管理代码,以便跨特权分离边界进行更精确的序列化/反序列化。
  • ssh-add(1):仅在 getopt() 处理完成后才连接 agent,让 "-v" 等选项有机会显示该操作的调试信息。
  • 加密代码:修复签名长度超过 sizet 容量时的边界检查。在 OpenSSH 中消息大小受 SSHBUFSIZE_MAX 限制,无法触发。
  • 加密代码:为 ed25519 验证增加签名可延展性和公钥有效性检查。SSH 不依赖这些属性。
  • 加密代码:修复 cofactor != 1 的曲线的 ECDSA 阶检查。所有支持的 EC 曲线 cofactor 均为 1,无法触发。
  • sshd(8):在记录子系统启动失败原因时,区分执行失败和未找到子系统。GHPR637。
  • 所有组件:对 timegm(3) 和 mktime(3) 的错误检测使用更安全的写法。
  • ssh(1)、sshd(8):避免接受配置文件或命令行中无效的 cipher 或 MAC 列表,否则可能导致后续运行时失败。
  • ssh(1):修复使用 PEM 风格私钥且旁边没有对应 .pub 公钥时,公钥认证过程中的 NULL 解引用崩溃。
  • sshd(8):使用 PKCS#11 密钥时,尝试加载主机私钥不再打印错误消息,因为这类密钥不需要文件系统上的私钥部分。GHPR664。
  • 所有组件:不再使用已弃用的 ERRloadcrypto_strings()。GHPR650。
  • ssh(1):正确报告配置默认值设置期间的错误。GHPR649。
  • ssh(1):错误消息中使用正确的指令名(Match 而非 Host)。bz3968。
  • sftp(1):修复 "ls -ln" 未正确显示数字 UID/GID,而是显示用户名和组名。bz3953。
  • sshd(8):避免配置解析期间分配失败时可能的 NULL 解引用。bz3948。
  • 所有组件:修复多处对加载超大公钥的防护失效。bz3969 和 bz3970。
  • sftp(1):确保 sftp 用于与其 ssh(1) 子进程通信的文件描述符不会泄漏到执行的子进程(例如通过 "!")。GHPR693。

可移植性

  • 与 OpenBSD 上游同步 fmt_scaled.c,修复大指数下的精确性问题(GHPR671)。
  • sshd(8):移除 clock_gettime64 的重复沙箱条目。
  • ssh(1)、sshd(8):如果系统头文件未提供,使用正确的 IPTOSDSCPVA 值。
  • 与 OpenBSD 上游同步 getrrsetbyname.c,引入健壮性修复。
  • 在 openbsd-compat 中禁用 strvisx(3) 和 stravis(3) 的替换,OpenSSH 中未使用。
  • 避免 Android 上的 fortify 警告。bz3954。
  • 修复可移植性代码错误路径上的多处内存泄漏。GHPR681。
  • 修订 README.privsep 文档,反映 sshd 近期转向多二进制模型。

OpenSSH 10.3 / 10.3p1(2026-04-02)

OpenSSH 10.3 于 2026-04-02 发布。

潜在不兼容变更

  • ssh(1)、sshd(8):移除对不支持重新密钥的实现的 bug 兼容。这类实现与 OpenSSH 互操作时,在传输需要重新密钥时会最终失败。
  • sshd(8):此前,当证书的 principals 段为空时,通过 authorizedkeys 的 principals="" 选项使用会被视为匹配任意 principal(即通配符)。这是有意行为,但如果 CA 意外签发了 principals 段为空的证书,后果令人意外且可能有风险:它并非如预期那样无用,而是可用来以任何通过 authorizedkeys 信任该 CA 的用户身份认证。(注意这不适用于通过 sshd_config 的 TrustedUserCAKeys 选项信任的 CA。)本版本将空 principals 段视为永不匹配任何 principal,并修正证书 principals 中通配符的解释:主机证书统一实现,用户证书不支持。
  • ssh(1):-J 及等效的 -oProxyJump="..." 选项现在会验证命令行传入的 ProxyJump/-J 的用户名和主机名(配置文件中的该选项不做此类验证)。防止这些参数直接暴露给对抗性输入时出现 shell 注入。由 rabbit 报告。

自 OpenSSH 10.2 以来的变更

安全

  • ssh(1):命令行提供的用户名中 shell 元字符的验证执行得太晚,无法阻止某些情况下它们通过 ssh_config 的 %-token 展开。对于某些配置(例如在 "Match exec" 块中使用 "%u" token),能控制传给 ssh(1) 的用户名的攻击者可能执行任意 shell 命令。由 Florian Kohnhäuser 报告。
  • sshd(8):将 authorizedkeys 的 principals="" 选项与证书中的 principal 列表匹配时使用了错误算法,当证书中的 principal 名包含逗号时可能导致不当匹配。利用需要 authorizedkeys 的 principals="" 选项列出多个 principal,且 CA 会签发以逗号分隔多个 principal 名的证书(典型 CA 会严格限制)。这只适用于 authorized_keys 中用户信任的 CA 密钥,主证书认证路径(TrustedUserCAKeys/AuthorizedPrincipalsFile)不受影响。由 Vladimir Tokarev 报告。
  • scp(1):以 root 身份在旧式(-O)模式下下载文件、未设置 -p(保留模式)标志时,scp 未如预期清除下载文件的 setuid/setgid 位。该 bug 可追溯到最初的 Berkeley rcp 程序。由 Cantina 和 Spearbit 的 Christos Papakonstantinou 报告。
  • sshd(8):修复 PubkeyAcceptedAlgorithms 和 HostbasedAcceptedAlgorithms 对 ECDSA 密钥应用不完整的问题。此前如果这些指令包含任何 ECDSA 算法名(如 "ecdsa-sha2-nistp384"),则任何其他 ECDSA 算法都会被接受,无论是否列出。由 Cantina 和 Spearbit 的 Christos Papakonstantinou 报告。
  • ssh(1):连接复用确认(通过 "ControlMaster ask/autoask" 请求)未对代理模式复用会话(即 "ssh -O proxy ...")进行测试。由 Michalis Vasileiadis 报告。

新特性

  • ssh(1)、sshd(8):支持 IANA 分配的 SSH agent 转发码点,依据 draft-ietf-sshm-ssh-agent。新名称的支持通过 EXT_INFO 消息通告。如果服务器支持新名称,则优先使用。对标准化前的 "@openssh.com" agent 转发扩展的支持仍然保留。
  • ssh-agent(1):实现 draft-ietf-sshm-ssh-agent 的 "query" 扩展支持。
  • ssh-add(1):通过新的 -Q 标志支持用 agent "query" 扩展查询协议扩展。
  • ssh(1):支持 ssh_config RevokedHostKeys 指令指定多个文件。bz3918。
  • sshd(8):支持 sshd_config RevokedKeys 指令指定多个文件。bz3918。
  • ssh(1):增加 ~I 转义选项,显示当前 SSH 连接的信息。
  • ssh(1):增加 "ssh -Oconninfo user@host" 复用命令,显示连接信息,类似 ~I 转义符。
  • ssh(1):增加 "ssh -O channels user@host" 复用命令,让运行中的 mux 进程显示当前打开的信道信息。
  • sshd(8):为 PerSourcePenalties 增加 'invaliduser' 惩罚,应用于使用不匹配真实账户的用户名的登录尝试。默认 5 秒,与 'authfail' 一致,管理员可设更长。
  • sshd(8):为服务器增加 GSSAPIDelegateCredentials 选项,控制是否接受客户端提供的委派凭据。该选项与 ssh_config 中的同名选项对应。GHPR614。
  • ssh(1)、sshd(8):支持 IPQoS 指令中的 VA DSCP 码点。
  • sshd(8):将 PerSourcePenalties 改为使用浮点时间,允许小于一秒的惩罚。适用于需要惩罚预期 >=1 QPS 事件的情况。
  • ssh-keygen(1):支持以 PKCS8 格式写入 ED25519 密钥。GHPR570。
  • 通过 libcrypto 支持 ed25519 签名方案。

Bug 修复

  • sshd(8):使 IPQoS 在 sshd_config 中首次匹配优先,与其他配置指令一致。bz3924。
  • sshd(8):修复 MaxStartups 使用单参数形式(非 x:y:z)且值低于 10 时潜在的崩溃。bz3941。
  • sshd(8):修复 /etc/moduli 中缺少所需 DH 群值时密钥交换期间潜在的挂起。
  • ssh-agent(1):修复扩展返回值,使其符合 draft-ietf-sshm-ssh-agent:扩展请求应使用 SSHAGENTEXTENSIONFAILURE 而非通用 SSHAGENT_FAILURE 表示失败。这让客户端能区分"请求失败"和"agent 不支持该扩展"。
  • ssh(1):使用 fmprintf 显示 challenge-response 名称和信息,以适当保留 UTF-8 字符。GitHub PR#452 提示。
  • scp(1):使用 sftp/sftp 上传目录(例如递归传输)时,除非目录是传输期间创建的或设置了 -p 标志,否则不再覆盖远程目录权限。bz3925。
  • 所有组件:实现 FIDO/webauthn 签名支持缺失的部分,主要涉及证书处理,并默认接受该签名格式。bz3748、GHPR624、GHPR625。
  • sshd_config(5):明确说明 DenyUsers/DenyGroups 覆盖 AllowUsers/AllowGroups。此前只规定指令处理顺序,两者都匹配时行为含糊。
  • ssh(1):不再尝试把 agent 中的证书与私钥匹配。该匹配用于支持未同时加载私钥的证书,但对 agent 托管的证书(私钥始终在 agent 中可用)不必要。更糟的是,这种匹配会打乱发给 agent 的请求,导致在 agent 中限制了密钥用途时这些密钥无法使用。bz3752。
  • sftp(1):如果 editline 已切换到 vi 模式(例如通过 .editrc 中的 "bind -v"),设置键绑定以便进入命令模式。
  • ssh(1)、sshd(8):改进 sntrup761 密钥协商算法的密钥计算性能。
  • ssh(1)、sshd(8):在认证前阶段强制执行最大包/块限制。
  • sftp(1):不再误用 sftp limits 扩展的 open-handles 字段。该值应是服务器允许打开的句柄数,而非上传/下载期间可发送的未完成读写请求数。
  • sshd(8):当主 sshd_config 没有任何 Subsystem 指令但 Match 块中定义了子系统时,连接时不再崩溃。bz3906。
  • sshd_config(5):在 ForceCommand 指令旁增加警告:强制命令不会自动禁用转发。
  • sshd_config(5):增加警告:TOKEN 的替换不做过滤或转义,管理员有责任确保在上下文中安全使用。
  • scp(1):修复本地到本地复制时详细输出中文件名引号问题。bz3900。
  • sshd(8):修复 PerSourceNetBlockSize IPv6 掩码在 sscanf 未解析时被搞乱。GHPR598。
  • ssh-add(1):加载 FIDO2 常驻密钥时,把注释设为 FIDO 应用字符串,与 ssh-keygen -K 行为一致。GHPR608。
  • sshd(8):不再对将由 sshd-auth 通过父进程 sshd-session 记录的日志消息执行 strnvis(),因为父进程也会执行。防止某些日志消息中非打印字符被双重转义。bz3896。
  • ssh-agent(1):对作为 setenv 命令发送给 shell 的 SSHAUTHSOCK 路径进行转义。修复主目录路径包含空白字符时 ssh-agent 失效的问题。bz3884。
  • 所有组件:移除不必要的 ECDSA 公钥有效性检查。
  • sshd(8):仅在最后一个信道关闭后激活 UnusedConnectionTimeout。此前 UnusedConnectionTimeout 可能在 ChannelTimeout 后过早触发。这对 OpenSSH 客户端不是问题(所有信道关闭后即终止),但可能影响其他客户端(如 API 客户端)。bz3827。
  • 所有组件:修复 10.1/10.2 引入的 PKCS#11 密钥 PIN 输入问题。bz3879。
  • scp(1):使用 SFTP 协议传输时,修复源路径以 ".." 结尾时隐式目标路径的选择。bz3871。
  • sftp(1):文件名 Tab 补全时,确保补全字符串不会停在多字节字符中间,否则后续会 fatal()。GHPR#587。
  • ssh-keygen(1):修复加载多个密钥时退出崩溃(通过 ssh-keygen -D 可见)。
  • scp(1)/sftp(1):进度条正确显示超过 2GBps 的带宽。

可移植性

  • sshd(8):修复 10.2p1 稳定分支引入的情况:PAM 模块在认证期间于 SSHMSGUSERAUTH_REQUEST 消息之间更改请求的用户名,可能迷惑 PAM 栈,使其对活动用户名的理解与 sshd 其余部分不同。由 Mike Damm 报告。
  • sshd(8):使用 PAM 的 keyboard-interactive 认证时,立即向客户端报告交互式指令。bz2876。
  • sshd(8):修复某些情况下 PAM 消息重复。
  • sshd(8):重复调用不再泄漏 PAM handle。bz3882。
  • 所有组件:支持需要 libstdc++ 的 libcrypto 实现(如 BoringSSL)。
  • sshd(8):修复 btmp 记录的 uttype,正确使用 LOGINPROCESS 和 USER_PROCESS。
  • sshd(8):允许 seccomp 沙箱中使用 uname(3)。RISC-V 平台上的 zlib-ng 需要。
  • 所有组件:移除剩余的 OpenSSLaddall_algorithms() 调用。GitHub PR#606 提示。
  • 所有组件:修复旧 Mac OS 上 nfds_t 相关的构建问题。
  • mdoc2man:若干改进,包括更好支持 Ic 中的 Dl 和 Ns。

OpenSSH 10.2 / 10.2p1(2025-10-10)

OpenSSH 10.2 于 2025-10-10 发布。

未来弃用警告

  • 未来版本将因 SHA1 哈希函数的弱点弃用对 SHA1 SSHFP 记录的支持。SHA1 SSHFP DNS 记录将被忽略,ssh-keygen -r 将只生成 SHA256 SSHFP 记录。无已知弱点的 SHA256 自 2012 年 OpenSSH 6.1 起已支持 SSHFP。

自 OpenSSH 10.1 以来的变更

这是 bug 修复版本,主要修复启用 ControlPersist 时 ssh(1) 不可用的问题。

Bug 修复

  • ssh(1):修复 ControlPersist 激活时终端连接处理不当导致会话不可用。bz3872。
  • ssh-keygen(1):修复从 PKCS#11 令牌下载密钥。
  • ssh-keygen(1):修复 CA 密钥保存在 ssh-agent(1) 中的签名操作。bz3877。

可移植性

  • 所有组件:支持没有 mmap(2) 的平台,例如 https://hterm.org 之类的 WASM 构建。
  • 所有组件:修复 FreeBSD 上缺少 fnctl.h 包含导致的构建问题。
  • 所有组件:修复 MacOS <10.12 Sierra(缺少 clock_gettime(3))上的构建。
  • sshd(8):远程主机为 "UNKNOWN" 占位名时不再设置 PAM_RHOST,避免某些 PAM 模块尝试解析时挂起。sshd 仅在连接不经过 IPv4 或 IPv6 套接字时使用 "UNKNOWN"。

OpenSSH 10.1 / 10.1p1(2025-10-06)

OpenSSH 10.1 于 2025-10-06 发布。

未来弃用警告

  • 与 10.2 相同的 SHA1 SSHFP 弃用警告。

潜在不兼容变更

  • ssh(1):协商到非后量子密钥协商算法时增加警告。此警告针对"先存储、后解密"攻击的风险,详情见 https://openssh.com/pq.html。可通过新的 WarnWeakCrypto ssh_config 选项控制,默认开启。该选项未来可能控制更多弱加密警告。
  • ssh(1)、sshd(8):DSCP 标记/IPQoS 处理有重大变化。客户端和服务端的默认 DSCP(即 IPQoS)值已修订,运行时使用方式也已改变。交互流量默认分配到 EF(加速转发)类,为中间网络(如无线介质,参考 RFC 8325)提供更合适的包优先级信息。非交互流量使用操作系统默认 DSCP 标记。两者的 DSCP 值都可通过 IPQoS 关键字覆盖。连接生命周期中会自动选择并更新合适的 DSCP 标记,ssh 和 sshd 会根据当前打开的 SSH 信道类型在交互和非交互 IPQoS 值之间切换。例如 sftp 会话与 shell 会话共用连接时,sftp 期间使用非交互值;只包含交互会话的连接标记为 EF。
  • ssh(1)、sshd(8):弃用 IPQoS 配置指令中对 IPv4 服务类型(ToS)关键字的支持。ToS 在九十年代末已被弃用,由区分服务体系取代,后者粒度更细。OpenSSH 在 2018 年(7.7)已将默认 IPQoS 从 ToS 改为 DSCP 值。包含 'lowdelay'、'reliability' 或 'throughput' 的 IPQoS 配置将被忽略,改用系统默认 QoS 设置,并会记录一条弃用调试消息,建议改用 DSCP QoS。
  • ssh-add(1):向 agent 添加证书时,将过期时间设为证书过期时间加上短暂(5 分钟)宽限期。这会让 agent 在证书过期后不久自动移除它们。新的 ssh-add -N 选项禁用此行为。
  • 所有组件:移除对 XMSS 密钥的实验性支持。该功能从未默认启用。预计不久将实现新的后量子签名方案。
  • ssh-agent(1)、sshd(8):将 agent 监听套接字从 /tmp 移到 ~/.ssh/agent 下,ssh-agent(1) 和 sshd(8) 中的转发套接字都如此。这确保文件系统访问受限(包括 /tmp)的进程不会天然具有使用 agent 中密钥的能力。移动默认目录后,操作系统不再清理陈旧的 agent 套接字,因此 ssh-agent 现在具备此能力。为支持 NFS 上的 $HOME,套接字路径包含主机名的截断哈希。ssh-agent 默认只清理同一主机名的套接字。ssh-agent(1) 新增标志:-U 在启动时抑制自动清理陈旧套接字;-u 强制清理但不保留运行中的 agent;-uu 强制清理且忽略主机名;-T 让 ssh-agent 把套接字放回 /tmp。

自 OpenSSH 10.0 以来的变更

安全

  • ssh(1):禁止命令行传入或通过配置文件的 %-序列展开的用户名包含控制字符,并禁止 ssh:// URI 中的 \0 字符。如果 ssh(1) 命令行由不可信来源的用户名或 URI 构造,且配置了使用 %r 展开的 ProxyCommand,攻击者可能注入在代理命令启动时执行的 shell 表达式。团队强烈建议不要用不可信输入构造 ssh(1) 命令行。此变更也略微放宽了有效性检查:配置文件中以字面量形式提供的用户名(不含 % 展开字符)不受这些检查限制,允许包含任意字符的用户名,但仅通过配置文件。理由是 ssh 配置是可信的。由 David Leadbeater 报告。

新特性

  • ssh(1)、sshd(8):增加 SIGINFO 处理程序,记录活动信道和会话信息。
  • sshd(8):拒绝用户认证证书时,除拒绝原因外,还记录足以识别证书的信息,便于调试证书授权问题。
  • ssh(1)、ssh-agent(1):支持托管在 PKCS#11 令牌上的 ed25519 密钥。
  • ssh(1):增加 ssh_config RefuseConnection 选项,在处理活动配置段时遇到会以错误信息终止 ssh(1),信息包含该选项的参数。可用于在配置文件中表达提醒或警告,例如 Match host foo / RefuseConnection "foo is deprecated, use splork instead"。
  • sshd(8):X11 显示号检查相对于 X11DisplayOffset,让用户可用 X11DisplayOffset 配置更高的端口范围,而不改变默认行为。
  • 单元测试:单元测试框架增加基本基准测试能力。在 OpenBSD 上用 "make UNITTEST_BENCHMARK=yes",在可移植 OpenSSH 上用 "make unit-bench"。

Bug 修复

  • sshd(8):修复某些情况下 MaxStartups 进程退出跟踪错误,最坏可能填满所有 MaxStartups 槽位并拒绝新连接。
  • ssh(1):修复启用 ObscureKeystrokeTiming 时 X 客户端启动延迟。bz#3820。
  • sshd(8):支持的最大配置从 256KB 提升到 4MB,超出时尽早显式失败。bz3808。
  • sftp(1):sftp 上传时,避免后续写入成功而忽略此前失败写入的情况。虽然不太可能,但技术上可能,因为 sftp 服务器允许重排请求。
  • sshd(8):避免 sshd-auth 进程退出时可能导致虚假错误消息的竞态。
  • sshd(8):PerSourcePenalties 实际阻止某来源地址范围访问时,以 INFO 级别记录。此前以 VERBOSE 级别记录,默认配置下会隐藏执行动作。
  • sshd(8):GssStrictAcceptor 缺失于 sshd -T 输出,已修复。
  • sshd(8):使 MaxStartups 和 PerSourceNetBlockSize 选项如文档所述首次匹配优先。bz3859。
  • ssh(1):修复本地转发取消路径中错误的返回值检查,导致失败的取消未被记录。
  • sshd(8):使 "Match !final" 不触发 ssh_config 的第二次解析(除非主机名规范化或单独的 "Match final" 触发)。bz3843。
  • ssh(1):改进加载密钥时的调试诊断。现在列出密钥指纹和算法(不只是算法编号),并明确哪些密钥未加载。
  • 所有组件:修复 LeakSanitizer、Coverity 和人工检查发现的内存泄漏。
  • sshd(8):sshd -T 输出 PermitRootLogin 当前名称 "prohibit-password",而非已弃用别名 "without-password"。bz#3788。
  • ssh(1):通过一次操作写入整行并使用无缓冲 stdio,使 known_hosts 行写入更原子化。

可移植性

  • sshd(8):检查 PAM 事务期间用户名未更改。
  • sshd(8):不再用 UNKNOWN 主机名记录审计消息,避免审计子系统慢速 DNS 查询。
  • 所有组件:复制 struct passwd 时确保字段非 NULL。例如 Android libc 可能返回 NULL pw_gecos。
  • 所有组件:移除 OpenSSL >=3 版本检查中的状态位。
  • sshd(8)、ssh(1):在 FreeBSD 上使用 SSHTUNCOMPAT_AF。否则其他操作系统发起 tun 转发时,一旦对方发送第一条 IPv6 消息(通常是接口启用后立即发送的路由器请求 ICMPv6 消息)就会失败。
  • ssh(1)、ssh-agent(8):在使用 nlist 函数前检查其是否存在,而不只依赖 nlist.h 头文件。
  • 所有组件:补齐缺失的系统头文件。
  • sshd(8):在 seccomp 沙箱中正确处理 futex_time64。
  • 增加 contrib/gnome-ssh-askpass4,使用 GCR API 支持 GNOME 40+。
  • sshd(8):getgrouplist 失败时让 ga_init() 优雅失败。OSX 上传入不存在的组名可能失败,其他平台似乎返回包含所传数字 gid 的组列表。bz3848。
  • ssh-agent(1):systemd 套接字激活下收到 SIGTERM 退出码为 0,防止通过 systemd 优雅关闭 agent 时服务被错误标记为 "failed"。
  • 构建:将一些 autoconf 宏包裹在 ACCACHECHECK 中,可跳过/覆盖用于检测编译器或链接器标志的 OSSHCHECKCFLAGCOMPILE 和 OSSHCHECKCFLAGLINK 宏。

OpenSSH 10.0 / 10.0p2(2025-04-09)

OpenSSH 10.0 于 2025-04-09 发布。

潜在不兼容变更

  • 此版本移除对弱 DSA 签名算法的支持,完成 2015 年开始的弃用过程。
  • scp(1)、sftp(1):调用 ssh 时传递 "ControlMaster no"。当配置中 ControlMaster 设为 yes/auto 时,禁用这些工具隐式创建会话,某些用户对此感到意外。此变更不阻止 scp/sftp 使用已创建的多路复用会话。GHPR557。
  • 此版本版本号为 10.0,宣告自身为 "SSH-2.0-OpenSSH10.0"。用 "OpenSSH1*" 之类模式朴素匹配版本的软件可能困惑。
  • sshd(8):将协议用户认证阶段的代码从每连接的 sshd-session 二进制移到新的 sshd-auth 二进制。分离此代码确保关键的认证前攻击面与连接其余部分使用的代码地址空间完全不相交,并在认证阶段完成后卸载认证代码,带来少量运行时内存节省。用户基本无感,但某些日志消息现在可能来自 "sshd-auth" 而非 "sshd-session"。下游发行版需要打包 sshd-auth 二进制。
  • sshd(8):默认禁用有限域(modp)Diffie-Hellman 密钥交换。具体从默认 KEXAlgorithms 列表中移除 "diffie-hellman-group" 和 "diffie-hellman-group-exchange-" 方法。客户端不变,默认继续支持。有限域 DH 在达到与 ECDH 或 PQ 密钥协商相同安全级别时速度慢、计算昂贵,且没有补偿性优势。
  • sshd(8):当 moduli 文件存在但不包含客户端请求范围内的 moduli 时,移除对编译内置 DH-GEX 群的隐式回退。文件完全不存在时仍保留回退行为。这让管理员能更明确控制选择哪些 DH 群,但如果 moduli 文件编辑错误可能导致连接失败。bz#2793。

自 OpenSSH 9.9 以来的变更

安全

  • sshd(8):修复 DisableForwarding 指令未能如文档所述禁用 X11 转发和 agent 转发的问题。服务器默认禁用 X11 转发,客户端默认关闭 agent 转发。

新特性

  • ssh(1):混合后量子算法 mlkem768x25519-sha256 现在默认用于密钥协商。该算法被认为可抵抗量子计算机攻击,强度不低于流行的 curve25519-sha256,已由 NIST 标准化,且比此前默认算法快得多。
  • ssh(1):选择连接密码时优先 AES-GCM 而非 AES-CTR。默认密码偏好顺序为 Chacha20/Poly1305、AES-GCM(128/256),然后是 AES-CTR(128/192/256)。
  • ssh(1):为 ssh_config 的 SetEnv 指令增加 %-token 和环境变量展开。
  • ssh(1):允许 ssh_config 的 User 指令进行 %-token 和环境变量展开,但 %r 和 %C 除外(会自引用)。bz#3477。
  • ssh(1)、sshd(8):sshconfig 和 sshdconfig 增加 "Match version" 支持,可匹配本地 OpenSSH 版本,例如 "Match version OpenSSH_10.*"。
  • ssh(1):ssh_config 增加 "Match sessiontype" 支持,可匹配最初请求的会话类型:"shell"(交互会话)、"exec"(命令执行)、"subsystem"(如 sftp)或 "none"(仅传输/转发)。
  • ssh(1):ssh_config 增加 "Match command ..." 支持,可匹配命令行指定的远程命令。
  • ssh(1):允许 'Match tagged ""' 和 'Match command ""' 分别匹配空 tag 和命令值。
  • sshd(8):允许 sshd_config 的 AuthorizedKeysFile 和 AuthorizedPrincipalsFile 指令使用 glob(3) 模式。bz2755。
  • sshd(1):客户端支持 VersionAddendum,与服务器同名选项对应。bz2745。
  • ssh-agent(1):收到 SIGUSR1 时删除所有已加载密钥。无需访问 $SSHAUTHSOCK 即可删除密钥。
  • 可移植 OpenSSH、ssh-agent(1):使用 LISTENPID/LISTENFDS 机制支持 systemd 风格套接字激活。设置这些环境变量、以 -d 或 -D 选项启动且未设套接字路径时激活。GHPR502。
  • ssh-keygen(1):支持不返回证明数据的 FIDO 令牌,例如较新的 WinHello。GHPR542。
  • ssh-agent(1):增加 "-Owebsafe-allow=..." 选项,覆盖默认的 FIDO 应用 ID 允许列表。
  • 增加一个进行中的工具,用于验证 ssh-keygen 注册 FIDO 密钥时可选写入的 FIDO 证明 blob。该工具位于 regress/misc/ssh-verify-attestation,供实验,不通过 "make install" 安装。
  • ssh-keygen(1):允许用 "-" 作为 moduli 筛选的输出文件。GHPR393。

Bug 修复

  • sshd(8):移除 sshd_config 及其包含的任何配置能放入(可能扩大的)套接字缓冲区的假设。此前足够大的配置可能导致 sshd 无法接受任何连接。sshd 现在主动管理向 sshd-session 子进程发送配置。
  • ssh(1):如果 X11 转发信道最近有流量,不启动 ObscureKeystrokeTiming 缓解。应修复启用此设置时的 X11 转发性能问题。bz3655。
  • ssh(1):禁止接受的主机名包含逗号,但允许下划线作为主机名的第一个字符。
  • sftp(1):恢复 "put" 时设置 high-water,防止虚假的 "server reordered acks" 调试消息。
  • ssh(1)、sshd(8):修复 9.8 的回归:sshconfig 和 sshdconfig 中未接受 "Match criteria=argument" 以及文档中的 "Match criteria argument" 语法。bz3739。
  • sftp(1)、ssh(1):修复若干可能的 NULL 解引用 bug,包括 Coverity CID 405019 和 477813。
  • sshd(8):修复超过 LoginGraceTime 时 PerSourcePenalty 错误使用 "crash" 惩罚。bz3797。
  • sshd(8):修复初始配置传递中 "Match invalid-user" 在没有其他谓词出现在匹配行时被错误激活。
  • sshd(8):修复用户特定延迟的调试日志。GHPR#552。
  • sshd(8):改进跨子进程边界的调试日志。此前 sshd-auth 和 sshd-session 进程早期的一些日志消息会丢失。
  • ssh(1):要求通过 '-e ^x' 命令行传入的控制转义字符序列恰好两个字符长。避免以 "ssh -e^ ..." 调用时单字节越界读取。GHPR368。
  • ssh(1)、sshd(8):防止 X11 端口处理中的整数溢出。bz#3730。
  • ssh-keygen(1):文件含 CR 字符时不再搞乱 ssh-keygen -l 输出。GHPR236、bz3385。
  • sshd(8):对 PerSourcePenalties 丢弃连接的日志增加速率限制。此前日志可能很吵。
  • ssh(1):修复 ssh -G 配置导出中 "Compression" 指令的参数,9.8 中回归。
  • sshd(8):修复 UpdateHostKeys 在 sshd 拒绝 agent 持有的主机密钥在主机密钥轮转子协议中返回的签名时的角落情况。当使用不支持特定签名算法的 PKCS#11 智能卡存储主机密钥时可能出现。
  • ssh-keygen(1):使用 RSA 密钥以 "ssh-keygen -Y" 签名时,根据请求的哈希算法("-Ohashalg=xxx")选择签名算法。允许使用非默认的 rsa-sha2-512,因为并非所有签名后端都支持。
  • ssh(1)、sshd(8)、ssh-keyscan(1):修复大端系统上的 ML-KEM768x25519 KEX。
  • 许多回归和互操作测试改进。

可移植性

  • 所有组件:增加对 AWS-LC(AWS libcrypto)的支持。bz3784。
  • sshd(8):增加 wtmpdb 支持,作为 Y2038 安全的 wtmp 替代。
  • sshd(8):增加将 sshd 锁定到内存的支持,通过 --with-linux-memlock-onfault 配置标志启用。
  • 增加构建独立 sk-libfido2 库的支持,通过 --with-security-key-standalone 启用。
  • ssh(1)、sshd(8)、ssh-keyscan(1):为缺少 _builtinpopcount 的编译器包含替代函数。
  • 所有组件:分别检查并替换 le32toh、le64toh、htole64。glibc 的某些 endian.h 版本缺少后两者。bz#3794。
  • 移除 RPM spec 中古老的 RHL 6.x 配置。

OpenSSH 9.9p2(2025-02-18)

OpenSSH 9.9p2 于 2025-02-18 发布,修复两个安全 bug。

安全

  • 修复 CVE-2025-26465:OpenSSH 6.8p1 至 9.9p1(含)的 ssh(1) 存在逻辑错误,当启用 VerifyHostKeyDNS 选项时(默认关闭),允许路径上的攻击者(即 MITM)冒充任意服务器。
  • 修复 CVE-2025-26466:OpenSSH 9.5p1 至 9.9p1(含)的 sshd(8) 在处理 SSH2MSGPING 包时存在内存/CPU 拒绝服务漏洞。可使用现有 PerSourcePenalties 功能缓解。

两个漏洞均由 Qualys 安全咨询团队发现并证明可利用。OpenBSD 的修复作为 errata 提供。

Bug 修复

  • ssh(1)、sshd(8):修复 Match 指令的回归:谓词与参数用 '=' 而非空白分隔时失败。bz3739。
  • sshd(8):修复 "Match invalid-user" 谓词在配置评估初始传递中错误匹配。
  • ssh(1)、sshd(8)、ssh-keyscan(1):修复大端系统上的 mlkem768x25519-sha256 密钥交换。
  • 修复特定操作系统/配置上的若干构建问题。

OpenSSH 9.9 / 9.9p1(2024-09-19)

OpenSSH 9.9 于 2024-09-19 发布。

未来弃用通知

OpenSSH 计划 2025 年初移除对 DSA 签名算法的支持,本版本在编译时默认禁用 DSA。DSA 本质上较弱:私钥限于 160 位并使用 SHA1 摘要,估计安全级别仅相当于 80 位对称加密。OpenSSH 自 2015 年起默认禁用 DSA 密钥,但保留运行时可选支持。DSA 是 SSHv2 RFC 中唯一强制实现的算法,主要因为 SSHv2 规范制定时替代算法受专利限制。这种情况已过去几十年,所有活跃维护的 SSH 实现都良好支持更好的算法。移除 DSA 支持的最后一步计划在 2025 年第一个 OpenSSH 版本。OpenBSD 可通过 Makefile.inc 中 "DSAKEY=yes" 重新启用,可移植版可通过 --enable-dsa-keys 配置选项启用。

潜在不兼容变更

  • ssh(1):移除对认证前压缩的支持。服务器多年前已只支持认证后压缩。认证前压缩显著增加 SSH 服务器攻击面,可能产生泄漏认证期间信息的预言机。
  • ssh(1)、sshd(8):对 "Match" 配置指令参数的处理现在遵循更接近 shell 的引号规则,包括允许嵌套引号和 -转义字符。如果配置中为旧式简单引号处理做了变通,可能需要调整。最可能出现在 "Match exec" 条件的参数中。这种情况下,把要评估的命令从 Match 行移到外部 shell 脚本是最简单的兼容新旧版本的方法。

新特性

  • ssh(1)、sshd(8):增加基于 FIPS 203 模块格密钥封装机制(ML-KEM)与 X25519 ECDH 结合的新混合后量子密钥交换,如 https://datatracker.ietf.org/doc/html/draft-kampanakis-curdle-ssh-pq-ke-03 所述。该算法 "mlkem768x25519-sha256" 默认可用。
  • ssh(1):ssh_config 的 "Include" 指令现在可展开环境变量以及 "Match Exec" 支持的同一组 %-token。
  • sshd(8):增加 sshd_config "RefuseConnection" 选项,设置后会在第一个认证请求时终止连接。
  • sshd(8):为 sshd_config PerSourcePenalties 增加 "refuseconnection" 惩罚类,在连接被新的 RefuseConnection 关键字丢弃时应用。
  • sshd(8):为 sshd_config Match 选项增加 "Match invalid-user" 谓词,当目标用户名在服务器上无效时匹配。
  • ssh(1)、sshd(8):将 Streamlined NTRUPrime 代码更新为快得多的实现。
  • ssh(1)、sshd(8):混合 Streamlined NTRUPrime/X25519 密钥交换算法除 "@openssh.com" 厂商扩展名外,现在还有 IANA 分配的名称 "sntrup761x25519-sha512"。
  • ssh(1)、sshd(8)、ssh-agent(1)、ssh-keygen(1):防止私钥在其生命周期的大部分时间内被包含进核心转储文件。这是在 ssh-agent 和 sshd 已有防核心转储控制之外的补充。支持 OpenBSD、Linux 和 FreeBSD。
  • 所有组件:将密钥处理转换为使用 libcrypto EVP_PKEY API,DSA 除外。
  • sshd(8):为宽限登录时间增加随机抖动(最多 4 秒),使其到期不可预测。

Bug 修复

  • sshd(8):将绝对路径要求放宽回 9.8 之前的状态,9.8 曾错误要求在 inetd 模式下以绝对路径启动 sshd。bz3717。
  • sshd(8):修复 9.8 引入的回归:某些 sshd 日志消息中源地址和目标地址顺序被交换。
  • sshd(8):签名验证失败时不应用 authorizedkeys 选项。防止更严格的密钥选项被错误应用于 authorizedkeys 中后续的密钥。bz3733。
  • ssh-keygen(1):在部分口令提示中包含路径名,帮助用户了解通过其他工具调用 ssh-keygen 时的情况。GHPR503 请求。
  • ssh(1)、ssh-add(1):解析 user@host 时一致地查找字符串中最后一个 '@' 而非第一个,便于一致地使用包含 '@' 的用户名。
  • ssh(1)、sshd(8):更严格解析密钥类型名。用户界面代码中只允许短名称(如 "rsa"),其他所有地方要求完整 SSH 协议名(如 "ssh-rsa")。bz3725。
  • regress:重新密钥回归测试的性能和正确性多项改进。
  • ssh-keygen(1):明确默认生成 ed25519 密钥类型,并明确使用 RSA 时默认签名方案为 rsa-sha2-512。GHPR505。
  • sshd(8):修复 Subsystem 选项解析中的小内存泄漏。GHPR515。
  • 所有组件:对 sshbuf 代码增加额外加固和一致性检查。
  • sshd(8):降低默认 logingrace 惩罚,确保单个忘记登录超时低于惩罚阈值。
  • ssh(1):修复代理复用(-O proxy)bug。如果 mux 以 ControlPersist 启动,之后通过 mux 代理连接添加转发并使用该转发,则当 mux 代理会话终止时,mux 主进程会发出错误消息终止连接。

可移植性

  • 将 contrib/ssh-copy-id 同步到最新上游版本。
  • regress:改进某些 awk(1) 用法的可移植性(如 Solaris)。
  • contrib/redhat RPM spec 文件中,without_openssl 此前被无条件错误启用。
  • sshd(8):恢复 9.8 中回归的退出前审计调用。修复 SSHCONNECTIONABANDON 事件未被记录的问题。
  • sshd(8):增加对 FreeBSD 上类别施加的登录限制的支持,允许 authhostok(3) 和 authtimeok(3) 控制登录。
  • Musl libc 构建修复。
  • 修复 GNU/Hurd 上 setres*id 的检测。

OpenSSH 9.8 / 9.8p1(2024-07-01)

OpenSSH 9.8 于 2024-07-01 发布,包含两个安全问题的修复,一个严重一个次要。

安全

1) sshd(8) 竞态条件

可移植 OpenSSH 8.5p1 至 9.7p1(含)存在严重漏洞,可能允许以 root 权限执行任意代码。已在启用 ASLR 的 32 位 Linux/glibc 系统上成功利用。实验室条件下,攻击平均需要 6-8 小时连续连接,达到服务器接受的最大值。64 位系统上利用据信可能但尚未演示。这些攻击很可能会改进。非 glibc 系统的利用可以想象但尚未研究。缺少 ASLR 的系统,或下游 Linux 发行版修改 OpenSSH 禁用每连接 ASLR 重随机化的用户,可能更容易利用。OpenBSD 不受影响。感谢 Qualys 安全咨询团队发现、报告并证明可利用性。

2) ssh(1) ObscureKeystrokeTiming 逻辑错误

OpenSSH 9.5 至 9.7(含)连接到 9.5 或更高版本的 OpenSSH 服务器时,ObscureKeystrokeTiming 功能(默认开启)存在逻辑错误,使该功能失效——被动观察者仍能检测哪些网络包包含真实按键,因为虚假和真实按键包都被无条件发送。此 bug 由 Philippos Giavridis 发现,剑桥大学计算机实验室的 Jacky Wei En Kung、Daniel Hugenroth 和 Alastair Beresford 独立发现。更糟的是,无条件发送真假按键包破坏了另一项长期存在的时序攻击缓解。自 OpenSSH 2.9.9 起,sshd 会为在 echo-off 模式的 TTY 上收到的流量(如向 su(8) 或 sudo(8) 输入密码)发送虚假按键回显包。该 bug 使这些虚假按键回显失效,可能让被动观察者再次检测到 echo 关闭,并获得相当有限的按键时序信息(默认 20ms 粒度)。此额外影响由 Jacky Wei En Kung、Daniel Hugenroth 和 Alastair Beresford 识别。该 bug 不影响禁用 ObscureKeystrokeTiming 的连接或未请求 TTY 的会话。

未来弃用通知

与 9.9 相同的 DSA 弃用通知。本版本在编译时默认禁用 DSA,是弃用时间表的第二步。最后一步计划在 2025 年第一个 OpenSSH 版本。

潜在不兼容变更

  • 所有组件:DSA 签名算法现在编译时禁用。
  • sshd(8):服务器现在阻止反复认证失败、反复连接但从不完成认证、或使服务器崩溃的客户端地址。参见下方 PerSourcePenalties。接受大量用户连接、或接受 NAT/代理后地址连接的服务器运营者可能需要考虑这些设置。
  • sshd(8):服务器被拆分为监听二进制 sshd(8) 和每会话二进制 "sshd-session"。监听二进制更小,不再需要支持 SSH 协议。作为此工作的一部分,移除了禁用特权分离(此前需要改代码)和禁用 sshd 重新执行的支

评论

社区普遍赞赏 OpenSSH 团队加快安全修复节奏与高效维护。多数人对比 curl 肯定其对待人工智能漏洞报告的务实策略,分歧较小。

认可更频繁发布安全修复的务实策略

  • OpenSSH 团队因人工智能工具和其他研究者能独立发现漏洞,推断未报告的攻击者同样能发现,故放弃批量发布改为频繁发版以加速修复;社区有人对比 curl 认为此法更健康,并乐见修复提速(较多人)。
  • > 由于人工智能发现的漏洞常被不同研究者独立发现,说明对手也能发现,团队将更频繁发版以及时修复(@FloatArtifact)

肯定团队对非安全缺陷的快速响应

  • 有用户分享在客户端特定条件下服务质量处理的小缺陷,一天内便获测试构建、修复确认和发布排期,称赞核心软件维护体验极佳(较多人)。
  • > 我报告了一个非安全缺陷,一天内就得到测试版和修复说明,这是最正面的报障体验(@davb)

关注项目资金与捐赠情况

  • 有用户注意到官方捐赠链接,并对 OpenSSH 背后的资金支持状况表示好奇(少数人)。

有价值的补充

  • 本版重点似乎是缓解名为 Crossing The Streams 的压缩侧信道漏洞,其利用不同会话共享 LZ77 状态进行类似 CRIME 的攻击。
  • 在 OS X SDK 27 及以上版本中,因所依赖的沙盒接口被移除且无替代,sshd 不再支持沙盒机制。