一条命令,让所有服务器信任一个新员工——不需要配置 authorized_keys,不需要逐个 ssh-copy-id,不需要担心哪个机器漏了。

这就是 SSH CA 签名认证做的事。


如果你读过我上一篇关于 knockd 端口敲门的文章,应该已经感觉到我对 SSH 安全的态度:防线要薄,但要分层。knockd 是第一层(端口隐藏),CA 签名是第二层(密钥管理)。

这篇文章不讲「SSH 基本用法」,讲的是如何把 SSH 密钥管理从「每个机器各管各的」升级成「一个 CA 说了算」。


传统方式的病根

现在你是怎么管理 SSH 密钥的?

ssh-copy-id user@server1
ssh-copy-id user@server2
ssh-copy-id user@server3
...

小团队还行。当你有 20 台服务器、5 个员工、每人换一次电脑——你就已经记不清哪个 key 还活着、哪个机器漏了。

更致命的是离职回收

  1. 找到离职员工的公钥指纹
  2. 登录每台服务器的 ~/.ssh/authorized_keys
  3. 一行一行找,删除
  4. 祈祷没有漏掉哪台

这个过程不止不安全,是必然出错——只要是人手操作的步骤,就一定会有机器被漏掉。


SSH CA 的工作原理

概念非常简单:

┌─────────────┐        签 名          ┌──────────────┐
│  Server A    │◄──── 可 信 ────────► │  CA Key Pair  │
│  Server B    │◄──── 可 信 ────────► │  (离线安全)   │
│  Server C    │◄──── 可 信 ────────► │              │
└─────────────┘                       └──────┬───────┘
                                              │
                                     ┌────────▼───────┐
                                     │  User Key       │
                                     ├────────────────┤
                                     │ 签过名的公钥     │
                                     │ (ssh-ed25519-   │
                                     │  cert.pub)      │
                                     └────────────────┘

CA 持有私钥,给用户的公钥签名。签名后的证书(cert)有效期可以设(比如 24 小时)。

服务器不存你的公钥,只存 CA 的公钥。服务器看到你出示的证书,检查是 CA 签的、有效期没过——放行。

加人:CA 签一声,员工拿着证书就能上所有机器。
踢人:等证书过期就行了。不用挨个删 authorized_keys。
紧急回收:搭配 RevokedKeys 文件,一条命令废掉一个证书。


搭建步骤

1. 创建 CA 密钥对(离线机器)

选择一个不上生产网的机器,或者一台专门做 CA 的离线机器。

ssh-keygen -t ed25519 -f ~/.ssh/ca_user_key -C "SSH CA User Key 2026"
ssh-keygen -t ed25519 -f ~/.ssh/ca_host_key -C "SSH CA Host Key 2026"

两条:一条签用户证书,一条签主机证书。分开管理,权限不同。

私钥必须加密,密码短语设强一点。不是开玩笑的——谁拿到 CA 私钥,谁就能伪造证书登录所有机器。

2. 把 CA 公钥部署到所有服务器

每台服务器的 /etc/ssh/sshd_config 加一行:

TrustedUserCAKeys /etc/ssh/ca_user_key.pub

然后把 ca_user_key.pub 拷贝到 /etc/ssh/ca_user_key.pub

再在 /etc/ssh/sshd_config 里加上(可选但推荐):

RevokedKeys /etc/ssh/revoked_keys

重启 sshd:

sudo systemctl restart sshd

搞定。以后所有服务器的 authorized_keys 文件可以删掉。清空。一干二净。

3. 为客户签发证书

员工生成自己的密钥对(用 Ed25519):

ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519

把公钥 ~/.ssh/id_ed25519.pub 发给 CA 管理员(或者通过内部工具自助签发)。

CA 签发:

ssh-keygen -s ~/.ssh/ca_user_key \
  -I "lihua@example.com" \
  -n "lihua,root" \
  -V "+52w" \
  ~/.ssh/id_ed25519.pub

