证书管理:如何构建和运行内部PKI

infisical 发布于 2026-07-01 阅读 144

本文全面介绍内部私有PKI(公钥基础设施)的构建与运维。

证书管理:如何构建并运行内部 PKI

博客图片

在大多数 TLS 环境中,每当服务证明其身份或加密连接时,背后都有证书在发挥作用,而公钥基础设施(PKI)则决定是否信任该证书。PKI 是由证书颁发机构(CA)、密钥和信任关系组成的系统,使双方无需事先共享秘密即可相互验证。

颁发证书很容易。你不需要复杂的服务或工具。单条 OpenSSL 命令就能生成语法上有效的 X.509 证书,自托管 CA 工具可以全天候为其签名。

真正的工作在于证书周围的方方面面:你需要保护根密钥十年之久,吊销功能不能离线,续期需要跟上证书生命周期缩短的步伐,准确记录所有已颁发的证书,并且要有经得起审查的审计追踪。运行 OpenSSL 并不能提供这些。

这些周边工作正是正确运行一个始终在线服务所需的全部内容,而现代的解决方案大多在于自动化:尽可能少地人工干预来颁发、续期和吊销证书。如果做得好,这就是 PKI 证书管理在实践中的样子。

什么是 PKI,它解决什么问题?

公钥基础设施的存在是为了回答一个问题:

当客户端连接到服务器时,它如何知道服务器是真实的,而不是中间位置的冒名顶替者?

PKI 通过信任锚点来回答这个问题。证书颁发机构签署证书,但客户端只有在证书能回溯到受信任的 CA,并通过客户端要求的检查(身份、有效期、允许的用途、CA 约束以及任何适用的吊销或策略检查)时,才会接受该证书。

一个可工作的 PKI 包含以下几个组件:

  • 证书X.509)是签署过的文档,将公钥绑定到身份,并包含有效期、允许的用途等元数据。X.509 是标准格式,包括保护网络流量的 TLS(传输层安全)证书。
  • 密钥对位于每个证书背后:私钥由所有者持有且绝不共享,公钥嵌入证书中供任何人使用。
  • 证书颁发机构颁发并签署证书,为其中的身份作担保。
  • 信任存储是系统信任的 CA 列表,随操作系统、浏览器和语言运行时一起分发。仅当证书能回溯到该存储中已有的 CA 时,它才被信任。
  • 吊销和验证服务允许客户端在使用证书之前检查其是否仍然有效,以防证书被泄露或提前吊销。

公共 PKI 使用浏览器和操作系统已信任的 CA。内部 PKI 则是私下运行相同的机制,但使用不同的信任存储:Java 密钥库、容器镜像、Kubernetes 配置包或服务网格配置都可以成为信任的载体。

这些成为你组织的受信任权威,意味着你需要承担公共 CA 所承担的所有责任,包括那些处理不当可能导致服务中断的责任。

内部 PKI 的运营模式

在选择根 CA、创建中间 CA 或配置自动化之前,将 PKI 分解为其必须执行的任务会很有帮助。内部 PKI 不仅仅是一个签署证书的 CA。它必须作为一个具有多个连接层的信任系统来运行。

  • 第一层是信任锚点。这是你的组织决定信任并分发给需要验证内部证书的系统的根证书。PKI 中的其他一切都依赖于这个决定,因为证书只有在依赖方能构建回退到受信任根的信任链时才有用。
  • 第二层是颁发路径。根通常不直接为日常服务签署证书。相反,它将这项工作委托给一个或多个中间 CA。这些颁发 CA 应用证书配置文件,检查请求者是否有权获取所请求的证书,并在请求有效的情况下签署证书。
  • 第三层是分发。必须在连接的两端建立信任:客户端需要在其信任存储中有正确的根证书,而服务器、设备或用户需要安装自己的叶证书,以便应用程序可以使用它们。这通常是内部 PKI 最难的部分,因为所涉及的系统各自以不同方式存储和信任证书。
  • 第四层是验证和吊销。在客户端信任证书之前,它必须验证证书的真实性和有效性。吊销是在证书到期前使其失效的方式,例如在密钥泄露时。证书吊销列表(CRL)、在线证书状态协议(OCSP)和短生命周期证书是管理该风险的主要方法。
  • 第五层是生命周期操作。证书被创建、部署、续期、吊销、轮换、发现、审计,并最终被替换。这部分将 PKI 从加密机制转变为可运营的系统。没有生命周期管理的 PKI 仍然可以颁发证书,但无法可靠地防止服务中断、执行策略或证明后续发生的情况。

