Hotdry Blog

Article

SSH 证书实战:构建无密码、可过期的 SSH 认证体系

通过 SSH 证书替代传统公钥,实现无密码登录、自动过期、主机密钥轮换无感等工程化目标,提供完整配置清单与参数阈值。

2026-04-03systems

首次通过 SSH 连接到一台新服务器时,几乎所有用户都会遇到那个令人纠结的提示:「The authenticity of host can't be established」,然后在 TOFU(Trust on First Use,首次信任)的驱动下输入「yes」。这种体验在少量服务器场景尚可接受,但当运维规模扩展到数十甚至上百台主机时,传统公钥认证的弊端便逐一显现:每台机器需要单独部署 authorized_keys、主机密钥变更引发的「WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED」令人不安、员工离职后的密钥回收更是繁琐。SSH 证书正是为解决这些痛点而设计,它自 OpenSSH 5.4(2010 年 3 月)引入,机制远比 X.509 证书简单 —— 本质上仍是一对 SSH 密钥,只是附加了签名与有效期信息。

传统公钥认证的四大痛点

运维场景中,公钥认证的固有缺陷制约着效率与安全。首先是密钥分发的复杂度:每新增一个用户或每台新服务器,都需要将公钥复制到目标主机的 ~/.ssh/authorized_keys,这在动态环境中几乎是不可持续的操作。其次是 TOFU 机制 —— 首次连接时指纹被缓存到本地的 known_hosts 文件,后续主机密钥变更(例如系统重装)会触发刺耳的警告,用户往往不知所措。第三是密钥回收困难:员工离职后手动删除 authorized_keys 中的条目容易遗漏,形成隐蔽的安全风险。最后是主机密钥轮换的连锁反应 —— 重建服务器意味着所有客户端都需要重新确认主机指纹,这在大规模基础设施中是不可接受的。

SSH 证书的核心优势

SSH 证书通过引入认证机构(CA)的概念,一次签名即可打通整个基础设施。其核心优势体现在以下几个维度:

免部署 authorized_keys:用户公钥无需存在于目标服务器的 authorized_keys 文件中,CA 签发的证书天然被服务器信任。这意味着新员工入职时只需获取一张证书,即可访问所有授权机器。

自动过期机制:证书可设定明确的生命周期,例如 +1w(一周)、+24h(24 小时)、+52w(52 周)。过期后自动失效,无需手动撤销。需注意服务器与客户端时钟偏差可能导致验证失败,生产环境应启用 NTP 同步。

消除 TOFU 确认:客户端配置 @cert-authority 规则后,所有由该 CA 签发的主机证书自动被信任,首次连接不再弹出指纹确认对话框。

主机密钥轮换无感知:服务器重建时重新签发主机证书即可,客户端无需任何操作,因为信任关系建立在 CA 而非具体主机密钥上。

细粒度权限控制:签名时可指定 principals(-n 参数)限定可登录的用户名,支持 force-command(-O force-command)强制执行特定命令,支持 source-address 限制源 IP CIDR。例如 -O source-address=192.0.2.0/24 限定仅能从指定网段登录。

实施路径:五步构建 CA 体系

第一步:生成 CA 密钥对

CA 本质上是一个 ECDSA 或 ED25519 密钥对,建议使用 ECDSA 以获得更短的密钥长度,同时确保安全强度。创建专用目录并设置严格权限(umask 077):

umask 077; mkdir CA
ssh-keygen -t ecdsa -C "Production SSH CA" -f CA/ssh-ca
chmod -w CA/ssh-ca*

生成的 ssh-ca 为私钥(严格保管),ssh-ca.pub 为公钥(可分发至所有服务器)。

第二步:签署用户证书

用户将自己的公钥提交给 CA 管理员(或通过安全通道传递),管理员使用 CA 私钥签发证书。关键参数包括:-I(证书标识)、-n(允许登录的 principal,即用户名)、-z(序列号,用于审计)、-V(有效期):

ssh-keygen -s CA/ssh-ca -I "jane-jolie" -n jane -z 001 -V +1w jane.pub

生成的 jane-cert.pub 即为证书文件,使用时需与私钥 jane 放在同一目录:

ssh -i jane jane@server.example.com

若私钥设置了 passphrase,首次连接时 SSH 会提示输入,解密后的私钥可加入 ssh-agent 避免重复输入。查看证书详情:

ssh-keygen -L -f jane-cert.pub

输出显示证书类型、签发 CA、有效期、 principals 及扩展权限(如 permit-pty、permit-port-forwarding)。

第三步:签署主机证书

