![]()
2010年发布的OpenSSH 5.4版本里,藏着一套能解决90%服务器管理噩梦的机制。15年过去了,它依然躺在代码库里吃灰,而运维们还在手动复制粘贴公钥到上百台机器。
这不是技术落后,是认知断层。
SSH证书(Certificate)的工作逻辑和TLS证书几乎一模一样:一个可信的证书颁发机构(CA)签发凭证,客户端和服务器各自验证这张凭证的真伪。但OpenSSH的实现比TLS早了整整5年,却几乎没人用。
问题出在路径依赖。传统SSH密钥模型——每个用户生成密钥对,公钥分发到每台服务器的authorized_keys——在"一个人管三台服务器"的场景下确实顺手。一旦规模膨胀,这套模型就变成了运维的债务黑洞。
新员工入职?把他的公钥塞进几十台机器的authorized_keys。有人离职?你根本记不清楚他的密钥散落在哪些角落。第一次连新服务器?面对那个"是否信任此主机指纹"的提示,99%的人直接敲yes——这个习惯等于把中间人攻击的邀请函贴在门上。
SSH证书把这一切压缩成三条命令:生成CA密钥对、签发证书、配置信任锚。之后,用户入职只需签发一张证书,离职只需吊销这张证书。主机身份由CA背书,不再需要人类用肉眼去"认"指纹。
证书模型 vs 传统模型:一场不对称的消耗战
传统模型的隐性成本被严重低估。Facebook在2016年开源的facebookincubator/certificates项目文档里算过一笔账:他们当时管理着数万台服务器,传统SSH密钥的轮换周期是90天,每次轮换需要消耗约4000人时的工程时间。
证书模型的核心优势是"信任收敛"。传统模型里,信任关系呈N×M的网状扩散——N个用户乘以M台服务器。证书模型里,信任关系收敛到两个锚点:用户CA和主机CA。
这个设计直接复制了TLS证书的成熟经验。如果你理解浏览器怎么验证HTTPS网站的身份,你已经懂了SSH证书的80%。
但复制经验不等于复制代码。OpenSSH的证书实现有几处关键差异:
第一,SSH证书没有证书链的概念。TLS世界里,根CA签发中间CA,中间CA再签发终端证书,形成可审计的信任链。SSH证书是扁平结构,CA直接签发给用户或主机,简化了实现,也限制了灵活性。
第二,SSH证书的有效期可以精确到秒。TLS证书通常以年为单位,SSH证书常见配置是按周或按月轮换。Facebook的生产环境用的是24小时有效期的用户证书,配合自动化签发系统,实现"凭证即服务"。
第三,SSH证书支持"主体"(Principal)的灵活定义。一张用户证书可以声明"这个用户在所有web服务器上是www-data,在数据库服务器上是dbadmin",权限粒度由CA策略控制,而不是由每台服务器的authorized_keys独立配置。
这些差异说明,SSH证书不是TLS证书的拙劣模仿,而是针对服务器管理场景的定向优化。
实操:两条CA密钥和三条命令
部署证书模型需要两个独立的CA:用户CA(User CA)和主机CA(Host CA)。分离的目的是控制爆炸半径——如果用户CA私钥泄露,攻击者只能签发虚假用户身份;主机CA泄露,攻击者只能伪造服务器身份。两者同时泄露的概率,远低于单一CA的灾难场景。
生成CA密钥对的命令和生成普通SSH密钥没有区别,只是命名约定不同:
ssh-keygen -t ed25519 -f user_ca -C "user-ca@yourorg"
ssh-keygen -t ed25519 -f host_ca -C "host-ca@yourorg"
这两条命令产出四个文件:user_ca和user_ca.pub,host_ca和host_ca.pub。带.pub后缀的是公钥,可以分发到任何需要验证证书的地方。不带后缀的是私钥,需要按照根CA的安全标准保管——离线存储、硬件安全模块(HSM)、双人控制,视你的威胁模型而定。
主机证书的签发流程如下。假设你已经有一台运行中的服务器,它的主机密钥通常位于/etc/ssh/ssh_host_ed25519_key.pub:
ssh-keygen -s host_ca \
-I "webserver-prod-01" \
-h \
-n "webserver-prod-01.example.com,10.0.1.50" \
-V +52w \
/etc/ssh/ssh_host_ed25519_key.pub
参数拆解:-s指定签名用的CA私钥;-I是证书标识,仅用于日志审计;-h声明这是主机证书(省略则默认为用户证书,签错类型会导致验证失败);-n列出证书绑定的主体,可以是主机名、IP地址或通配符;-V +52w设置有效期为52周。
执行后生成ssh_host_ed25519_key-cert.pub,这就是主机证书。把它复制回服务器,然后在sshd_config里添加一行:
HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub
重启SSH服务,这台服务器现在会向所有连接者出示证书,而不是裸公钥。
客户端侧的配置更简单。在~/.ssh/known_hosts或系统级的/etc/ssh/ssh_known_hosts里添加:
@cert-authority *.example.com ssh-ed25519 AAAA...your-host-ca-public-key...
@cert-authority指令告诉SSH客户端:对于匹配*.example.com的任何主机,只要它出示的证书能用后面这串公钥验证通过,就自动信任,不再提示指纹确认。
第一次配置完成后,新服务器上线不再需要人工确认指纹。新服务器只需要申请一张主机证书,客户端侧零变动。
用户证书:入职一张证,离职一键废
主机证书解决的是"服务器身份可信"问题,用户证书解决的是"访问权限可管理"问题。
为用户签发证书的流程类似,只是参数指向不同:
ssh-keygen -s user_ca \
-I "alice@example.com" \
-n "alice,www-data" \
-V +1d \
alice.pub
这里-n指定的是用户名主体。Alice可以用这张证书登录任何允许"alice"或"www-data"用户的服务器。-V +1d把有效期压到1天,强制每日续签,降低凭证泄露后的窗口期风险。
服务器侧需要配置信任用户CA。在sshd_config里添加:
TrustedUserCAKeys /etc/ssh/user_ca.pub
重启后,这台服务器接受任何由该CA签发的用户证书,authorized_keys文件可以彻底退役。
权限粒度控制通过证书的主体字段实现。你可以签发一张证书让Bob在所有web服务器上是www-data,在数据库服务器上是readonly,在跳板机上保持bob。这种动态映射是传统静态authorized_keys无法实现的。
吊销机制是证书模型的另一张底牌。OpenSSH支持两种吊销方式:证书序列号列表(Serial)和密钥标识列表(Key ID)。
序列号方式需要CA在签发时分配唯一序列号(-z参数),然后维护一个吊销列表文件:
RevokedKeys /etc/ssh/revoked_keys
文件格式每行一个十六进制序列号。用户离职时,把他的证书序列号追加进这个文件,所有服务器即时生效。
密钥标识方式更粗暴:直接列出被吊销的-I标识符。适合小规模场景,大规模下查询效率不如序列号。
吊销的实时性取决于配置分发速度。如果你用Puppet、Ansible或类似工具管理revoked_keys文件,吊销延迟等于你的配置管理周期。追求实时的话,需要把吊销列表塞进集中式存储,让sshd动态加载。
为什么15年了还没普及?
技术成熟度和采用率之间的鸿沟,从来不只是技术问题。
第一个障碍是工具链的缺失。TLS证书有Let's Encrypt、Certbot、ACME协议构成的完整生态,申请、续期、部署可以全自动化。SSH证书没有等价物,每个组织都要自己写脚本、搭流程、造轮子。
Facebook开源的certificates项目是一个参考实现,但它绑定的是Facebook内部基础设施(如Kerberos认证),移植成本不低。Netflix的Bless项目更轻量,但2019年后停止维护。Square的ssh-ca、Lyft的ssh-cert-authority各有取舍,没有形成社区共识。
第二个障碍是认知惯性。多数运维团队把SSH密钥管理当成"已经解决的问题"——尽管解决得很痛苦。痛苦被归因为"规模大了就这样",而不是"模型选错了"。
第三个障碍是安全审计的合规要求。很多企业的SOC 2、ISO 27001审计清单里,SSH密钥管理条目还停留在"定期轮换""记录访问日志"层面,没有强制要求证书模型。合规驱动力的缺位,让技术升级变成纯成本项。
但风向正在变化。2023年,美国网络安全与基础设施安全局(CISA)发布的《联邦机构SSH安全指南》首次把证书模型列为"推荐实践"。同年,欧盟NIS2指令的配套技术规范里,SSH证书被纳入"安全通信"控制项的合规路径之一。
云厂商的动作更快。AWS Systems Manager Session Manager支持通过SSH证书进行身份验证,Google Cloud的OS Login服务底层就是证书模型,Azure的VM登录扩展也在2022年添加了证书支持。
这些信号指向同一个判断:证书模型正在从"最佳实践"变成"基准要求"。
对于还在传统模型里挣扎的团队,迁移路径比想象中平缓。不需要一次性替换所有服务器,可以按业务单元逐步试点。用户CA和主机CA可以独立部署,先解决"服务器身份可信"问题,再推进"用户权限可管理"。
关键决策是CA私钥的保管策略。小型团队可以用硬件安全密钥(如YubiKey)存储CA私钥,签名操作需要物理接触。中型团队考虑HashiCorp Vault、AWS KMS等托管HSM服务。大型团队需要完整的密钥 ceremony 流程,多人参与、分片存储、审计日志缺一不可。
证书有效期是另一个需要权衡的参数。Facebook的24小时极端配置,背后是自动化签发系统的支撑。手动签发场景下,周级或月级有效期更现实。主机证书可以放宽到年级别,因为主机身份变更频率远低于人员流动。
主体字段的设计反映组织架构。按项目团队划分?按职能角色划分?按访问级别划分?证书模型的灵活性是把双刃剑,前期规划不足会导致后期证书泛滥、管理反噬。
一个务实的起点:先用主机证书解决"首次连接确认指纹"的痛点。这个场景的ROI最高——零用户培训成本,立即消除中间人攻击向量,为后续用户证书推广建立信任基础。
当你的团队第一次SSH到新服务器而不再看到那个红色的指纹警告时,那种体验有点像从HTTP切换到HTTPS:之前觉得"反正没出事"的习惯,在对比之下突然显得荒唐。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.