4. OpenSSL 实战:安装、自签名证书、CSR 生成与证书查看

OpenSSL 这东西,可以说是证书管理领域的瑞士军刀。我做了这么多年运维,几乎每天都要跟它打交道。别看它命令行参数多,其实核心场景就那么几个:装好它、给自己签个证、帮别人生成请求、查查证书里写了啥。今天咱们就把这四个事儿捋清楚。

本章核心脉络:OpenSSL 安装 → 生成自签名证书 → 生成 CSR(证书签名请求)→ 查看证书信息。每一步都是后面章节的基础,别跳过。

OpenSSL 实战核心流程 ① 安装 OpenSSL yum / apt / 源码 ② 自签名证书 x509 -req -days 365 ③ 生成 CSR req -new -key ④ 查看 x509 -text 🔑 关键参数速查 • -newkey rsa:2048 :生成 2048 位 RSA 密钥对 • -days 365 :证书有效期 1 年(生产环境建议不超过 2 年) • -subj "/CN=xxx" :免交互指定主题信息 • -text :以人类可读格式输出证书全部字段

4.1 安装 OpenSSL:别以为系统自带就完事了

大部分 Linux 发行版都预装了 OpenSSL,但版本可能很老。我记得有一次排查一个 TLS 握手失败的问题,折腾了两天,最后发现是 OpenSSL 版本太旧,不支持 TLS 1.2。嗯,从那以后我养成了一个习惯:先查版本。

# 查看当前版本
openssl version

# 输出示例:OpenSSL 1.1.1k  25 Mar 2021

如果版本低于 1.1.1,我建议你升级。为什么?1.1.1 是长期支持版,安全更新会持续到 2023 年之后。3.0 系列虽然新,但有些老项目兼容性有问题,生产环境我一般选 1.1.1 系列。

各系统安装方式:

操作系统 安装命令 备注
CentOS / RHEL 7 yum install openssl openssl-devel 默认 1.0.2,建议加 EPEL 升到 1.1.1
CentOS / RHEL 8+ dnf install openssl openssl-devel 默认 1.1.1,够用
Ubuntu / Debian apt install openssl libssl-dev 默认 1.1.1 或 3.0
macOS brew install openssl 系统自带版本较老,建议用 Homebrew
源码编译 ./config && make && make install 适合定制化需求,但维护成本高

我的习惯:在 Docker 容器里我直接用官方镜像 alpine:latest 然后 apk add openssl,干净利落。但在物理机或 VM 上,我倾向于用包管理器安装,方便后续用 yum update 统一打补丁。

4.2 生成自签名证书:5 分钟搞定内部测试

自签名证书,说白了就是自己给自己当 CA。开发环境、内网测试、临时 HTTPS 服务,都用得上。但注意,自签名证书浏览器会报不安全,生产环境别这么干。

一步到位法(推荐):

openssl req -x509 -newkey rsa:2048 -keyout server.key -out server.crt -days 365 -nodes

# 参数说明:
# -x509       :直接输出自签名证书,不走 CSR 流程
# -newkey rsa:2048 :同时生成 2048 位 RSA 私钥
# -keyout     :私钥输出文件
# -out        :证书输出文件
# -days 365   :有效期 1 年
# -nodes      :私钥不加密(no DES),省去输入密码的麻烦

执行后会交互式问你国家、组织、通用名称等信息。如果你不想交互,加个 -subj 参数:

openssl req -x509 -newkey rsa:2048 -keyout server.key -out server.crt \
  -days 365 -nodes \
  -subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/OU=Dev/CN=test.example.com"

我曾经踩过的坑:-nodes 这个参数名容易让人误解。它不是“没有节点”的意思,而是“no DES”,即私钥不加密。如果你不加这个参数,每次重启 Nginx 都要手动输入私钥密码,自动化部署时会疯掉。测试环境我建议加上,生产环境看你的安全策略。

分步法(适合教学):

  1. 先生成私钥:openssl genrsa -out server.key 2048
  2. 再生成证书:openssl req -x509 -key server.key -out server.crt -days 365

两种方式结果一样,一步法更省事。我个人习惯用一步法,除非我需要把私钥单独拿出来做其他用途。