每台服务器的主机密钥也需要由 CA 签发。获取服务器的公钥(例如 ssh_host_ed25519_key.pub)后,使用 -h 参数签发主机证书:

ssh-keygen -h -s CA/ssh-ca -V +52w -I "server-001" -z 1000 -n server.example.com ssh_host_ed25519_key.pub

注意 -n 指定的 principal 应与客户端连接时使用的主机名或 IP 地址匹配。若需同时支持主机名和 IP 访问,可用逗号分隔: -n server.example.com,192.0.2.141

第四步:服务器端配置

将 CA 公钥安装到服务器,并配置 sshd 信任该 CA:

install -m444 /path/to/ssh-ca.pub /etc/ssh/ssh-ca.pub
echo "TrustedUserCAKeys /etc/ssh/ssh-ca.pub" >> /etc/ssh/sshd_config
echo "HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub" >> /etc/ssh/sshd_config
sshd -t && systemctl restart sshd

重启后,sshd 将信任所有由该 CA 签发的用户证书,无需在用户的 authorized_keys 中添加任何内容。

第五步:客户端配置

客户端只需在 known_hosts 中添加一条 @cert-authority 规则,即可信任由该 CA 签发的所有主机:

echo "@cert-authority *.example.com $(cat CA/ssh-ca.pub)" > ~/.ssh/known_hosts

pattern 支持通配符(如 *.example.com)和逗号分隔的多个模式。此后连接任何匹配的主机都不会触发指纹确认,且主机密钥变更对用户透明。

高级约束与审计

强制命令与功能限制

签名时可嵌入强制性约束,限制用户行为。例如强制仅能执行 date 命令,即使客户端请求 uname 也会被替换:

ssh-keygen -s CA/ssh-ca -I "jane-jolie" -n jane -z 2 -V +1w -O force-command=/usr/bin/date jane.pub

清除所有默认扩展并显式启用部分功能:

ssh-keygen -U -s CA/ssh-ca -I "jane-jolie" -n jane,root -z 4 -V +1w \
    -O clear \
    -O extension:permit-agent-forwarding \
    -O extension:permit-port-forwarding \
    jane.pub

上述配置禁用了 PTY 分配,用户登录后无法获得交互式终端,但可使用端口转发功能。

源 IP 限制

限制证书仅能从特定网段使用:

ssh-keygen -s CA/ssh-ca -I "jane-jolie" -n jane -z 3 -V +1w -O source-address=192.0.2.0/24 jane.pub

不符合源地址的连接请求将被服务器拒绝并记录到日志。

审计与故障排查

服务器日志(auth.log 或 journalctl)记录了所有证书认证的详细信息,包括用户指纹、证书 ID、序列号、签发 CA 的指纹。典型日志条目:

sshd-session[3099]: Accepted publickey for jane from 192.0.2.42 port 17087 ssh2: 
ECDSA-CERT SHA256:2WH263LauVfk5XvxHvrdvNt0y9OgaHBLSvcQ+R6u/KE 
ID Jane Jolie (serial 1) CA ECDSA SHA256:A5ZBb5b/GbAv03EAb8fmDzv4p+q0g8Ulxrt8QZpbamM

常见错误排查:若连接时仍提示输入密码,检查服务器日志中是否出现「Certificate invalid: name is not a listed principal」—— 这表明证书的 -n 参数未包含目标用户名;若提示主机指纹确认,检查证书是否已过期(Certificate invalid: expired)或 known_hosts 中的 @cert-authority 规则是否正确。

参数速查清单

场景 关键参数 示例值
用户证书有效期 -V +1w(7 天)、+24h(24 小时)
允许登录的用户 -n jane 或 jane,root(多用户逗号分隔)
主机证书有效期 -V +52w(一年)
主机 principal -n server.example.com,192.0.2.141
强制命令 -O force-command=/path -O force-command=/usr/bin/date
源 IP 限制 -O source-address=CIDR -O source-address=192.0.2.0/24
禁用 PTY -O clear 先用 -O clear 清除默认扩展

局限性与适用场景

SSH 证书适用于管理员拥有 CA 私钥且对目标服务器拥有完全控制权的场景。对于共享主机或多租户环境,传统 authorized_keys 机制更为合适,因其不依赖 CA 密钥的分发与信任链管理。在自建基础设施中,采用证书体系可显著降低运维负担:新增用户只需签发证书,新增服务器只需部署 CA 公钥与主机证书,所有密钥生命周期由有效期自动管理,离职回收可通过过期机制无缝完成。


参考资料

systems