思考内部 PKI 的一个有用方式是:层级创建信任,颁发委托信任,分发传播信任,验证检查信任,生命周期管理防止信任随时间衰减。

根 CA 和中间 CA

层级结构的顶部是根 CA。其证书是自签名的,意味着它为自己作担保,其公钥被分发到每个信任存储。根的私钥是系统中最有价值的秘密,因为该密钥签署的任何证书都会自动被信任。如果它泄露,PKI 中的每个证书都会变得可疑,整个结构必须重建。

由于该密钥价值极高,你不会用它进行日常颁发。相反,根签署一个或多个中间 CA 证书,而这些中间 CA(也称为颁发 CA)负责实际向服务器和客户端颁发证书的工作。根签署中间证书,几乎不做其他事情。

CA 层级结构,显示离线根 CA 签署两个中间颁发 CA

这种分离带来了两个好处。根密钥可以保持离线并物理断开,远离攻击者可能触及的网络。如果某个中间 CA 被攻破,你可以吊销该中间 CA 并颁发替换证书,而无需触及根或向机群中的每台机器推送新的信任。

结果是形成一个信任链:从证书向上追溯到客户端已信任的根。中间 CA 签署服务器的证书,根签署中间 CA,而根存在于客户端的信任存储中。

当客户端收到服务器的证书时,它会沿此链向上追溯,看是否能到达它信任的根。如果能,则链成立,证书可以被接受。如果不能,客户端拒绝该证书。

设计 CA 层级结构

层级是证书颁发机构管理的组织原则,因为证书通过继承工作。有三种常见设计,对大多数组织而言,只有一种是正确答案。

设计 结构 适用场景
单层 一个 CA 颁发所有证书 仅限实验室和测试。没有隔离性,CA 被攻破则整个 PKI 被攻破。
双层 离线根加一个或多个在线颁发 CA 几乎所有生产环境。你获得隔离性和离线根。
三层 在根和颁发 CA 之间增加一个策略 CA 大型企业,拥有多个团队或严格的法规分离。额外的仪式对大多数组织来说过于复杂。

对几乎所有人来说,答案是双层:一个气隙根(即物理上离线的根),其唯一工作是签署中间证书,以及在线颁发 CA 负责日常工作。

你可以运行一个或多个颁发 CA。将颁发工作分散到多个中间 CA 可以限定每个 CA 的范围,例如每个环境、每个业务单元或每种证书类型(如 TLS 服务器证书与设备注册)使用单独的颁发 CA。这样,某个分支的问题或策略变更只会局限在该分支内,而不会影响所有证书。代价是每个额外的 CA 都需要多保护一个密钥,并多运维一个服务。

证书如何颁发:X.509、CSR 和信任链

颁发是 X.509 证书、证书签名请求(CSR)和 CA 层级结构结合的地方。

证书颁发流程:服务器生成 CSR,CA 验证并签署,客户端遍历信任链

从需要证书的服务开始,例如一个名为 api.example.com 的内部 API。

该服务首先生成私钥和 CSR。私钥保留在服务本地,绝不应发送给 CA。CSR 包含对应的公钥以及服务请求 CA 认证的身份,例如 api.example.com

CA 收到该 CSR,但不应盲目签署请求者提交的任何内容。CSR 只是一个请求。在颁发证书之前,CA 会根据证书配置文件检查请求。

对于 TLS 服务器证书,该配置文件可能规定:

属性 示例策略
允许的身份 api.example.com
证书类型 TLS 服务器证书
最大有效期 30 天
密钥用途 仅服务器身份验证
CA 能力 不允许颁发其他证书
批准 对于批准的工作负载自动批准,对于敏感名称手动批准

如果请求符合配置文件,颁发 CA 就会签署证书。该签名将服务的公钥绑定到其身份。然后服务安装该证书,并在 TLS 握手时(通常连同构建信任链所需的中间证书一起)呈现给客户端。

当客户端连接时,它在信任证书之前先进行验证。它验证证书能否回溯到受信任的根,链中的每个签名是否有效,证书是否未过期,是否允许用于 TLS 服务器身份验证,以及证书中的身份是否与客户端期望访问的服务匹配。

这就是信任链在实践中的样子:

api.example.com 证书
由
TLS 颁发 CA 签署
由
客户端信任的根 CA 签署

重要的一点是 CA 控制着最终的证书。