参数解读:

  • -s:指定 CA 私钥
  • -I:证书身份标识,用于日志审计
  • -n:允许登录的用户名,逗号分隔
  • -V:有效期,+52w 是一年;推荐个人密钥给 30-90 天

输出文件:id_ed25519-cert.pub,这就是证书。

员工把这个证书放到 ~/.ssh/ 目录下(和密钥对一起),SSH 客户端会自动识别。

验证一下:

ssh -i ~/.ssh/id_ed25519 lihua@server1

如果没问题,应该直接登录成功,不会再提示输入密码。

4. 主机证书(可选——彻底消灭 known_hosts 警告)

每次连新服务器时 The authenticity of host ... can't be established 这个警告,所有人都见过。

主机证书解决这个问题。

首先,服务器也需要把自己的主机公钥交给 CA 签发:

ssh-keygen -s ~/.ssh/ca_host_key \
  -I "server01.example.com" \
  -h \
  -V "+5y" \
  /etc/ssh/ssh_host_ed25519_key.pub

-h 表示这是主机证书。生成的 ssh_host_ed25519_key-cert.pub 放到 /etc/ssh/ 下。

然后在 sshd_config 里加上:

HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub

重启 sshd。

客户端要做的是:在全局 ~/.ssh/known_hosts/etc/ssh/ssh_known_hosts 中加一条:

@cert-authority *.example.com ssh-ed25519 AAAAC3... (CA 主机公钥)

以后连接 *.example.com 的任何服务器,自动验证主机证书由 CA 签发,不会再有警告。


日常管理:加人、踢人、轮换

加人:员工提交公钥 → CA 签发证书(设 90 天有效期)→ 员工拿到 cert → 直接登录。零服务器操作。

正常离职:等证书过期。员工拿到的证书有有效期,过期自然失去权限。不需要做任何操作。

紧急回收:在 /etc/ssh/revoked_keys 文件中写入证书序列号:

ssh-keygen -L -f ~/lihua-id_ed25519-cert.pub  # 查看序列号
echo "serial: 1234" | sudo tee -a /etc/ssh/revoked_keys

一条命令推送到所有服务器(Ansible/ssh 循环),立即生效。

CA 私钥轮换:生成新 CA 密钥对→重新签发所有有效证书→更新每台服务器的 TrustedUserCAKeys。这个动作应该在设计时就自动化。


真实的坑

没有自动化工具的 SSH CA 是另一种噩梦

如果你手动 ssh 到 50 台服务器部署 TrustedUserCAKeys,那你只是换了一种痛苦的方式。SSH CA 必须配合 Ansible、Salt、或自建脚本做分发。CA 签发的自动化是收益最大化的前提。

证书有效期太短会被骂

设 7 天有效期很安全,但员工每周要找 CA 管理员续签。大部分团队折中在 30-90 天,配合用户自助签发工具(比如写个小 Web 页面 + 公司 SSO 认证)。

SSH 客户端版本

OpenSSH 5.4+ 支持 CA 功能(2010 年),Ubuntu 16.04+、CentOS 7+ 都内置支持。基本上不需要担心版本问题。但 Windows 自带的 OpenSSH 需要确认版本——Windows 10 1809+ 可以,更老的建议用 WSL。

不兼容遗留系统

有些堡垒机、跳板机、第三方工具不支持证书认证。需要单独给这些系统配置传统的密钥方式。


总结

SSH CA 签名认证做三件事:

  1. 统一信任中心:一台 CA 管所有服务器信任
  2. 时间绑定的权限:证书过期是天然回收机制
  3. 零配置新机器:新服务器部署时配好 TrustedUserCAKeys,之后证书级别的任何操作不需要碰它

如果用一句话说清楚:让 SSH 密钥管理从手工作坊变成工业化流水线。

配合 kncokd + SSH CA + fail2ban 三层,你的 SSH 防线已经超过大多数企业标准了。


原文发表于 cn-res.vip,没有版权自由转载。标明出处非常感谢,删了也没事。