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 证书体系结构图

下面这张图展示了我们刚才搭建的三层证书体系。你可以把它当作模板,以后所有证书管理都按这个结构来。

自签名证书体系结构图 自签名证书体系结构 CA 根证书 自签名 · 有效期10年 服务端证书 CN=www.myserver.com 有效期1年 · 由CA签名 客户端证书 CN=client-001 有效期1年 · 由CA签名 HTTPS / TLS 服务端 Nginx / Apache / Tomcat mTLS 客户端认证 微服务 / VPN / 双向认证 说明:CA根证书离线保存,服务端和客户端证书由CA签名,有效期通常为1年 生产环境建议使用中间CA,根证书仅用于签发中间CA

4.6 验证证书是否生效

证书生成完了,怎么确认没问题?我一般用三步验证法:

  1. 查看证书详情:openssl x509 -in server.crt -text -noout | grep -E "Subject:|Issuer:|Not Before|Not After"
  2. 验证证书链:openssl verify -CAfile ca.crt server.crt,返回 OK 才算通过
  3. 测试 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。