这个简单的流程掩盖了真正的运维工作。它假设颁发 CA 的密钥受到保护,根证书已经分发给客户端,证书在过期前已续期,并且当密钥泄露时可以进行吊销或替换。还需要有人知道每个证书部署在哪里。这些假设正是 PKI 证书管理的起点。

搭建私有 CA

正确搭建私有 CA 主要在于保护密钥和分发信任。生成和签署证书只是其中的一小部分。

首先进行根密钥仪式。根密钥离线生成,最好是在硬件安全模块(HSM)(一种内部生成和存储密钥的专用设备,绝不允许私钥被提取)上生成。

这不是一次性设置。根必须定期回到在线状态,以重新签署其 CRL,而每一次都是一次有计划的、有见证的仪式,并具有相同的控制措施。

其余设置在此基础上展开:

  • 颁发 CA 的密钥保护。颁发 CA 的密钥是在线的,因此暴露于任何能访问服务器的实体。因此,它应该存放在 HSM、CloudHSM 或支持签名工作流并防止私钥提取的、基于 HSM 的密钥管理服务中。
  • 中间证书创建。根签署 CA 证书,从而建立所有下级证书继承的信任链。
  • 证书配置文件。每个配置文件限制了请求者可以请求的内容:允许的密钥用途、最大有效期以及可以覆盖的域名。配置文件强制执行最小权限原则,因此一个只需要单一服务证书的 CI 管道不能为其无权颁发的域名生成证书。

在依赖系统的信任存储中信任根之前,私有 CA 毫无用处。这些系统是依赖方:验证你的证书的服务器、客户端和设备。将根证书放入它们的信任存储是一项持续的工作。

这项工作涵盖:对于服务器和工作站使用配置管理(如 Ansible 或 Puppet);对于容器使用基础镜像或初始化容器;对于受管理的手机和笔记本电脑使用移动设备管理(MDM);对于 Kubernetes 使用 ConfigMap 或 trust-manager。

吊销证书:CRL 和 OCSP

证书在过期之前一直有效,这在私钥泄露或证书被错误颁发时成了问题。

有两种机制:

  • 证书吊销列表(CRL)是已签署的、按计划发布的已吊销序列号列表,发布到客户端可下载的高可用端点。它们是通用的基线,但随着吊销证书数量的增加,它们会变得庞大且获取缓慢。
  • 在线证书状态协议(OCSP)允许客户端查询单个证书并获得近乎实时的回答,这在 CRL 变得笨重时很重要。OCSP stapling 进一步改进:服务器自己获取签名的状态响应、缓存它,并在 TLS 握手时呈现,因此客户端完全不需要联系响应者。这消除了往返延迟以及向第三方泄露客户端访问站点的隐私问题。

更深层的问题是吊销证书和实际拒绝它之间的时间差。以下是你实际吊销一个证书时发生的情况:

  1. 你告诉 CA 根据序列号和原因吊销该证书。
  2. CA 记录它,并在下一个 CRL 中发布或更新 OCSP 响应者。
  3. 依赖方只有在下次获取 CRL 或查询 OCSP 时才会看到更改,这可能滞后一个发布间隔。
  4. 即使如此,那些软失败(当吊销服务不可达时继续处理)的客户端仍然会接受该证书。

因此,你声称“已吊销”的证书可能继续有效几分钟到几小时,或在软失败客户端上无限期有效。这个时间差正是短生命周期证书具有吸引力的主要原因:如果证书几天后自动过期,那么吊销路径就几乎不重要了。

大规模 PKI 证书生命周期管理

管理单个证书很简单。你可以生成它、安装它、监控其到期日期并手动续期。困难在于,没有哪个真实环境只有一个证书。它有成百上千个证书,由不同团队颁发,分布在服务器、负载均衡器和设备上,每个都有自己的到期日期和所有者,而且很多甚至没人记得创建过。PKI 证书生命周期管理是一门跟踪每个证书并使其保持最新的学科。

在这种规模下,你需要:

  • 完整且持续更新的清单。每个证书、其所有者、到期日期、颁发 CA 以及依赖它的服务。你不知道的证书就是那个在周六到期并导致服务宕机的证书,因为从未为其设置告警。
  • 自动续期由系统本身在到期前提前触发,而不是靠日历提醒(忙碌的一周可能会忽略它)。
  • 到期和生命周期告警集成到你的团队已在监视的工具中(如 Slack、PagerDuty 或 Webhook),这样失败的续期会响亮地出现,而不是无声无息。
  • 发现未管理的证书,这些证书出现在你流程之外,通常通过网络扫描找到清单遗漏的部分。这些影子证书会导致意外的服务中断和安全漏洞,因为它们会在没有警告的情况下过期,并且可能在没有真正策略的情况下颁发。
  • 策略文档。描述 PKI 允许做什么的证书策略,以及描述 CA 如何实际满足该策略的认证实践声明。审计员会要求这两者,严肃的客户安全审查也会要求。