4.3 生成 CSR:给 CA 递交的“申请书”

CSR(Certificate Signing Request)就是你去正规 CA 申请证书时提交的文件。它包含你的公钥和身份信息,CA 审核通过后签个名,就变成正式证书了。

生成 CSR 的标准流程:

# 第一步:生成私钥(如果还没有)
openssl genrsa -out mydomain.key 2048

# 第二步:生成 CSR
openssl req -new -key mydomain.key -out mydomain.csr

# 同样可以加 -subj 免交互
openssl req -new -key mydomain.key -out mydomain.csr \
  -subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/OU=IT/CN=www.example.com"

生成的 .csr 文件是文本格式的,你可以用 cat 查看,里面是 Base64 编码的内容。CA 会要求你把这个文件贴到他们的申请页面上。

关键字段说明:

  • CN(Common Name):证书绑定的域名。单域名证书就填 www.example.com,通配符证书填 *.example.com。这是最重要的字段,填错了证书就没法用。
  • O(Organization):公司名称,OV/EV 证书必须和营业执照一致。
  • OU(Organizational Unit):部门,比如 IT、DevOps。
  • C/ST/L:国家、省、市,按实际情况填就行。

查看 CSR 内容:

openssl req -text -noout -verify -in mydomain.csr

这个命令会解析 CSR 里的公钥、主题、扩展信息等。我每次提交 CSR 前都会跑一遍这个命令,确认信息无误再提交。曾经有一次我手抖把 CN 写成了 www.exmaple.com(拼写错误),CA 审核通过后才发现,重新申请浪费了 2 天时间。所以,提交前一定要检查!

4.4 查看证书信息:诊断问题的第一步

拿到一个证书文件,不管是 .crt、.pem 还是 .cer,第一件事就是看看里面写了啥。OpenSSL 提供了非常强大的查看功能。

查看 PEM 格式证书:

openssl x509 -in server.crt -text -noout

输出内容很长,包含版本、序列号、签名算法、颁发者、有效期、主题、公钥信息、扩展项等。我重点看这几个:

字段 含义 常见问题
Subject 证书持有者信息 CN 域名与实际访问域名不匹配
Issuer 颁发者信息 自签名证书 Issuer = Subject
Not Before / Not After 有效期起止时间 证书过期是最常见的 HTTPS 报错原因
Subject Public Key Info 公钥算法和长度 1024 位 RSA 已不安全,建议 2048+
X509v3 Subject Alternative Name SAN 扩展域名列表 缺少 SAN 会导致 Chrome 报错

快速检查证书过期:

openssl x509 -in server.crt -noout -dates
# 输出示例:
# notBefore=Jan  1 00:00:00 2024 GMT
# notAfter=Dec 31 23:59:59 2024 GMT

我写了个监控脚本,每天跑一次这个命令,提前 30 天发告警。证书过期导致的线上事故,我见过太多次了。

查看 DER 格式证书(Windows 常用):

openssl x509 -in certificate.der -inform DER -text -noout

查看证书指纹(用于校验证书是否被篡改):

openssl x509 -in server.crt -noout -fingerprint -sha256
# 输出:SHA256 Fingerprint=AB:CD:EF:...

4.5 实战场景:一条命令排查证书问题

最后分享一个我常用的组合拳。当用户反馈“网站打不开,证书错误”时,我会在服务器上跑这条命令:

echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | \
  openssl x509 -text -noout | grep -E "(Subject:|Issuer:|Not Before|Not After|DNS:)"

这条命令做了三件事:

  1. 用 s_client 模拟 TLS 握手,拿到服务器返回的证书
  2. 用 x509 -text 解析证书内容
  3. 用 grep 过滤出关键字段

输出结果一目了然:证书是谁发的、给谁用的、什么时候过期、SAN 里有没有正确的域名。80% 的证书问题,靠这一条命令就能定位。

注意:-servername 参数用于 SNI(Server Name Indication),如果你的服务器托管了多个 HTTPS 站点,不加这个参数可能拿到默认证书,导致诊断结果不准。我刚开始用 s_client 时就犯过这个错,查了半天发现查的是隔壁站点的证书。