适用场景
服务器数量增长到几十台以上后,传统「把公钥塞进每台机器 authorized_keys」的运维方式会暴露三个问题:人员离职后密钥清理不彻底、密钥无有效期一旦泄露长期可用、新机器上线需要逐台分发公钥。SSH 证书认证通过引入一个自建 CA(Certificate Authority),用短期证书替代长期密钥,把「每台机器授权」改为「CA 一次性签发」,是规模化 SSH 访问治理的标准做法。本文适用于运维团队、云主机集群、跳板机与 CI/CD 发布账号的 SSH 登录改造。
前置条件
- OpenSSH 版本不低于 6.5(证书认证自该版本引入),推荐 8.x 以上;执行
ssh -V确认 - 至少两台 Linux 主机,一台作为证书签发机(可离线),其余作为目标服务器
- 目标服务器 sshd 配置文件路径 /etc/ssh/sshd_config,具备 root 或 sudo 权限
- 各主机系统时间同步(chrony 或 ntpd),证书校验强依赖时间
原理说明
SSH 证书认证的核心是把信任锚点从「每台服务器的 authorized_keys 列表」上移到一个 CA 公钥。目标服务器只需在 sshd 中配置 TrustedUserCAKeys 指向 CA 公钥,此后任何由该 CA 私钥签发、且在有效期与 principal(主体名)范围内的证书,都可直接登录,无需在服务器上保留任何用户公钥。
- 签发者对用户 → User CA:用于签发用户登录证书(-s user_ca)
- 签发者对主机 → Host CA:用于签发服务器主机证书(-h),客户端借此免除首次连接时的指纹确认
- 证书包含字段:Key ID(-I)、有效期(-V)、主体名(-n)、序列号、来源限制(-O),可随时通过 KRL(Key Revocation List)吊销
操作步骤
1. 生成 CA 密钥对
在签发机上创建用户 CA 与主机 CA,私钥权限必须为 600 且不入库、不随代码分发。
sudo mkdir -p /etc/ssh/ca && sudo chmod 700 /etc/ssh/ca
sudo ssh-keygen -t ed25519 -f /etc/ssh/ca/user_ca -C "user-ca" -N ""
sudo ssh-keygen -t ed25519 -f /etc/ssh/ca/host_ca -C "host-ca" -N ""
sudo chmod 600 /etc/ssh/ca/user_ca /etc/ssh/ca/host_ca
ls -l /etc/ssh/ca/
参数说明:-t ed25519 指定密钥算法;-N “” 表示空密码短语(便于自动化签发,但私钥文件本身必须严格保护)。
2. 目标服务器信任用户 CA
把 user_ca.pub 分发到各服务器的 /etc/ssh/ 目录,并在 sshd_config 中声明信任。
# 在每台目标服务器执行
sudo scp ca_server:/etc/ssh/ca/user_ca.pub /etc/ssh/user_ca.pub
sudo tee -a /etc/ssh/sshd_config >/dev/null <<'EOF'
# SSH 证书认证
TrustedUserCAKeys /etc/ssh/user_ca.pub
EOF
sudo sshd -t && sudo systemctl reload sshd
如需要求证书主体名必须存在于系统账户,可追加 AuthorizedPrincipalsFile /etc/ssh/auth_principals/%u,在对应文件中写入允许的 principal 列表(每行一个)。
3. 签发用户登录证书
用户生成密钥对后把公钥交给 CA 签发,证书有效期建议 8 小时至 7 天。
# 用户侧:生成密钥对
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -C "alice" -N ""
# 把 id_ed25519.pub 提交给 CA(如通过工单或内部平台)
# CA 侧:签发证书,有效期 8 小时,主体名 alice
sudo ssh-keygen -s /etc/ssh/ca/user_ca \
-I "alice@corp-20260911" \
-n alice \
-V +8h \
-O clear_allow_extensions \
/tmp/alice.pub
# 产出 /tmp/alice-cert.pub,回传给用户
关键参数:-I 为 Key ID(写入日志,便于审计);-n 为允许的登录主体名,多个用逗号分隔;-V +8h 为相对有效期,也可写绝对时间 -V 20260911:20260912。
用户把证书放到私钥同目录并命名为 <私钥名>-cert.pub,sshd 会自动加载:
mv alice-cert.pub ~/.ssh/id_ed25519-cert.pub
ssh alice@web01.example.com
4. 签发主机证书(可选但强烈推荐)
# 目标服务器上签发自身主机证书,有效期 52 周
sudo ssh-keygen -s /etc/ssh/ca/host_ca \
-I "host-web01" -h \
-n web01.example.com,10.0.0.11 \
-V +52w \
/etc/ssh/ssh_host_ed25519_key.pub
sudo tee -a /etc/ssh/sshd_config >/dev/null <<'EOF'
HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub
EOF
sudo sshd -t && sudo systemctl reload sshd
# 客户端 known_hosts 声明主机 CA,免除逐台指纹确认
echo "@cert-authority *.example.com $(cat /etc/ssh/ca/host_ca.pub)" >> ~/.ssh/known_hosts
配置验证
查看证书内容,确认主体名、有效期与用途正确:
ssh-keygen -L -f ~/.ssh/id_ed25519-cert.pub
验证 sshd 已加载信任的 CA:
sudo sshd -T | grep -i trustedusercakeys
# 预期输出:trustedusercakeys /etc/ssh/user_ca.pub
登录时观察服务器认证日志,应出现证书认证成功记录:
sudo journalctl -u ssh -n 20 | grep -i "Accepted publickey"
# 预期包含:Accepted publickey for alice ... ED25519-CERT SHA256:...
客户端调试可用:ssh -vvv alice@web01.example.com,在输出中检索 Offering public key 与 Server accepts key 两行。
常见问题
FAQ 1:证书认证后,原来的 authorized_keys 公钥登录还能用吗?
可以,两者并行不冲突。sshd 会先按证书认证处理,失败后回退到 authorized_keys。改造期间建议保留原公钥,待全部用户切换证书后,再通过 AuthorizedKeysFile none 关闭公钥认证以强制证书登录。注意该指令会同时禁用无证书的密钥登录,务必确认证书链路已完全可用再修改。
FAQ 2:证书明明未过期,为什么登录报「Permission denied (publickey)」?
按以下顺序排查:
- 证书文件名:必须为私钥名后加
-cert.pub,否则 ssh 不会自动加载,需用-i显式指定 - 时间偏差:证书校验基于时间,客户端或服务器任一方的时钟误差超过有效期窗口即失败。执行
timedatectl status检查同步状态 - principal 不匹配:登录用户名必须落在证书的 -n 列表中,或存在于 AuthorizedPrincipalsFile
- 服务器未信任 CA:确认 TrustedUserCAKeys 路径正确且文件可读,reload 后生效
定位最直接的方式是客户端 ssh -vvv 与服务器端 sudo /usr/sbin/sshd -ddd -p 2222 双端对照日志。
FAQ 3:如何撤销一张已签发但未过期的证书?
SSH 证书无法单独撤销,但由于采用短期有效期,通常等待过期即可。若需立即吊销,使用 KRL(Key Revocation List):
# CA 侧生成吊销列表
sudo ssh-keygen -k -f /etc/ssh/ca/revoked_keys -s /etc/ssh/ca/user_ca /tmp/alice.pub
# 目标服务器加载
sudo tee -a /etc/ssh/sshd_config >/dev/null <<'EOF'
RevokedKeys /etc/ssh/revoked_keys
EOF
sudo sshd -t && sudo systemctl reload sshd
已撤销的证书在 KRL 生效后立即失效,ssh -vvv 中可见 key revoked 提示。
总结
SSH 证书认证把「逐台分发公钥」变成「CA 统一签发」,收益集中在三点:短期有效把密钥泄露的时间窗口从永久压缩到数小时;集中吊销用 KRL 一次性失效;可审计通过 Key ID 把每次登录关联到具体签发记录。落地建议按顺序推进:先建主机 CA 消除指纹确认,再建用户 CA 并保留原公钥并行运行,最后关闭公钥认证强制证书登录。CA 私钥必须离线保存或放入硬件模块,一旦泄露等同于全部服务器失守。