4、OpenSSL入门:从零开始搭建你的证书体系
说实话,很多运维干了三五年,证书管理还是靠“百度+复制粘贴”。出了问题就抓瞎。我个人觉得,OpenSSL 是每个运维必须啃下的硬骨头。它不复杂,但细节多。今天我们就把它彻底讲透。
4.1 OpenSSL 是什么?为什么必须学它?
OpenSSL 是一个开源的加密工具包。说白了,它干三件事:
- 加密通信——比如 HTTPS 背后的 TLS 握手
- 证书管理——生成、签名、吊销证书
- 随机数/哈希——各种密码学基础操作
我在项目中遇到过好几次,开发说“证书过期了”,结果一查,连怎么生成自签名证书都不知道。嗯,这就是我们今天要解决的问题。
一句话总结:OpenSSL 是证书世界的“瑞士军刀”。你不需要精通密码学,但必须会用这把刀。
4.2 安装 OpenSSL
不同系统安装方式略有差异。我习惯用包管理器搞定,干净利落。
| 操作系统 | 安装命令 | 验证命令 |
|---|---|---|
| CentOS / RHEL | yum install openssl -y |
openssl version |
| Ubuntu / Debian | apt install openssl -y |
openssl version |
| macOS | brew install openssl |
openssl version |
| Windows | 下载安装包或 WSL | openssl version |
小技巧:安装完后,先跑 openssl version -a,看看编译参数。我曾经遇到一个坑——生产环境的 OpenSSL 没编译 EC 椭圆曲线支持,导致 ECC 证书生成失败。提前检查能省很多事。
4.3 OpenSSL 命令行基础
你不需要记住所有参数。但下面这几个命令,我建议你刻在脑子里。
4.3.1 查看证书内容
openssl x509 -in cert.pem -text -noout
这个命令我几乎每天用。它能让你看清证书的颁发者、有效期、SAN 域名等关键信息。
4.3.2 生成私钥
openssl genrsa -out server.key 2048
2048 位是目前的最低标准。别用 1024,不安全。也别用 4096,性能开销大,除非你有特殊合规要求。
4.3.3 生成证书签名请求(CSR)
openssl req -new -key server.key -out server.csr
执行后会让你填一堆信息。我建议你直接用 -subj 参数跳过交互:
openssl req -new -key server.key -out server.csr \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/CN=www.example.com"
注意:CN(Common Name)必须填域名或 IP。浏览器现在主要看 SAN(Subject Alternative Name),但 CN 仍然是传统校验字段。我建议两个都填。
4.4 生成自签名证书体系
这是今天的重头戏。我们会搭建一个完整的证书链:CA 证书 → 服务端证书 → 客户端证书。
为什么要分三层?你想想看,如果每个服务器都用同一个根证书签名,根证书泄露就全完了。分层之后,根证书可以离线保存,中间 CA 只签服务端证书,安全得多。
4.4.1 生成 CA 根证书
CA 是证书体系的信任锚点。它自己签自己,所以叫自签名。
# 1. 生成 CA 私钥
openssl genrsa -out ca.key 4096
# 2. 生成 CA 自签名证书(有效期10年)
openssl req -x509 -new -nodes -key ca.key \
-sha256 -days 3650 \
-out ca.crt \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyCA/CN=My Root CA"
我的习惯:CA 私钥一定要设置强密码保护。我曾经见过有人把 CA 私钥直接放代码仓库里……嗯,后果很严重。建议用 -aes256 参数加密:
openssl genrsa -aes256 -out ca.key 4096
4.4.2 生成服务端证书
服务端证书用于 HTTPS、TLS 等场景。它由 CA 签名,客户端信任 CA 就会信任它。
# 1. 生成服务端私钥
openssl genrsa -out server.key 2048
# 2. 生成 CSR
openssl req -new -key server.key -out server.csr \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/CN=www.myserver.com"
# 3. 用 CA 签名(有效期1年)
openssl x509 -req -in server.csr \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-out server.crt -days 365 -sha256
这里有个关键点:-CAcreateserial 会生成一个序列号文件。每次签名序列号递增,防止证书重复。我建议你把这个文件也备份好。
4.4.3 生成客户端证书
客户端证书用于双向认证(mTLS)。比如微服务之间的通信、VPN 登录等场景。
# 1. 生成客户端私钥
openssl genrsa -out client.key 2048
# 2. 生成 CSR
openssl req -new -key client.key -out client.csr \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/CN=client1"
# 3. 用 CA 签名
openssl x509 -req -in client.csr \
-CA ca.crt -CAkey ca.key -CAserial ca.srl \
-out client.crt -days 365 -sha256
避坑指南:我曾经在项目中遇到客户端证书和服务端证书用同一个 CN,结果 TLS 握手失败。原因是 OpenSSL 默认会校验 CN 是否匹配。建议客户端证书的 CN 用唯一标识,比如 client-001 或邮箱地址。
4.5 证书体系结构图
下面这张图展示了我们刚才搭建的三层证书体系。你可以把它当作模板,以后所有证书管理都按这个结构来。
4.6 验证证书是否生效
证书生成完了,怎么确认没问题?我一般用三步验证法:
- 查看证书详情:
openssl x509 -in server.crt -text -noout | grep -E "Subject:|Issuer:|Not Before|Not After" - 验证证书链:
openssl verify -CAfile ca.crt server.crt,返回OK才算通过 - 测试 TLS 握手:
openssl s_client -connect localhost:443 -CAfile ca.crt
我曾经踩过的坑:有一次 verify 返回 unable to get local issuer certificate,查了半天发现是 CA 证书路径写错了。记住,-CAfile 必须指向根证书,不是中间证书。
4.7 本章小结
今天我们干了三件事:安装了 OpenSSL、学会了基础命令、亲手搭建了一套完整的自签名证书体系。你手头现在应该有 6 个文件:ca.key、ca.crt、server.key、server.crt、client.key、client.crt。