痛点拆解:重装系统只改服务器,却把整条 CI 上传链打断
痛点 1:换 HostKey 未通知 CI。重装或 ssh-keygen -A 后 Secrets 指纹 未更新,rsync 在 StrictHostKeyChecking=yes 下集体失败——常是策略生效而非 SSH 故障。
痛点 2:删 RSA 无重叠。内网旧客户端仍可能只认 RSA;无双指纹窗口会出现「人能连、CI 不能连」。
痛点 3:误以为 UpdateHostKeys 管 CI。它只作用于交互式 known_hosts,不会更新 UserKnownHostsFile。
痛点 4:长连接与 CA 不同步。ControlPersist 可能沿用旧主连接,而新 Job 已因指纹失败;用户证书 轮换也必须与 HostKey 分机工单。
服务端与客户端两条变更链:UpdateHostKeys 管什么、不管什么
UpdateHostKeys 只帮助交互式客户端追加新主机公钥,不改写 CI 的 UserKnownHostsFile。变更单须同时列 HostKey 路径、监听面与 Secrets 指纹库。
推荐顺序:生成 Ed25519 → 多行 HostKey → Secrets 双指纹 → reload sshd → rsync 与 SHA256 探针 → 删旧钥与旧 Secret 行。
变更前务必 sudo sshd -t 再 reload;轮换窗口须覆盖所有 Host 别名与 OIDC 上传入口。
可量化基线:把「轮换」变成可审计的数字
第一,为每台远程 Mac 维护「当前生效 HostKey 指纹表」:类型(ed25519/ecdsa/rsa)、ssh-keygen -lf 输出、生成日期、工单号。第二,记录重叠窗口起止时间(建议 48–72 小时,跨至少一个完整发布周期与一次 原子发布)。第三,单独计数「主机密钥验证失败」与「用户认证失败」,避免混在泛化上传错误里。
轮换后 24 小时内从托管 Runner、自建 Runner、跳板各跑一次 ssh -o BatchMode=yes 探针;重叠期可缩短 ControlPersist,避免长连接掩盖新指纹(见 ControlMaster 专文)。
决策矩阵:轮换策略、UpdateHostKeys 与 CI 同步方式
| 场景 | 服务端动作 | CI / 客户端动作 | 停机风险 |
|---|---|---|---|
| 计划内 Ed25519 升级 | 新增 ssh_host_ed25519_key,保留 RSA 直至窗口结束 | Secrets 双行指纹;StrictHostKeyChecking=yes | 低(设计良好时零停机) |
| 系统重装 / 克隆 | 全新 HostKey 套件;视为紧急轮换 | 立即更新 Secrets;短时接受双指纹不可用则先维护窗口 | 高(无重叠则 CI 全红) |
| 仅启用 UpdateHostKeys yes | 方便笔记本用户自动追加新密钥 | 不替代 Secrets 更新 | 对 CI 几乎无帮助 |
| 删除弱算法 RSA(<3072) | 从 HostKey 与 HostKeyAlgorithms 移除 | 确认无旧客户端;审计供应商脚本 | 中(遗留系统可能断连) |
| 与 SSH CA 用户证书同周发布 | 分拆工单:HostKey 与用户 CA 各一张 | 联合回归 rsync + 证书登录 + 完整性闸门 | 中(沟通成本高) |
服务端换钥须让 Secrets 在重叠窗口内可控演进,勿逼 Runner 回 ssh-keyscan。
实操步骤:远程 Mac 上从生成 HostKey 到收尾删旧钥
# 1) 盘点现有主机密钥与指纹(在远程 Mac 上)
# sudo ls -l /etc/ssh/ssh_host_*
# sudo ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
# sudo ssh-keygen -lf /etc/ssh/ssh_host_rsa_key.pub
# 2) 生成新 Ed25519(若迁移;保留旧文件)
# sudo ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N "" -C "host-$(hostname)-20260518"
# 3) sshd_config 片段(示例;以 Apple 自带路径为准)
# HostKey /etc/ssh/ssh_host_ed25519_key
# HostKey /etc/ssh/ssh_host_rsa_key
# HostKeyAlgorithms ssh-ed25519,ecdsa-sha2-nistp256,ssh-rsa
# UpdateHostKeys ask
# sudo sshd -t && sudo launchctl kickstart -k system/com.openssh.sshd
# 4) 受控工作站采集新指纹,与旧指纹一并写入 Secret SSH_KNOWN_HOSTS(两行)
# 5) CI 探针:export RSYNC_RSH='ssh -o StrictHostKeyChecking=yes -o UserKnownHostsFile=~/.ssh/ci_known_hosts'
# ssh -o BatchMode=yes ci-upload@remote-mac.example.com true
# rsync -av --dry-run ./dist/ ci-upload@remote-mac.example.com:/Volumes/builds/staging/
# 6) 窗口结束后:从 sshd_config 移除旧 HostKey 行,删旧私钥文件,Secrets 只保留新行
每一步都应在变更单记录工单号,并与 shasum -a 256 发布闸门同一评审,避免「密钥已换、产物清单仍指向旧路径」的二次事故。
强相关 CTA:先服务端轮换设计,再客户端固定,再传输与发布
阅读顺序:本文 → known_hosts 固定 → ControlMaster → OIDC → SSH CA → 完整性 → 原子发布 → 首页。
FAQ 与为什么考虑 SFTPMAC 托管远程 Mac
轮换期间 CI 全红是否说明 pin 失败?
通常说明 pin 成功:客户端拒绝未知密钥。按重叠窗口更新 Secrets 即可恢复;勿改回 StrictHostKeyChecking=no。
UpdateHostKeys 在 macOS 远程登录上默认开启吗?
取决于系统自带的 sshd_config 与补充片段;以 sshd -T | grep updatehostkeys 为准,不要假设默认行为。
双指纹窗口多久合适?
至少覆盖一次完整发布与各地 Runner 时区的一轮定时 Job;高合规环境可 72 小时并强制探针清单签字。
总结:2026 年远程 Mac 的主机密钥轮换应是服务端可重复 Runbook,通过 Ed25519 迁移、双密钥重叠与 Secrets 同步,让 CI 在 StrictHostKeyChecking=yes 下仍连续上传。
局限:自建机需自管补丁、HostKey 存档与 on-call。若要把 Apple 原生构建与可审计 SFTP/rsync 一并交付,SFTPMAC 托管远程 Mac 可协调变更窗口与指纹库,减少重装后全员改 Secrets 的救火成本。
把 HostKey 轮换、known_hosts 片段与 rsync 闸门写进同一张运维表,托管环境更容易做到 Ed25519 升级不断流。
