macOS Tahoe 26.3 导致 SSH 中断:大小写敏感变更、DSA 密钥弃用及完整修复指南

macOSTahoe ·
macOS Tahoe 26.3 导致 SSH 中断:大小写敏感变更、DSA 密钥弃用及完整修复指南

macOS Tahoe 26.3 悄然修改了 SSH 用户名处理方式(改为大小写敏感)并禁用了 ssh-dss 密钥。本指南提供修复 SSH 连接、更新配置以及迁移至 Ed25519 密钥的完整方法。

Apple 于 2026 年 2 月 11 日发布了 macOS Tahoe 26.3,数千名开发者和系统管理员的 SSH 连接随即中断。没有警告对话框,没有迁移助手,也没有任何发布说明提及此事。前一天还能正常使用 ssh administrator@yourserver,第二天就收到 Connection closed by 10.10.83.28 port 22。如果你依赖 DSA 密钥连接旧版基础设施,这些密钥将彻底失效。本指南将详细说明究竟发生了什么变化、为何发生以及如何修复每一个受影响的工作流——从交互式会话到自动化 CI/CD 流水线。

核心要点

  • macOS Tahoe 26.3 强制执行大小写敏感的 SSH 用户名。 输入 administrator 而非 Administrator 会导致连接立即关闭,不会出现密码提示。
  • ssh-dss(DSA)密钥已被永久移除。 Tahoe 26.3 捆绑的 OpenSSH 10.0 在编译时已完全去除 DSA 支持,没有任何配置选项可以重新启用。
  • 连接不支持 mlkem768x25519-sha256 或 sntrup761x25519-sha512 的服务器时,现在会出现后量子密钥交换警告。
  • Ed25519 是所有新 SSH 密钥的推荐类型。 它比 RSA 更快、更安全,且生成的签名更小。
  • 应审计每个 ~/.ssh/config 文件,检查 User 指令中的大小写不匹配问题,以及 HostKeyAlgorithms 或 PubkeyAcceptedAlgorithms 中对 ssh-dss 的引用。

目录

  1. macOS Tahoe 26.3 SSH 究竟发生了什么变化
  2. 更新后 SSH 连接失败的诊断方法
  3. 理解大小写敏感变更
  4. 理解 DSA 密钥移除
  5. 后量子密钥交换警告
  6. 逐步修复:大小写敏感问题
  7. 逐步修复:从 DSA 迁移到 Ed25519
  8. 完整 SSH 配置审计指南
  9. SSH Agent 变更与 Keychain 集成
  10. 对 CI/CD 流水线和自动化的影响
  11. 对远程开发工作流的影响
  12. 旧版基础设施的变通方案
  13. 2026 年 SSH 安全最佳实践
  14. 常见问题解答
  15. 结论

macOS Tahoe 26.3 SSH 究竟发生了什么变化

macOS Tahoe 26.3 搭载 OpenSSH 10.0,引入了三项会影响日常 SSH 工作流的重大变更。Apple 在面向用户的发布说明中未提及任何一项,导致开发者只能通过连接失败来自行发现问题。

变更一:大小写敏感的用户名匹配

在 Tahoe 26.3 之前,macOS 的 SSH 客户端对用户名大小写较为宽松。你可以使用 ssh administrator@server、ssh Administrator@server 甚至 ssh ADMINISTRATOR@server 进行连接,只要底层操作系统能匹配到对应账户,远程服务器就会正确解析用户名。更新后,SSH 客户端在连接完全建立之前就会执行严格的大小写匹配检查。如果大小写与远程服务器的预期不符,连接将立即关闭——在密码认证或密钥交换完成之前。

变更二:完整移除 DSA(ssh-dss)

OpenSSH 自 2015 年的 7.0 版本起就已弃用 DSA。弃用过程遵循清晰的时间线:

日期OpenSSH 版本DSA 状态
20157.0默认禁用,可通过配置重新启用
20249.x编译时可选,默认启用
2024 年中期9.x编译时可选,默认禁用
2025 年 4 月10.0完全从代码库中移除
2026 年 2 月10.0(macOS Tahoe 26.3)推送给所有 macOS 用户

在 macOS Tahoe 26.3 中,PubkeyAcceptedAlgorithms +ssh-dss 这一变通方案已不再有效。该算法在二进制文件中不存在。任何引用 ssh-dss 的 SSH 配置都会产生 Bad key types 错误。

变更三:后量子密钥交换警告

OpenSSH 10.0 引入了一个警告,当连接到不支持后量子密钥交换算法的服务器时会触发该警告。警告内容如下:

WARNING: connection is not using a post-quantum key exchange algorithm.
This session may be vulnerable to 'store now, decrypt later' attacks.

虽然这只是警告而非硬性失败,但它会在终端输出中产生噪音,并可能破坏解析 SSH 输出的自动化脚本。

未发生变化的内容

值得注意的是,以下内容保持不变:

  • RSA 密钥继续有效(使用 rsa-sha2-256 和 rsa-sha2-512 签名算法)
  • ECDSA 密钥继续有效(尽管 Ed25519 是首选)
  • SSH 端口转发、隧道和 ProxyJump 功能完全相同
  • ~/.ssh/known_hosts 文件格式未发生变化

如果你是 macOS SSH 新手或从头搭建开发环境,我们的 macOS Tahoe 开发者设置指南 涵盖了完整的初始配置。


更新后 SSH 连接失败的诊断方法

在进行任何更改之前,你需要确定三个问题中的哪一个影响了你的连接。SSH 详细输出是你的主要诊断工具。

步骤一:启用详细 SSH 输出

使用三重详细标志运行失败的 SSH 命令,查看完整的握手协商过程:

ssh -vvv user@hostname

这会产生显示连接每个阶段的详细输出。寻找以下特定模式:

大小写敏感失败模式:

debug1: Connecting to 10.10.83.28 [10.10.83.28] port 22.
debug1: Connection established.
debug1: identity file /Users/you/.ssh/id_ed25519 type 3
debug3: receive packet: type 7
Connection closed by 10.10.83.28 port 22

关键指标是连接在建立后、任何认证尝试之前就关闭了。没有"Permission denied"消息——连接就是断开了。

DSA 密钥失败模式:

/Users/you/.ssh/config line 15: Bad key types '+ssh-dss'.

