私有 CA 搭建与管理:使用 OpenSSL 创建企业内部证书体系
在企业内部网络中,使用私有证书颁发机构(CA)可以摆脱对公共 CA 的依赖,实现低成本、高可控的内部 TLS 加密、代码签名、设备认证等。本文将详细介绍如何使用开源工具 OpenSSL 搭建一套完整的私有 CA 体系,包括根 CA、中间 CA、服务器证书和客户端证书的签发,以及SSL证书吊销列表(CRL)的管理。
1. 为什么需要私有 CA?
成本控制:公共 CA 签发的证书通常按年收费,内部大量设备需要证书时成本高昂。
灵活性:可自定义证书有效期、扩展字段(如 SAN)、密钥用法等。
安全性:私钥完全掌握在自己手中,无需将内部域名暴露给第三方。
自动化:便于与内部运维系统集成,实现自动化签发和续签。
OpenSSL 是开源的加密库,提供了完整的命令行工具,足以完成 CA 的搭建和证书管理。
2. 准备工作
2.1 安装 OpenSSL
大多数 Linux 发行版默认已安装 OpenSSL。检查版本:
bash
openssl version
若未安装,使用包管理器安装(以 Ubuntu 为例):
bash
sudo apt update && sudo apt install openssl
2.2 规划目录结构
建议为 CA 创建独立的目录树,便于管理和备份。示例结构:
~/ca/
├── root-ca/ # 根CA目录
│ ├── certs/ # 已签发的证书(根CA签发的中间CA证书)
│ ├── crl/ # 吊销列表
│ ├── newcerts/ # 新签发的证书副本
│ ├── private/ # 私钥(权限必须为600)
│ ├── index.txt # 证书数据库
│ ├── serial # 下一个证书序列号
│ └── openssl.cnf # 根CA专用配置文件
├── intermediate-ca/ # 中间CA目录(可选)
│ ├── certs/
│ ├── crl/
│ ├── newcerts/
│ ├── private/
│ ├── index.txt
│ ├── serial
│ └── openssl.cnf
└── certs/ # 最终颁发的各类证书(按用途存放)
├── server/
├── client/
└── ...
创建目录:
bash
mkdir -p ~/ca/{root-ca,intermediate-ca,certs/{server,client}}
cd ~/ca
3. 搭建根 CA(Root CA)
根 CA 是整个信任链的顶点,私钥必须严格保护。通常根 CA 仅用于签发中间 CA,不直接签发最终用户SSL证书,以减少私钥暴露风险。
3.1 准备根 CA 配置文件
创建 `root-ca/openssl.cnf`,内容如下(可根据需要调整):
ini
[ ca ]
default_ca = CA_default
[ CA_default ]
# 目录结构
dir = /home/username/ca/root-ca
certs = $dir/certs
crl_dir = $dir/crl
new_certs_dir = $dir/newcerts
database = $dir/index.txt
serial = $dir/serial
RANDFILE = $dir/private/.rand
# 私钥和证书
private_key = $dir/private/ca.key.pem
certificate = $dir/certs/ca.cert.pem
# 默认有效期
default_days = 3650
default_crl_days = 30
default_md = sha256
preserve = no
# 策略(根CA签发中间CA时使用)
policy = policy_loose
[ policy_loose ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
# 用于生成CSR的选项
default_bits = 4096
distinguished_name = req_distinguished_name
string_mask = utf8only
default_md = sha256
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = CN
stateOrProvinceName = State or Province Name
stateOrProvinceName_default = Beijing
localityName = Locality Name
localityName_default = Beijing
organizationName = Organization Name
organizationName_default = Example Inc
organizationalUnitName = Organizational Unit Name
organizationalUnitName_default = IT
commonName = Common Name
commonName_default = Example Root CA
commonName_max = 64
[ v3_ca ]
# 根CA扩展
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:TRUE, pathlen:1
keyUsage = critical, digitalSignature, keyCertSign, cRLSign
> 注意:`dir` 路径需替换为实际路径。建议使用绝对路径。
3.2 初始化数据库和序列号
bash
cd ~/ca/root-ca
touch index.txt
echo 01 > serial
3.3 生成根 CA 私钥和自签名证书
bash
# 生成私钥(2048位或4096位,推荐4096)
openssl genrsa -out private/ca.key.pem 4096
chmod 400 private/ca.key.pem # 严格限制权限
# 生成自签名证书(有效期10年)
openssl req -config openssl.cnf -key private/ca.key.pem \
-new -x509 -days 3650 -sha256 -extensions v3_ca \
-out certs/ca.cert.pem
命令执行后会提示输入证书主题信息,按 `openssl.cnf` 中的默认值或手动填写。
3.4 验证根 CA 证书
bash
openssl x509 -in certs/ca.cert.pem -text -noout
确认 `Basic Constraints` 包含 `CA:TRUE` 且 `Key Usage` 正确。
4. 搭建中间 CA(Intermediate CA)
使用中间 CA 签发最终用户证书,即使中间 CA 私钥泄露,也可通过根 CA 吊销其证书,无需重建整个信任链。
4.1 准备中间 CA 配置文件
复制根 CA 的 `openssl.cnf` 到 `intermediate-ca/`,并修改以下部分:
ini
[ CA_default ]
dir = /home/username/ca/intermediate-ca
private_key = $dir/private/intermediate.key.pem
certificate = $dir/certs/intermediate.cert.pem
default_days = 730 # 中间CA签发的证书默认2年
default_crl_days = 30
policy = policy_loose
[ v3_intermediate_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:TRUE, pathlen:0
keyUsage = critical, digitalSignature, keyCertSign, cRLSign
> 注意:中间 CA 的 `pathlen` 设为 0,表示不能再签发下级 CA。
4.2 初始化中间 CA 目录
bash
cd ~/ca/intermediate-ca
touch index.txt
echo 01 > serial
4.3 生成中间 CA 私钥和 CSR
bash
# 生成私钥
openssl genrsa -out private/intermediate.key.pem 4096
chmod 400 private/intermediate.key.pem
# 生成 CSR(证书签名请求)
openssl req -config openssl.cnf -new -sha256 \
-key private/intermediate.key.pem \
-out intermediate.csr
填写主题信息时,`Common Name` 应为例如 `Example Intermediate CA`。
4.4 使用根 CA 签发中间 CA 证书
bash
cd ~/ca/root-ca
openssl ca -config openssl.cnf -extensions v3_intermediate_ca \
-days 3650 -notext -md sha256 \
-in ../intermediate-ca/intermediate.csr \
-out ../intermediate-ca/certs/intermediate.cert.pem
输入根 CA 私钥密码(如果设置了)。签发后,可查看证书:
bash
openssl x509 -in ../intermediate-ca/certs/intermediate.cert.pem -text -noout
4.5 创建证书链文件
将根 CA 和中间 CA 的证书合并为一个文件,供服务端配置使用:
bash
cat ../intermediate-ca/certs/intermediate.cert.pem \
../root-ca/certs/ca.cert.pem > ../intermediate-ca/certs/ca-chain.cert.pem
5. 签发服务器证书
服务器证书用于保护 Web 服务、API 等,通常需要包含主题备用名称(SAN)。
5.1 准备服务器证书配置文件(可选)
为简化命令,可以为服务器证书创建扩展配置文件 `server.cnf`:
ini
[ req ]
default_bits = 2048
distinguished_name = req_distinguished_name
req_extensions = req_ext
prompt = no
[ req_distinguished_name ]
countryName = CN
stateOrProvinceName = Beijing
localityName = Beijing
organizationName = Example Inc
organizationalUnitName = IT
commonName = www.example.com
[ req_ext ]
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = www.example.com
DNS.2 = example.com
DNS.3 = internal.example.com
IP.1 = 10.0.0.1
5.2 生成服务器私钥和 CSR
bash
cd ~/ca/certs/server
# 生成私钥
openssl genrsa -out server.key.pem 2048
chmod 400 server.key.pem
# 生成 CSR(使用配置文件)
openssl req -new -sha256 -key server.key.pem \
-config server.cnf -out server.csr
如果不使用配置文件,也可交互式输入,但 SAN 需要通过 `-addext` 添加(OpenSSL 1.1.1+)。
5.3 使用中间 CA 签发证书
bash
cd ~/ca/intermediate-ca
openssl ca -config openssl.cnf -extensions server_cert \
-days 730 -notext -md sha256 \
-in ../certs/server/server.csr \
-out ../certs/server/server.cert.pem
其中 `server_cert` 扩展应在中间 CA 的 `openssl.cnf` 中定义:
ini
[ server_cert ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = www.example.com
DNS.2 = example.com
IP.1 = 10.0.0.1
> 注意:实际签发时,可以在命令行使用 `-extfile` 指定扩展文件,避免修改主配置文件。
例如:
bash
openssl ca -config openssl.cnf -extfile server.cnf -extensions server_cert ...
5.4 验证证书
bash
openssl verify -CAfile ca-chain.cert.pem ../certs/server/server.cert.pem
若返回 `OK` 则表示证书链验证通过。
6. 签发客户端证书
客户端证书用于双向 TLS 认证(mTLS),验证客户端身份。
6.1 准备客户端证书配置文件 `client.cnf`
ini
[ req ]
default_bits = 2048
distinguished_name = req_distinguished_name
req_extensions = req_ext
prompt = no
[ req_distinguished_name ]
countryName = CN
stateOrProvinceName = Beijing
localityName = Beijing
organizationName = Example Inc
organizationalUnitName = IT
commonName = John Doe
[ req_ext ]
subjectAltName = email:john@example.com
6.2 生成客户端私钥和 CSR
bash
cd ~/ca/certs/client
openssl genrsa -out client.key.pem 2048
openssl req -new -sha256 -key client.key.pem \
-config client.cnf -out client.csr
6.3 签发客户端证书
中间 CA 的配置文件中需定义 `client_cert` 扩展:
ini
[ client_cert ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature
extendedKeyUsage = clientAuth
subjectAltName = email:copy
签发命令:
bash
cd ~/ca/intermediate-ca
openssl ca -config openssl.cnf -extensions client_cert \
-days 365 -notext -md sha256 \
-in ../certs/client/client.csr \
-out ../certs/client/client.cert.pem
6.4 转换为 PKCS#12 格式(用于浏览器)
bash
openssl pkcs12 -export -clcerts -in client.cert.pem \
-inkey client.key.pem -out client.p12 -password pass:changeit
7. 证书吊销列表(CRL)管理
当私钥泄露或员工离职时,需及时吊销证书。
7.1 吊销证书
bash
cd ~/ca/intermediate-ca
openssl ca -config openssl.cnf -revoke ../certs/server/server.cert.pem
吊销原因可通过 `-crl_reason` 指定,如 `keyCompromise`、`affiliationChanged` 等。
7.2 生成 CRL
bash
openssl ca -config openssl.cnf -gencrl -out crl/intermediate.crl.pem
查看 CRL:
bash
openssl crl -in crl/intermediate.crl.pem -text -noout
7.3 定期更新 CRL
可设置 cron 任务定期重新生成 CRL,并分发到需要检查吊销状态的系统。
8. 证书续签与轮换
证书到期前需续签。最简单的方法是重新生成 CSR(或重用原私钥),然后签发新证书。
对于服务器SSL证书,可提前生成新证书并替换,确保服务不中断。
9. 安全最佳实践
私钥保护:
根 CA 私钥应离线保存(如加密 USB 或 HSM),仅在签发中间 CA 时短暂使用。
中间 CA 私钥可在线但应严格限制权限(600),并设置强密码。
密钥长度:至少 2048 位 RSA,推荐 4096 位;ECC(如 prime256v1)也可考虑。
有效期:根 CA 建议 10 年,中间 CA 5 年,服务器/客户端证书 1-2 年。
命名规范:证书 CN 和 SAN 应清晰明确,避免模糊。
备份:定期备份 CA 目录,尤其是 `index.txt`、`serial`、私钥(加密)。
监控:记录所有证书签发和吊销操作,及时发现异常。
使用 HSM:高安全场景使用硬件安全模块存储私钥。
10. 常用命令速查
操作 命令
生成 RSA 私钥 `openssl genrsa -out key.pem 2048`
查看证书 `openssl x509 -in cert.pem -text -noout`
验证证书链 `openssl verify -CAfile chain.pem cert.pem`
生成 CSR(交互) `openssl req -new -key key.pem -out cert.csr`
生成 CSR(非交互) `openssl req -new -key key.pem -config req.cnf -out cert.csr`
签发证书(CA) `openssl ca -config openssl.cnf -in cert.csr -out cert.pem`
吊销证书 `openssl ca -config openssl.cnf -revoke cert.pem`
生成 CRL `openssl ca -config openssl.cnf -gencrl -out crl.pem`
转换 PKCS#12 `openssl pkcs12 -export -in cert.pem -inkey key.pem -out bundle.p12`
结语
通过 OpenSSL 搭建私有 CA 体系,企业可以完全自主管理内部证书生命周期。本文所述步骤已在实际生产环境中验证,读者可根据自身需求调整有效期、密钥强度等参数。建议配合自动化工具(如 cfssl、Easy-RSA 或 Ansible)实现更高效的证书管理,并定期审视安全策略。
如果遇到问题,可查阅 OpenSSL 官方文档或使用 `openssl` 命令的 `-help` 选项获取详细用法