证书生命周期:颁发、部署、监控、通过 ACME 自动续期,或吊销并重新颁发

所有这些都有时间限制。公共 TLS 证书的最长有效期现在为 200 天(之前是 398 天),而 CA/Browser Forum 的已批准时间表将在 2027 年 3 月缩短到 100 天,2029 年 3 月缩短到 47 天。Let's Encrypt 计划在 2028 年将其默认证书缩短到 45 天,并且已经提供六天选项

这些限制仅适用于由浏览器信任存储中的 CA 颁发的公共证书。来自你自己的内部 CA 的证书不受 CA/Browser Forum 的管辖,因此没有强制要求将内部有效期缩短到 47 天。但这一趋势会带动内部期望。许多团队自行缩短内部有效期,因为存活几天而不是一年的证书为恶意行为者留下的窗口要小得多。无论你选择哪种节奏,方向都是更频繁地续期,而今天感觉良好的手动习惯在你希望之前就会失效。这种压力是团队自动化此过程的主要原因。

开发者友好的 PKI 是什么样子

所有这些都可以在内部构建。你可以用 OpenSSL 生成密钥和 CSR,让它们被签署,安装证书,并为整个流程构建自动化。

但是,保持该可靠性的所有东西都需要你来构建并维护运行。

无论哪种方式,目标相同。一个开发者友好的 PKI,其颁发、续期和吊销证书都不需要人工干预,尤其是续期,应用程序所有者永远不需要记住。一些接口使之成为可能:

  • ACME(自动证书管理环境)是这些接口中最常见的,其优势在于围绕它的生态系统。ACME 客户端(如 Certbot)意味着服务可以使用现有软件自行请求和轮换证书。
  • REST API 覆盖了 ACME 无法触及的场景,例如 CI/CD 管道、Terraform 运行以及需要即时证书的应用程序启动脚本。
  • EST 和 SCEP 处理设备注册。EST(安全传输注册)和 SCEP(简单证书注册协议)是网络设备和物联网(IoT)设备用于获取和续期证书的标准,无需人为配置每个设备。
  • 在防护栏内的自助服务。开发者直接颁发自己的证书,而证书配置文件则限定每个请求允许包含的内容。

在小规模下,OpenSSL 加上几个脚本就能应付。超出此规模,一个托管的 PKI 证书管理系统可以提供相同的接口以及其背后的运维层,这样团队使用服务而不是运行它。

Infisical 这样的平台可以作为直接覆盖开发者侧需求的 PKI 证书管理器。

自建 vs 购买:谁来承担运维负担

因此,决策在于你是否要拥有这个运维层,还是将其交给别人。

  • 主权、气隙或法规排除了 SaaS 控制平面触及你的证书操作。
  • 你已经运行底层基础设施。已经在运营 HashiCorp Vault 的团队可以使用 Vault 的 PKI 引擎作为颁发 CA,并在其上使用 cert-manager,重复利用已有的基础设施和技能。
  • 你的需求确实特殊,例如不常见的算法或任何产品都无法适应的层级形状。
  • 经济性在极大规模下反转,在这种情况下按证书或按席位计费最终可能比一个专门的 PKI 团队更昂贵。

即使自建是正确的选择,维护成本也是实实在在的。选择自建就是选择无限期地为整个运维层配备人员并维持其运转,包括人员更替和审计,只要 PKI 存在。

对大多数团队来说,PKI 中值得关注的部分是策略和与自身系统的集成,而重新实现吊销可用性和密钥仪式增加的内容很少是特定于他们的。当没有硬性约束迫使自建时,合理的默认选择是将无差异的运维层外包,并将团队时间花在只有他们才能做的事情上。

从哪里开始

运行内部 PKI 更多的是运维而非密码学。签名已经解决且微不足道。持久的工作是在庞大、变化的车队中保持证书的可信和最新,而当今团队管理此问题的一致方法是尽可能利用工具进行自动化。

合理的顺序是首先确定层级结构,因为一切都继承自它,而双层结构几乎适合所有人。

  • 原文链接: infisical.com/blog/pki-i...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~

相关文章

0 条评论