或者:

Bad key types '+ssh-rsa,ssh-dss'

此错误在 SSH 客户端解析配置文件时立即出现,在任何连接尝试之前。

后量子警告模式:

WARNING: connection is not using a post-quantum key exchange algorithm.
This session may be vulnerable to 'store now, decrypt later' attacks.

这在密钥交换期间出现,但不会阻止连接完成。

步骤二:检查 SSH 客户端版本

验证运行的是哪个 OpenSSH 版本:

ssh -V

macOS Tahoe 26.3 上的预期输出:

OpenSSH_10.0p1, LibreSSL 3.3.6

如果你看到的是旧版本,可能有通过 Homebrew 安装的 OpenSSH 优先级更高。检查正在使用的二进制文件:

which ssh

系统 SSH 位于 /usr/bin/ssh。如果看到 /opt/homebrew/bin/ssh 或 /usr/local/bin/ssh,说明你在使用 Homebrew 版本,其行为可能有所不同。

步骤三:使用显式参数测试

通过显式指定用户名大小写和密钥类型来隔离问题:

# 测试大小写敏感性——尝试两种大小写
ssh -vvv Administrator@hostname
ssh -vvv administrator@hostname

# 不使用任何配置文件干扰进行测试
ssh -F /dev/null -vvv user@hostname

# 使用特定密钥进行测试
ssh -vvv -i ~/.ssh/id_ed25519 user@hostname

终端 SSH 调试输出

步骤四:检查 SSH 配置中的错误

解析配置文件以识别引用已弃用算法的行:

# 检查任何 ssh-dss 引用
grep -n "ssh-dss" ~/.ssh/config

# 检查系统配置中的 ssh-dss 引用
grep -n "ssh-dss" /etc/ssh/ssh_config

# 检查所有 User 指令以审查大小写
grep -n "User " ~/.ssh/config

如需深入了解 macOS Tahoe 上的终端使用,请参考我们的 macOS Tahoe 终端指南。


理解大小写敏感变更

为何此变更会导致连接中断

在大多数类 Unix 系统上,用户名在操作系统层面是大小写敏感的。名为 Administrator 的用户在技术上与 administrator 是不同的账户。然而,SSH 协议本身(RFC 4252)声明用户名是"大小写敏感的",但承认服务器实现可以选择不同的处理方式。

在 macOS Tahoe 26.3 之前,macOS SSH 客户端对大小写较为宽松。当你输入 ssh administrator@server 时,客户端会原样发送用户名,许多 SSH 服务器(特别是运行在 Windows、macOS 或网络设备上的服务器)会在认证期间对大小写进行规范化处理。连接会成功,因为服务器完成了将 administrator 匹配到 Administrator 账户的工作。

使用 OpenSSH 10.0 后,macOS 的 SSH 客户端现在执行更严格的预认证检查。如果服务器返回早期协议消息表明大小写不匹配,连接将在认证进行之前终止。这意味着:

  • 连接到 Windows 服务器(历来对大小写进行规范化处理)可能会中断
  • 连接到网络设备(路由器、交换机、NAS 设备)使用不区分大小写用户名的可能会中断
  • 连接到 macOS 服务器(管理员账户为 Administrator,但脚本使用 administrator)将会中断
  • 连接到 Linux 服务器受影响的可能性较小,因为 Linux 用户名本已区分大小写

常见的中断场景

场景一:macOS 到 macOS 远程管理

许多系统管理员使用以下方式连接远程 Mac:

ssh [email protected]

但 macOS 默认管理员账户创建为首字母大写的 Administrator。这在 Tahoe 26.3 之前有效,之后会中断。

场景二:网络设备管理

连接路由器、交换机、防火墙和 NAS 设备通常使用通用用户名:

ssh [email protected]
ssh [email protected]

如果设备将用户名存储为 Admin 或 ROOT,这些连接现在将无声地失败。

场景三:SSH 配置别名

许多开发者有带有错误大小写但以前有效的 SSH 配置条目:

# ~/.ssh/config - 这现在可能会中断
Host production
    HostName prod.example.com
    User deploy      # 服务器期望 "Deploy"
    IdentityFile ~/.ssh/prod_key

理解 DSA 密钥移除

反对 DSA 的安全理由

SSH 中实现的 DSA(数字签名算法)使用固定的 1024 位密钥长度和 SHA-1 进行哈希。这种组合提供的对称安全性约为 80 位——远低于现代安全标准推荐的 128 位最低值。

DSA 密钥的具体弱点:

属性DSA(ssh-dss)Ed25519RSA-4096
密钥大小1024 位256 位4096 位
哈希算法SHA-1SHA-512SHA-256/512
安全级别~80 位~128 位~128 位
签名大小40 字节64 字节512 字节
签名速度慢快中等
验证速度慢快中等
偏差漏洞高无无

DSA 特别容易受到实现缺陷的影响。如果签名期间使用的随机数生成器存在任何偏差,私钥可以从少量签名中恢复。这已在现实攻击中被利用。

"移除"的实际含义

在之前的 macOS 版本中,DSA 默认禁用,但可以通过配置选项重新启用:

# 这在 macOS Sequoia 及更早版本有效
Host legacy-server
    HostKeyAlgorithms +ssh-dss
    PubkeyAcceptedAlgorithms +ssh-dss

在 macOS Tahoe 26.3 中,这些配置行本身就会导致错误,因为 SSH 二进制文件不再将 ssh-dss 识别为有效的算法标识符。错误信息为:

/Users/you/.ssh/config line 8: Bad key types '+ssh-dss'.

这意味着:

  1. 你不能使用 DSA 密钥进行认证(公钥登录)
  2. 你不能接受服务器的 DSA 主机密钥
  3. 你甚至不能在配置文件中引用 ssh-dss 而不导致错误
  4. ssh-keygen 工具不再能生成 DSA 密钥

检查你是否有 DSA 密钥

在继续迁移之前,检查现有密钥:

