4. 证书颁发机构(CA)搭建:根CA与中间CA的架构设计、自建CA(OpenSSL命令行)、企业CA(Microsoft ADCS)
聊到CA搭建,很多人第一反应就是“跑个OpenSSL命令就完事了”。嗯,确实能跑起来,但生产环境这么干,早晚要出事。我见过不少团队,根CA直接对外发证书,一旦私钥泄露,整个信任链都得重建——那场面,真是灾难级的。
这一章,咱们就聊聊正经的CA架构该怎么搭。说白了,就是两件事:分层和隔离。
4.1 为什么需要根CA + 中间CA?
先看一个最基础的架构图,你就明白了。
为什么要这么分层?我直接说结论:安全隔离。根CA是整个信任链的“命根子”,一旦私钥泄露,所有由它签发的证书都不再可信。所以根CA必须离线,放在保险柜里,甚至拔掉网线。中间CA负责日常签发,即使被黑,根CA可以吊销它,然后重新签发一个新的中间CA证书——整个信任链还能继续用。
4.2 自建CA:OpenSSL命令行实战
OpenSSL是自建CA的“瑞士军刀”。虽然命令行参数多到让人头疼,但掌握了核心流程,其实就那么几步。
4.2.1 搭建根CA
先创建目录结构,这是我一贯的做法:
mkdir -p ~/myCA/rootCA/{certs,crl,newcerts,private}
cd ~/myCA/rootCA
touch index.txt
echo 1000 > serial
然后生成根CA私钥和自签名证书:
# 生成根CA私钥(4096位,带密码保护)
openssl genrsa -aes256 -out private/ca.key.pem 4096
# 生成根CA自签名证书(20年有效期)
openssl req -new -x509 -days 7300 -key private/ca.key.pem \
-sha256 -out certs/ca.cert.pem \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/CN=MyRootCA"
4.2.2 搭建中间CA
中间CA的私钥生成方式一样,但证书需要由根CA来签发:
# 生成中间CA私钥
openssl genrsa -aes256 -out intermediate/private/intermediate.key.pem 4096
# 生成中间CA证书签名请求(CSR)
openssl req -new -key intermediate/private/intermediate.key.pem \
-sha256 -out intermediate/csr/intermediate.csr.pem \
-subj "/C=CN/ST=Beijing/O=MyCompany/CN=MyIntermediateCA"
# 根CA签发中间CA证书(5年有效期)
openssl ca -config openssl_root.cnf -extensions v3_intermediate_ca \
-days 1825 -notext -md sha256 \
-in intermediate/csr/intermediate.csr.pem \
-out intermediate/certs/intermediate.cert.pem
这里有个关键点:openssl_root.cnf 配置文件里必须定义 v3_intermediate_ca 扩展,包含 basicConstraints=CA:TRUE, pathlen:0。为什么?因为中间CA虽然可以签发证书,但不能继续往下签发子CA——这就是 pathlen:0 的作用。
4.2.3 用中间CA签发服务器证书
日常用得最多的就是这一步:
# 生成服务器私钥
openssl genrsa -out www.example.com.key 2048
# 生成CSR
openssl req -new -key www.example.com.key \
-out www.example.com.csr \
-subj "/C=CN/ST=Beijing/O=MyCompany/CN=www.example.com"
# 中间CA签发服务器证书(1年有效期)
openssl ca -config openssl_intermediate.cnf \
-days 365 -notext -md sha256 \
-in www.example.com.csr \
-out www.example.com.cert.pem
subjectAltName 扩展。结果Chrome直接报错“证书名称不匹配”。现在我的配置模板里,默认就带上SAN,省得后面返工。
4.3 企业CA:Microsoft ADCS
如果你在Windows环境里做企业CA,ADCS(Active Directory Certificate Services)是首选。它和AD域控深度集成,用户证书可以自动注册,省去了手动部署的麻烦。
4.3.1 ADCS的架构角色
| 角色 | 说明 | 我的建议 |
|---|---|---|
| 根CA | 企业信任锚点,离线安装 | 用Standalone CA模式,装完就拔网线 |
| 策略CA | 定义证书模板和颁发策略 | 通常和中间CA合并在同一台服务器 |
| 颁发CA | 实际处理证书请求 | 可以部署多台做负载均衡 |
4.3.2 部署步骤(精简版)
- 安装根CA:在离线服务器上运行
Server Manager → Add Roles and Features → Active Directory Certificate Services,选择“Certification Authority”,CA类型选“Root CA”。 - 安装中间CA:在在线服务器上同样安装ADCS,但CA类型选“Subordinate CA”。安装完成后,提交CSR到根CA进行签名。
- 配置证书模板:在中间CA上,通过“Certification Authority”管理控制台,右键“Certificate Templates” → “Manage”,复制并修改需要的模板(如Web Server、User等)。
- 自动注册策略:通过组策略(GPO)将证书模板发布到特定OU,域成员会自动申请和续订证书。
4.4 OpenSSL vs ADCS:怎么选?
这个问题没有标准答案,我根据自己的经验列了个对比表:
| 维度 | OpenSSL | ADCS |
|---|---|---|
| 成本 | 免费,Linux自带 | 需要Windows Server授权 + CAL |
| 自动化 | 需要自己写脚本 | AD域集成,自动注册/续订 |
| 管理界面 | 纯命令行 | GUI + PowerShell |
| 适合场景 | Linux环境、DevOps、小规模 | Windows域环境、大规模企业 |
| 证书模板 | 手动编辑OpenSSL配置 | 内置模板,可自定义 |
我个人习惯是:Linux环境用OpenSSL,Windows环境用ADCS。但如果团队里没有专职的PKI运维人员,我建议优先考虑ADCS——图形界面确实能降低出错的概率。
4.5 证书链的验证
CA搭好了,证书也签发了,怎么验证证书链是否完整?
用OpenSSL验证:
# 验证服务器证书是否由中间CA签发
openssl verify -CAfile intermediate/certs/ca-chain.cert.pem \
www.example.com.cert.pem
# 查看证书链
openssl s_client -connect www.example.com:443 -showcerts
这里有个坑:证书链文件必须包含根CA和中间CA的证书。我见过有人只把服务器证书部署到Nginx上,结果客户端因为找不到中间CA证书而报错。正确的做法是生成一个 ca-chain.cert.pem 文件,把根CA和中间CA的证书按顺序拼接起来:
cat intermediate/certs/intermediate.cert.pem \
rootCA/certs/ca.cert.pem > ca-chain.cert.pem
🔑 核心要点回顾:
- 根CA必须离线,中间CA负责日常签发
- OpenSSL搭建CA的核心是配置文件,建议从模板开始改
- ADCS适合Windows域环境,自动注册能省大量人力
- 证书链文件必须包含所有中间CA和根CA证书