# 列出所有 SSH 密钥及其类型
for key in ~/.ssh/*.pub; do
    echo "=== $key ==="
    ssh-keygen -l -f "$key"
done

示例输出:

=== /Users/you/.ssh/id_dsa.pub ===
1024 SHA256:abc123... you@mac (DSA)          # 此密钥必须替换
=== /Users/you/.ssh/id_ed25519.pub ===
256 SHA256:xyz789... you@mac (ED25519)       # 此密钥没问题
=== /Users/you/.ssh/id_rsa.pub ===
3072 SHA256:def456... you@mac (RSA)          # 此密钥没问题

任何被标识为 (DSA) 的密钥都必须替换。如果发现了一个,先不要删除它——你需要它来确认哪些服务器已授权该密钥。


后量子密钥交换警告

警告含义

OpenSSH 10.0 引入了使用 ML-KEM(前身为 CRYSTALS-Kyber)算法与 X25519 混合的后量子密钥交换。默认密钥交换算法现在是 mlkem768x25519-sha256,备选为 sntrup761x25519-sha512。

当连接到不支持这两种算法的服务器时,OpenSSH 会显示:

WARNING: connection is not using a post-quantum key exchange algorithm.
This session may be vulnerable to 'store now, decrypt later' attacks.

"存储后解密"攻击是指对手可以今天记录你的加密 SSH 流量,并在未来量子计算机具备破解经典密钥交换算法能力时进行解密。

何时会看到此警告

  • 连接运行 OpenSSH 8.x 或更早版本的服务器
  • 连接内置 SSH 实现的网络设备
  • 连接运行旧版 SSH 守护进程的云实例
  • 连接 GitHub、GitLab 或 Bitbucket(可能尚不支持后量子算法)

消除警告

如果你了解风险并希望抑制警告,在 ~/.ssh/config 中添加:

# 全局抑制后量子警告
Host *
    WarnWeakCrypto no

或仅针对特定主机:

Host legacy-server
    HostName 192.168.1.100
    WarnWeakCrypto no

理想的解决方案是将服务器更新到支持 sntrup761x25519-sha512 的 OpenSSH 9.0 或更高版本,或支持更新的 mlkem768x25519-sha256 的 OpenSSH 9.9+。


逐步修复:大小写敏感问题

修复一:确定正确的用户名大小写

首先,验证远程系统上的确切用户名。方法取决于远程操作系统:

对于远程 Linux/macOS 服务器:

# 如果仍可通过控制台、物理访问或其他 SSH 客户端登录
grep "your_username" /etc/passwd

# 或使用 id 命令
id

# 输出示例:uid=501(Administrator) gid=20(staff) groups=...

对于远程 Windows 服务器(OpenSSH):

# 在远程机器的 PowerShell 中
whoami
# 输出:DOMAIN\Administrator

对于网络设备:

查看设备的 Web 管理界面或文档以获取确切的用户名格式。常见模式:

  • Cisco IOS:通常小写(admin)
  • Juniper:通常小写(root)
  • Synology NAS:按创建时的大小写
  • QNAP NAS:按创建时的大小写

修复二:更新 SSH 配置文件

打开 SSH 配置并更正所有 User 指令:

# 打开配置文件
nano ~/.ssh/config

修复前(已损坏):

Host production
    HostName prod.example.com
    User administrator
    IdentityFile ~/.ssh/prod_key

Host nas
    HostName nas.local
    User admin
    Port 22

修复后(已修复):

Host production
    HostName prod.example.com
    User Administrator
    IdentityFile ~/.ssh/prod_key

Host nas
    HostName nas.local
    User Admin
    Port 22

修复三:更新 Shell 别名和脚本

在 shell 配置中搜索 SSH 命令:

# 检查 bash 别名
grep -n "ssh " ~/.bashrc ~/.bash_profile 2>/dev/null

# 检查 zsh 别名
grep -n "ssh " ~/.zshrc ~/.zprofile 2>/dev/null

# 检查自定义脚本中的 SSH 命令
grep -rn "ssh " ~/scripts/ ~/bin/ 2>/dev/null

更新任何硬编码的用户名以使用正确的大小写。

修复四:更新环境变量

某些工具使用环境变量作为 SSH 用户名:

# 检查 SSH 相关环境变量
env | grep -i ssh
env | grep -i user

# 需要检查的常见变量
echo $DEPLOY_USER
echo $SSH_USER
echo $REMOTE_USER

修复五:验证修复

进行更改后,验证每个连接:

# 使用详细输出进行测试
ssh -v production

# 预期:认证成功
# debug1: Authentication succeeded (publickey).

逐步修复:从 DSA 迁移到 Ed25519

本节介绍将 DSA 密钥替换为 Ed25519 密钥的完整过程。如需了解终端命令的背景知识,我们的 Mac 终端精通指南 涵盖了所有基础内容。

SSH 密钥迁移流程

阶段一:清点 DSA 密钥

在生成新密钥之前,记录 DSA 密钥的使用位置:

# 步骤 1:查找系统上的所有 DSA 密钥
find ~/.ssh -name "*.pub" -exec grep -l "ssh-dss" {} \;

# 步骤 2:对于每个 DSA 密钥,检查哪些服务器已授权它
# 记下公钥指纹
ssh-keygen -l -f ~/.ssh/id_dsa.pub

# 步骤 3:检查 known_hosts 中的 DSA 主机密钥
grep "ssh-dss" ~/.ssh/known_hosts | awk '{print $1}'

创建迁移清单:

# 创建迁移跟踪文件
cat > ~/ssh_migration_checklist.txt << 'EOF'
SSH DSA 密钥迁移清单
===============================
日期:$(date)

发现的 DSA 密钥:
- [ ] ~/.ssh/id_dsa -> 用于:_______________
- [ ] ~/.ssh/id_dsa.pub -> 已授权在:_______________

具有 DSA 主机密钥的服务器:
- [ ] server1.example.com
- [ ] 192.168.1.100

使用 DSA 的自动化/脚本:
- [ ] deploy.sh
- [ ] backup-cron.sh
- [ ] CI/CD 流水线:_______________
EOF

阶段二:生成新的 Ed25519 密钥

使用有意义的注释生成新的 Ed25519 密钥对:

# 使用描述性注释生成 Ed25519 密钥
ssh-keygen -t ed25519 -C "yourname@macbook-2026-02" -f ~/.ssh/id_ed25519

# 系统会提示输入密码——请设置一个
# 密码可在机器被入侵时保护你的私钥

如果需要为不同用途准备单独的密钥(推荐用于安全隔离):

# 工作服务器的密钥
ssh-keygen -t ed25519 -C "work-servers-2026" -f ~/.ssh/id_ed25519_work

# 个人项目的密钥
ssh-keygen -t ed25519 -C "personal-2026" -f ~/.ssh/id_ed25519_personal

# CI/CD 自动化的密钥
ssh-keygen -t ed25519 -C "cicd-automation-2026" -f ~/.ssh/id_ed25519_cicd

验证生成的密钥:

# 检查新密钥
ssh-keygen -l -f ~/.ssh/id_ed25519.pub

# 预期输出:
# 256 SHA256:abcdef123456... yourname@macbook-2026-02 (ED25519)

阶段三:将新密钥部署到服务器

对于之前使用 DSA 密钥的每台服务器,部署新的 Ed25519 公钥:

方法一:使用 ssh-copy-id(如果仍可认证)

如果你有其他可用的认证方法(密码、不同密钥):

# 使用密码认证部署新密钥
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server

# 或在部署期间指定一个可用密钥进行认证
ssh-copy-id -i ~/.ssh/id_ed25519.pub -o "IdentityFile=~/.ssh/id_rsa" user@server

方法二:手动部署(如果 ssh-copy-id 不可用)

# 复制公钥内容
cat ~/.ssh/id_ed25519.pub | pbcopy

# 使用任何可用方法(密码、控制台等)SSH 到服务器
ssh user@server

# 在远程服务器上添加密钥
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "粘贴你的公钥在此处" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

方法三:对于无法 SSH 访问的服务器

如果 DSA 密钥是唯一的认证方法且已不再有效:

  1. 使用服务器的 Web 管理控制台(如果可用)
  2. 通过物理控制台或 IPMI/iLO/iDRAC 访问
  3. 使用仍有访问权限的跳板机
  4. 联系服务器管理员

阶段四:更新 SSH 配置

替换 SSH 配置中的 DSA 密钥引用:

# 修改前
Host old-server
    HostName legacy.example.com
    User admin
    IdentityFile ~/.ssh/id_dsa
    HostKeyAlgorithms +ssh-dss
    PubkeyAcceptedAlgorithms +ssh-dss

# 修改后
Host old-server
    HostName legacy.example.com
    User Admin
    IdentityFile ~/.ssh/id_ed25519_work

阶段五:清理已知主机

删除陈旧的 DSA 主机密钥条目:

# 在 known_hosts 中查找具有 DSA 主机密钥的服务器
grep "ssh-dss" ~/.ssh/known_hosts

# 删除特定主机条目(下次连接时会重新接受主机密钥)
ssh-keygen -R hostname_or_ip

# 或一次性删除所有 DSA 条目
# 首先备份文件
cp ~/.ssh/known_hosts ~/.ssh/known_hosts.backup.$(date +%Y%m%d)

# 然后删除 DSA 条目
grep -v "ssh-dss" ~/.ssh/known_hosts > ~/.ssh/known_hosts.tmp
mv ~/.ssh/known_hosts.tmp ~/.ssh/known_hosts

阶段六:验证一切正常

测试每个服务器连接:

# 使用详细输出测试连接
ssh -v old-server

# 验证正在提供正确的密钥
# 查找:debug1: Offering public key: /Users/you/.ssh/id_ed25519_work ED25519

# 对所有配置的主机运行完整连接测试
for host in $(grep "^Host " ~/.ssh/config | awk '{print $2}' | grep -v '\*'); do
    echo "测试:$host"
    ssh -o ConnectTimeout=5 -o BatchMode=yes "$host" echo "OK" 2>&1
    echo "---"
done

阶段七:废弃 DSA 密钥

一旦所有服务器完成迁移和验证:

# 存档旧的 DSA 密钥(不要立即删除)
mkdir -p ~/.ssh/deprecated
mv ~/.ssh/id_dsa ~/.ssh/deprecated/id_dsa.retired.$(date +%Y%m%d)
mv ~/.ssh/id_dsa.pub ~/.ssh/deprecated/id_dsa.pub.retired.$(date +%Y%m%d)
chmod 400 ~/.ssh/deprecated/id_dsa.retired.*

将存档的密钥保留至少 90 天,以防发现遗漏的服务器。


完整 SSH 配置审计指南

处理完个别问题后,对 SSH 配置进行全面审计。如果你在 macOS 上使用 SSH 已有多年,并在多次 macOS 升级过程中积累了配置条目,这一点尤为重要。

审计步骤一:检查已弃用算法

# 检查任何已弃用算法引用
echo "=== 检查 ~/.ssh/config ==="
grep -n -E "(ssh-dss|ssh-dsa|diffie-hellman-group1-sha1|diffie-hellman-group14-sha1|hmac-sha1-96|hmac-md5)" ~/.ssh/config 2>/dev/null

echo ""
echo "=== 检查 /etc/ssh/ssh_config ==="
grep -n -E "(ssh-dss|ssh-dsa|diffie-hellman-group1-sha1)" /etc/ssh/ssh_config 2>/dev/null

echo ""
echo "=== 检查 /etc/ssh/ssh_config.d/ ==="
grep -rn -E "(ssh-dss|ssh-dsa)" /etc/ssh/ssh_config.d/ 2>/dev/null

审计步骤二:验证配置语法

# 在不连接的情况下测试 SSH 配置语法
ssh -G test-host 2>&1 | head -5

# 如果有错误,将显示为:
# /Users/you/.ssh/config line X: Bad key types '...'

审计步骤三:审查所有 User 指令

# 提取所有 User 指令及其适用的主机
awk '/^Host /{host=$2} /User /{print host, $0}' ~/.ssh/config

审查输出并验证每个用户名的大小写。

审计步骤四:检查文件权限

SSH 对文件权限要求严格。不正确的权限可能导致无声失败:

# 检查并修复 SSH 目录权限
echo "=== 目录权限 ==="
ls -la ~/.ssh/

echo ""
echo "=== 预期权限 ==="
echo "~/.ssh/           -> drwx------ (700)"
echo "~/.ssh/config     -> -rw------- (600)"
echo "~/.ssh/id_*       -> -rw------- (600) 用于私钥"
echo "~/.ssh/*.pub      -> -rw-r--r-- (644) 用于公钥"
echo "~/.ssh/authorized_keys -> -rw------- (600)"
echo "~/.ssh/known_hosts     -> -rw-r--r-- (644)"

# 如需要则修复权限
chmod 700 ~/.ssh
chmod 600 ~/.ssh/config 2>/dev/null
chmod 600 ~/.ssh/id_* 2>/dev/null
chmod 644 ~/.ssh/*.pub 2>/dev/null
chmod 600 ~/.ssh/authorized_keys 2>/dev/null

审计步骤五:推荐的现代 SSH 配置模板

以下是适用于 macOS Tahoe 26.3 的完整现代 SSH 配置模板:

# ~/.ssh/config
# 针对 macOS Tahoe 26.3 / OpenSSH 10.0 更新
# 最后审计:2026-02-28

# ============================================
# 全局默认值
# ============================================
Host *
    # 默认使用 Ed25519 密钥
    IdentityFile ~/.ssh/id_ed25519

    # 仅提供为每台主机显式配置的密钥
    IdentitiesOnly yes

    # macOS Keychain 集成
    UseKeychain yes
    AddKeysToAgent yes

    # 现代密钥交换首选项
    KexAlgorithms mlkem768x25519-sha256,[email protected],curve25519-sha256,[email protected]

    # 连接稳定性
    ServerAliveInterval 60
    ServerAliveCountMax 3

    # 安全加固
    HashKnownHosts yes
    StrictHostKeyChecking ask

# ============================================
# 工作服务器
# ============================================
Host prod-web
    HostName prod-web.example.com
    User Deploy
    IdentityFile ~/.ssh/id_ed25519_work
    Port 22

Host staging
    HostName staging.example.com
    User Deploy
    IdentityFile ~/.ssh/id_ed25519_work
    Port 22

# ============================================
# 个人服务器
# ============================================
Host homelab
    HostName 192.168.1.100
    User admin
    IdentityFile ~/.ssh/id_ed25519_personal

# ============================================
# 跳板机配置
# ============================================
Host internal-*
    ProxyJump bastion.example.com
    User admin
    IdentityFile ~/.ssh/id_ed25519_work

Host bastion.example.com
    User jump-user
    IdentityFile ~/.ssh/id_ed25519_work
    ForwardAgent no

SSH Agent 变更与 Keychain 集成

macOS Tahoe 26.3 还带来了 SSH agent 与 macOS Keychain 交互方式的细微变化。

Keychain 集成

macOS 特有的 UseKeychain 指令在 Tahoe 26.3 中继续有效,但其行为已有所细化:

# 将新的 Ed25519 密钥添加到 macOS Keychain
ssh-add --apple-use-keychain ~/.ssh/id_ed25519

# 验证密钥已添加
ssh-add -l

如果密钥添加成功,你将看到:

256 SHA256:abcdef123456... yourname@macbook-2026-02 (ED25519)

持久密钥加载

确保你的 SSH 配置包含以下指令,以在重启后保持密钥持久性:

Host *
    UseKeychain yes
    AddKeysToAgent yes
    IdentityFile ~/.ssh/id_ed25519

没有 UseKeychain yes,每次重启后都需要运行 ssh-add。

检查 SSH Agent

# 检查 agent 是否正在运行
echo $SSH_AUTH_SOCK

# 列出已加载的密钥
ssh-add -l

# 如果没有加载密钥,请添加它们
ssh-add --apple-use-keychain ~/.ssh/id_ed25519

有关 macOS 安全配置的更多详情,请参阅我们的 macOS Tahoe 安全隐私指南。


对 CI/CD 流水线和自动化的影响

macOS Tahoe 26.3 中的 SSH 变更对自动化工作流有重大影响。如果你的 CI/CD 流水线在 macOS 运行器(GitHub Actions、GitLab CI、Mac 上的 Jenkins)上运行,在运行器操作系统升级后这些变更将影响你。

GitHub Actions

如果你使用 macos-latest 或 macos-15 运行器,SSH 二进制文件最终会被更新。现在就审计你的工作流:

# .github/workflows/deploy.yml
# 修改前(可能损坏)
- name: Deploy
  run: |
    ssh administrator@${{ secrets.DEPLOY_HOST }} "cd /app && git pull"

# 修改后(已修复)
- name: Deploy
  run: |
    ssh Administrator@${{ secrets.DEPLOY_HOST }} "cd /app && git pull"

检查你的部署密钥:

  • DEPLOY_USER——验证大小写是否与远程账户匹配
  • SSH_PRIVATE_KEY——验证它不是 DSA 密钥
  • KNOWN_HOSTS——验证没有 DSA 主机密钥条目

GitLab CI

# .gitlab-ci.yml
deploy:
  before_script:
    # 部署前检查密钥类型
    - ssh-keygen -l -f ~/.ssh/id_deploy
    # 确保它不是 DSA
    - |
      if ssh-keygen -l -f ~/.ssh/id_deploy | grep -q "DSA"; then
        echo "ERROR: 检测到 DSA 密钥。需要迁移。"
        exit 1
      fi
  script:
    # 用户名使用正确大小写
    - ssh -o StrictHostKeyChecking=no Deploy@$DEPLOY_HOST "deploy.sh"

Jenkins

对于在 macOS agent 上运行的 Jenkins 流水线:

pipeline {
    agent { label 'macos' }
    stages {
        stage('Pre-flight SSH Check') {
            steps {
                sh '''
                    # 验证 SSH 版本
                    ssh -V

                    # 检查凭据中的 DSA 密钥
                    for key in ~/.ssh/*.pub; do
                        if ssh-keygen -l -f "$key" | grep -q "DSA"; then
                            echo "WARNING: 发现 DSA 密钥:$key"
                            exit 1
                        fi
                    done

                    echo "SSH 预检通过"
                '''
            }
        }
    }
}

Ansible Playbooks

如果你从 macOS 控制节点运行 Ansible:

# ansible.cfg
[defaults]
# 确保使用正确的 SSH 二进制文件
ssh_executable = /usr/bin/ssh

# 强制特定 SSH 参数
[ssh_connection]
ssh_args = -o IdentitiesOnly=yes -o IdentityFile=~/.ssh/id_ed25519_ansible

检查 Ansible 清单中的用户名大小写:

# inventory.ini
# 修改前
[webservers]
web1.example.com ansible_user=administrator

# 修改后
[webservers]
web1.example.com ansible_user=Administrator

自动化备份脚本

检查任何使用 SSH 的 cron 任务或 launchd 任务:

# 查找所有包含 SSH 引用的 cron 任务
crontab -l 2>/dev/null | grep -i ssh

# 查找包含 SSH 引用的 launchd plist
grep -rl "ssh" ~/Library/LaunchAgents/ /Library/LaunchAgents/ /Library/LaunchDaemons/ 2>/dev/null

# 检查 rsync 备份脚本(rsync 默认使用 SSH)
grep -rn "rsync.*@" ~/scripts/ ~/bin/ 2>/dev/null

对远程开发工作流的影响

VS Code 远程 SSH

Visual Studio Code 的远程 SSH 扩展存储可能受影响的连接配置:

# VS Code SSH 配置位置
cat ~/Library/Application\ Support/Code/User/settings.json | grep -A5 "remote.SSH"

# 检查 VS Code 的 SSH 配置引用
grep -n "ssh" ~/Library/Application\ Support/Code/User/settings.json 2>/dev/null

更新你的 VS Code SSH 目标以使用正确的用户名大小写和非 DSA 密钥。

JetBrains Gateway / 远程开发

JetBrains IDE 单独存储 SSH 配置:

# 检查 JetBrains SSH 配置
find ~/Library/Application\ Support/JetBrains -name "*.xml" -exec grep -l "ssh" {} \; 2>/dev/null

tmux 和持久会话

如果你通过 SSH 使用 tmux 或 screen,重连脚本需要更新:

# 常见的 tmux 重连别名——检查用户名大小写
alias tm='ssh -t Administrator@server "tmux attach || tmux new"'

如需全面的开发者环境设置,请参阅我们的 macOS Tahoe 开发者终极指南。


旧版基础设施的变通方案

某些环境无法立即更新。网络设备、嵌入式系统和旧版服务器可能在未来数年内仍需要 DSA。以下是从最推荐到最不推荐排列的实用变通方案。

变通方案一:使用跳板机(推荐)

设置一台仍支持 DSA 的 Linux 堡垒机并将其用作代理:

# ~/.ssh/config
Host legacy-device
    HostName 192.168.1.1
    User admin
    ProxyJump bastion

Host bastion
    HostName bastion.example.com
    User jump
    IdentityFile ~/.ssh/id_ed25519

堡垒机运行较旧的 OpenSSH(或编译时支持 DSA 的版本),处理与旧设备的 DSA 协商。你的 Mac 只需使用 Ed25519 向堡垒机进行认证。

变通方案二:使用 Docker 容器

在 Docker 容器内运行旧版 OpenSSH 客户端:

# 为旧版 SSH 创建 Dockerfile
cat > ~/legacy-ssh/Dockerfile << 'EOF'
FROM alpine:3.18
RUN apk add --no-cache openssh-client
ENTRYPOINT ["ssh"]
EOF

# 构建镜像
docker build -t legacy-ssh ~/legacy-ssh/

# 使用它连接旧设备
docker run --rm -it \
    -v ~/.ssh:/root/.ssh:ro \
    legacy-ssh \
    -o HostKeyAlgorithms=+ssh-dss \
    -o PubkeyAcceptedKeyTypes=+ssh-dss \
    admin@legacy-device

创建 shell 别名以方便使用:

# 添加到 ~/.zshrc
alias legacy-ssh='docker run --rm -it -v ~/.ssh:/root/.ssh:ro legacy-ssh'

# 用法
legacy-ssh -o HostKeyAlgorithms=+ssh-dss admin@legacy-device

变通方案三:通过 Homebrew 安装旧版 OpenSSH

你可以从源代码编译 OpenSSH 9.7p1(最后支持 DSA 的版本):

# 安装依赖
brew install openssl@3

# 下载 OpenSSH 9.7p1 源代码
curl -O https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-9.7p1.tar.gz
tar xzf openssh-9.7p1.tar.gz
cd openssh-9.7p1

# 使用 DSA 支持和自定义前缀进行配置
./configure \
    --prefix=$HOME/openssh97 \
    --with-ssl-dir=$(brew --prefix openssl@3)

# 构建并安装
make -j$(sysctl -n hw.ncpu)
make install

# 使用旧版 SSH 二进制文件
~/openssh97/bin/ssh -o HostKeyAlgorithms=+ssh-dss admin@legacy-device

为旧版连接创建别名:

# 添加到 ~/.zshrc
alias ssh-legacy='~/openssh97/bin/ssh -o HostKeyAlgorithms=+ssh-dss -o PubkeyAcceptedKeyTypes=+ssh-dss'

# 用法
ssh-legacy admin@old-router

变通方案四:使用 Linux 虚拟机

如果你使用 UTM、Parallels 或 VMware Fusion:

  1. 设置轻量级 Linux 虚拟机(Alpine 或 Ubuntu Server)
  2. 从 Mac 通过 SSH 连接到虚拟机(使用 Ed25519)
  3. 从虚拟机通过 SSH 连接到旧设备(使用 DSA)

这提供了完全隔离,无需修改你的 macOS SSH 安装。

长期规划:制定设备更换计划

如果你因网络设备不支持现代算法而依赖 DSA,这明确表明这些设备从安全角度来看已达到使用寿命终点。制定更换时间表:

  • 路由器/交换机:大多数企业厂商自 2018 年起已支持 Ed25519
  • NAS 设备:Synology、QNAP 和 TrueNAS 均支持 Ed25519
  • 旧版服务器:如果运行的 OpenSSH 版本早于 6.5,整个系统需要更新

2026 年 SSH 安全最佳实践

以 macOS Tahoe 26.3 的变更为契机,现在正是实施全面 SSH 安全改进的好时机。

密钥管理最佳实践

1. 为不同角色使用独立密钥:

# 工作基础设施
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_work -C "work-2026"

# 个人项目
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_personal -C "personal-2026"

# CI/CD 和自动化
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_automation -C "automation-2026"

# Git 托管(GitHub、GitLab)
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_git -C "git-2026"

2. 始终使用密码:

密码在静态状态下加密你的私钥。如果你的机器被入侵,攻击者无法在没有密码的情况下使用你的 SSH 密钥。结合 macOS Keychain 集成,你只需输入一次密码。

# 在密钥生成期间出现提示时:
Enter passphrase (empty for no passphrase): [输入强密码]
Enter same passphrase again: [确认]

3. 每年轮换密钥:

在密钥注释中包含年份,以便知道它们是何时生成的:

ssh-keygen -t ed25519 -C "you@company-2026-Q1" -f ~/.ssh/id_ed25519_work_2026

年份更替时,生成新密钥、部署并废弃旧密钥。

4. 设置正确的文件权限:

# 私钥:仅所有者可读
chmod 400 ~/.ssh/id_ed25519*
chmod 600 ~/.ssh/id_ed25519*.pub

# 实际上,公钥可以被所有人读取
chmod 644 ~/.ssh/id_ed25519*.pub

# SSH 目录本身
chmod 700 ~/.ssh

# 配置文件
chmod 600 ~/.ssh/config

服务器端加固

如果你管理 SSH 服务器,借此机会对其进行加固:

# /etc/ssh/sshd_config 推荐设置

# 禁用密码认证(仅使用密钥)
PasswordAuthentication no

# 禁用 root 登录
PermitRootLogin no

# 仅允许特定用户
AllowUsers deploy admin

# 使用现代密钥交换
KexAlgorithms mlkem768x25519-sha256,[email protected],curve25519-sha256

# 使用现代主机密钥算法
HostKeyAlgorithms ssh-ed25519,rsa-sha2-512,rsa-sha2-256

# 使用现代加密算法
Ciphers [email protected],[email protected],[email protected]

# 使用现代 MAC
MACs [email protected],[email protected]

# 频率限制
MaxAuthTries 3
MaxSessions 5
LoginGraceTime 30

更改 sshd_config 后,始终在断开连接之前进行测试:

# 验证配置
sudo sshd -t

# 如果没有错误,重启 sshd
sudo systemctl restart sshd

# 重要:在关闭现有会话之前,保持当前会话打开
# 并使用新连接进行测试

监控和告警

设置 SSH 认证事件监控:

# 监控失败尝试的 auth.log(Linux 服务器)
tail -f /var/log/auth.log | grep "sshd"

# 监控 SSH 事件的 macOS 系统日志
log stream --predicate 'process == "sshd"' --level info

常见错误排查

错误:"Connection closed by X.X.X.X port 22"

原因: 用户名大小写不匹配。

修复方法:

# 确定正确的用户名
ssh -vvv user@host 2>&1 | grep "debug1: Sending"

# 尝试相反的大小写
ssh Administrator@host  # 如果 'administrator' 失败
ssh administrator@host  # 如果 'Administrator' 失败

错误:"Bad key types '+ssh-dss'"

原因: SSH 配置引用了已移除的 DSA 算法。

修复方法:

# 查找并编辑有问题的行
grep -n "ssh-dss" ~/.ssh/config

# 删除或替换算法引用
# 修改前:HostKeyAlgorithms +ssh-dss
# 修改后:(删除整行,或替换为现代算法)

错误:"Bad key types '+ssh-rsa,ssh-dss'"

原因: SSH 配置有包含 DSA 的复合算法列表。

修复方法:

# 修改前
HostKeyAlgorithms +ssh-rsa,ssh-dss
PubkeyAcceptedAlgorithms +ssh-rsa,ssh-dss

# 修改后(删除 ssh-dss,如有需要保留 ssh-rsa 用于旧版 RSA)
HostKeyAlgorithms +ssh-rsa
PubkeyAcceptedAlgorithms +ssh-rsa

注意:ssh-rsa(使用 SHA-1 签名)也已弃用。如果必须使用 RSA,请使用 rsa-sha2-256 或 rsa-sha2-512:

HostKeyAlgorithms rsa-sha2-512,rsa-sha2-256
PubkeyAcceptedAlgorithms rsa-sha2-512,rsa-sha2-256

错误:"No matching host key type found"

原因: 远程服务器仅提供 DSA 主机密钥。

修复方法: 这需要在服务器端进行操作。在服务器上生成新的主机密钥:

# 在远程服务器上(如果有控制台访问权限)
sudo ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ""
sudo ssh-keygen -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key -N ""
sudo systemctl restart sshd

如果无法更新服务器,请使用上述跳板机或 Docker 变通方案。

错误:"WARNING: connection is not using a post-quantum key exchange algorithm"

原因: 远程服务器不支持后量子密钥交换。

修复方法:

# 针对特定主机抑制警告
# 添加到 ~/.ssh/config:
Host old-server
    WarnWeakCrypto no

# 或全局抑制(不推荐)
Host *
    WarnWeakCrypto no

错误:"Permission denied (publickey)"

原因: 密钥迁移后,新密钥未在服务器上授权。

修复方法:

# 检查正在提供的密钥
ssh -v user@host 2>&1 | grep "Offering public key"

# 部署正确的密钥
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@host

错误:"WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED"

原因: 从 known_hosts 删除 DSA 主机密钥条目后,服务器提供了不同类型的主机密钥。

修复方法:

# 删除旧的主机密钥条目
ssh-keygen -R hostname

# 重新连接并接受新的主机密钥
ssh user@hostname
# 系统会提示你验证新的主机密钥指纹

理解更广泛的背景

macOS Tahoe 26.3 中的 SSH 变更是整个行业更大趋势的一部分。理解这一背景有助于你为未来的变更做好准备,而不是对每次变更做出被动反应。

OpenSSH 发布时间线

版本日期关键变更
7.02015DSA 默认禁用
8.22020RSA 的 SHA-1 签名已弃用
8.82022RSA 的 SHA-1 签名默认禁用
9.02022后量子 KEx(sntrup761)默认启用
9.92024添加 ML-KEM 后量子支持
10.02025DSA 完全移除,ML-KEM 成为默认

macOS 历来落后于这些发布版本 6-12 个月,这就是为什么 DSA 移除在 2026 年初才影响到 macOS 用户,尽管它已于 2025 年 4 月在 OpenSSH 10.0 中实现。

未来可期的变化

根据 OpenSSH 开发路线图:

  • SHA-1 RSA 签名(ssh-rsa)可能在 OpenSSH 11.x 中被完全移除
  • ECDSA 与 NIST 曲线可能因 Ed25519 而被弃用
  • 后量子签名(不只是密钥交换)将被添加
  • 基于证书的认证将越来越多地被推广以替代原始公钥

现在就做好准备:

  1. 确保所有密钥都是 Ed25519
  2. 如果必须使用 RSA,改用 rsa-sha2-256/512
  3. 在你的服务器上测试后量子密钥交换
  4. 为你的组织评估 SSH 证书基础设施

有关 macOS Tahoe 26.3 更广泛更新的更多详情,请参阅我们的 macOS Tahoe 26.3 发布指南。


快速参考:常用命令

以下是本指南中提到的所有命令的汇总参考,按任务分类:

诊断

# 检查 SSH 版本
ssh -V

# 详细连接测试
ssh -vvv user@host

# 检查使用的是哪个 SSH 二进制文件
which ssh

# 不使用配置文件进行测试
ssh -F /dev/null user@host

# 检查当前密钥类型
for key in ~/.ssh/*.pub; do
    echo "=== $key ==="
    ssh-keygen -l -f "$key"
done

密钥生成

# 生成 Ed25519 密钥(推荐)
ssh-keygen -t ed25519 -C "description-YYYY" -f ~/.ssh/id_ed25519

# 生成 RSA 密钥(如果目标不支持 Ed25519)
ssh-keygen -t rsa -b 4096 -C "description-YYYY" -f ~/.ssh/id_rsa

密钥部署

# 将密钥部署到远程服务器
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@host

# 将密钥添加到 macOS Keychain
ssh-add --apple-use-keychain ~/.ssh/id_ed25519

配置审计

# 在配置中查找 DSA 引用
grep -n "ssh-dss" ~/.ssh/config /etc/ssh/ssh_config

# 查找所有 User 指令
grep -n "User " ~/.ssh/config

# 验证配置语法
ssh -G test-host

# 修复权限
chmod 700 ~/.ssh
chmod 600 ~/.ssh/config
chmod 400 ~/.ssh/id_*
chmod 644 ~/.ssh/*.pub

清理

# 删除旧的主机密钥
ssh-keygen -R hostname

# 从 known_hosts 删除所有 DSA 条目
cp ~/.ssh/known_hosts ~/.ssh/known_hosts.bak
grep -v "ssh-dss" ~/.ssh/known_hosts > ~/.ssh/known_hosts.tmp
mv ~/.ssh/known_hosts.tmp ~/.ssh/known_hosts

常见问题解答

我能在 macOS Tahoe 26.3 上降级 OpenSSH 以恢复 DSA 支持吗?

由于系统完整性保护(SIP),你无法替换 macOS 上的系统 OpenSSH 二进制文件。但是,你可以通过 Homebrew 安装旧版本或从源代码编译到自定义位置。位于 /usr/bin/ssh 的系统 ssh 始终是随 Tahoe 26.3 附带的 OpenSSH 10.0 版本。有关从源代码构建 OpenSSH 9.7p1 的详细说明,请参阅"旧版基础设施的变通方案"部分。

用户名大小写敏感变更是永久性的还是一个 bug?

根据 OpenSSH 10.0 发布说明和项目方向,这似乎是符合 SSH 协议规范(RFC 4252,该规范将用户名定义为大小写敏感)的有意行为。Apple 尚未就此是否为 bug 发表评论,也没有迹象表明会被撤销。你应该将此视为永久行为并相应更新配置。

我的 RSA 密钥也会停止工作吗?

使用 SHA-2 签名的 RSA 密钥(rsa-sha2-256 和 rsa-sha2-512)继续有效,在可预见的将来将继续受到支持。但是,使用 SHA-1 签名的 RSA 密钥(ssh-rsa)自 OpenSSH 8.8 起已默认禁用,可能在未来版本中被完全移除。如果你使用 RSA 密钥,请验证它们至少有 3072 位,并且你的服务器接受 SHA-2 签名。对于新密钥,Ed25519 是首选。

如何修复从 macOS 到 Windows Server 的 SSH 连接?

Windows Server 的 OpenSSH 实现历来对用户名不区分大小写。macOS Tahoe 26.3 更新后,你需要使用 Windows 识别的确切大小写。对于域账户,使用 DOMAIN\Username 或 [email protected]。对于本地账户,在计算机管理中检查账户名。相应更新你的 ~/.ssh/config:

Host windows-server
    HostName win.example.com
    User DOMAIN\\AdminUser
    IdentityFile ~/.ssh/id_ed25519

这也会影响 SFTP 和 SCP 吗?

是的。sftp 和 scp 都使用相同的 SSH 客户端库,受到相同的大小写敏感性强制执行和 DSA 移除的影响。使用系统 SSH 二进制文件的任何 SFTP 客户端(如 Cyberduck、Transmit 或 FileZilla)也会受到影响。捆绑自己 SSH 库的 GUI SFTP 客户端(例如使用其自身 libssh2 构建的 Cyberduck)可能不受影响,但这取决于具体应用程序。


结论

macOS Tahoe 26.3 在没有充分警告的情况下推送了破坏既有工作流的 SSH 变更。大小写敏感用户名强制执行、完整 DSA 移除和后量子密钥交换警告各自都需要关注,但一旦你理解了变更内容,它们都很容易解决。

立即需要采取的行动:

  1. 审计你的 ~/.ssh/config,检查 User 指令中的大小写不匹配并删除任何 ssh-dss 引用
  2. 生成 Ed25519 密钥以替换任何剩余的 DSA 密钥
  3. 将新密钥部署到你清单中的所有服务器
  4. 使用正确的用户名大小写和密钥路径更新自动化脚本和 CI/CD 流水线
  5. 根据你的安全态势消除或解决后量子警告

这些变更虽然带来了干扰,但推动了 macOS SSH 生态系统走向更强的安全默认值。Ed25519 比 DSA 更快、更安全,生成的密钥也更小。大小写敏感的用户名符合 SSH 协议规范。后量子密钥交换防御未来的威胁。迁移的痛苦是真实的,但安全改进是实质性的。

如果你正在 macOS Tahoe 上搭建新的开发环境,请从我们的 macOS Tahoe 开发者设置指南 开始,从一开始就正确配置一切。如需更广泛的安全配置,我们的 macOS Tahoe 安全隐私指南 涵盖了 SSH 之外的完整安全栈。