4、OpenSSL工具箱:常用命令速查(s_client, verify, x509)
说实话,排查证书信任链故障,OpenSSL 就是我的瑞士军刀。这三个命令——s_client、verify、x509——我几乎每天都会用到。它们各有侧重,配合起来能解决 90% 的证书问题。
下面这张图是我自己总结的,三个命令分别管什么,以及它们之间的关系。
4.1 s_client:远程连接与证书抓取
s_client 是我排查远程服务端证书问题的首选工具。它模拟了一个 SSL/TLS 客户端,能直接和服务端握手,并把证书链原样拉下来。
最基本的用法是这样的:
openssl s_client -connect example.com:443 -showcerts
加上 -showcerts 参数后,它会输出完整的证书链。我个人习惯把输出重定向到文件里,方便后续分析:
openssl s_client -connect example.com:443 -showcerts > cert_chain.pem
s_client 连上去一看,服务端根本没配中间证书。
有时候你只想看证书链,不想看握手细节。可以加 -servername 参数(用于 SNI 场景),再配合 sed 提取证书部分:
openssl s_client -connect example.com:443 -servername example.com -showcerts 2>/dev/null | sed -n '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p'
-servername,它可能返回默认证书,而不是你想要的域名证书。我曾经踩过这个坑,排查了半天才发现是 SNI 没传对。
4.2 verify:本地信任链校验
verify 命令用来做本地校验。你把证书链文件和根证书准备好,它就能告诉你这条链是否可信。
基本语法:
openssl verify -CAfile <根证书> -untrusted <中间证书> <服务器证书>
举个例子,假设你有三个文件:
root.pem—— 根证书intermediate.pem—— 中间证书server.pem—— 服务器证书
校验命令如下:
openssl verify -CAfile root.pem -untrusted intermediate.pem server.pem
如果一切正常,你会看到:
server.pem: OK
如果出错了,它会告诉你具体原因。比如:
unable to get local issuer certificate—— 找不到颁发者证书certificate has expired—— 证书过期了self-signed certificate in chain—— 链里出现了自签名证书
verify 只做本地校验,它不联网。所以你得确保本地有完整的根证书和中间证书。我经常把根证书和中间证书拼成一个文件,用 -CAfile 一次性加载。
还有一个参数 -CApath,可以指定一个目录,OpenSSL 会去那里找根证书。Linux 系统上通常是 /etc/ssl/certs:
openssl verify -CApath /etc/ssl/certs -untrusted intermediate.pem server.pem
verify 显示 OK,但浏览器就是报错。后来发现是中间证书的顺序不对。OpenSSL 的 verify 对证书顺序比较宽容,但有些服务端和客户端很严格。所以,verify 通过不代表线上一定没问题。
4.3 x509:证书内容解析
x509 命令用来查看证书的详细信息。它就像一把手术刀,能把证书的每个字段都剖开给你看。
最常用的参数是 -text,它会输出证书的全部内容:
openssl x509 -in server.pem -text -noout
-noout 表示不输出证书的 base64 编码,只看解析后的文本。输出内容很长,我一般重点关注这几个字段:
| 字段 | 说明 | 常见问题 |
|---|---|---|
| Subject | 证书持有者信息 | CN 是否匹配域名? |
| Issuer | 颁发者信息 | 是否与上一级证书的 Subject 一致? |
| Not Before / Not After | 有效期 | 是否过期?是否还没生效? |
| Subject Public Key Info | 公钥算法和长度 | 是否使用了弱算法(如 RSA 1024)? |
| X509v3 extensions | 扩展字段 | 是否有 Basic Constraints、Key Usage? |
只看指纹(fingerprint)也很常用,用来快速比对证书是否一致:
openssl x509 -in server.pem -fingerprint -sha256 -noout
输出类似:
SHA256 Fingerprint=AB:CD:EF:...:12:34
Issuer 和 Subject。如果 Issuer 和 Subject 一样,那就是自签名证书。如果不一样,再看有效期。很多故障其实都是证书过期引起的,看一眼 Not After 就能排除掉一半问题。
还有一个实用场景:提取公钥或私钥信息。比如查看证书对应的公钥长度:
openssl x509 -in server.pem -pubkey -noout | openssl pkey -pubin -text -noout
x509 只能处理 PEM 格式的证书。如果你拿到的是 DER 格式(二进制),需要先转换:openssl x509 -in cert.der -inform DER -out cert.pem -outform PEM。我遇到过有人直接把 DER 文件扔给 x509,结果报错说“no start line”,其实就是格式不对。
4.4 三个命令的配合使用
说实话,单独用哪个命令都只能看到一面。我通常的排查流程是这样的:
- 抓取: 用
s_client从远程服务端拉下证书链。 - 解析: 用
x509逐张查看证书内容,确认 Subject、Issuer、有效期、扩展字段。 - 校验: 用
verify做本地信任链校验,确认根证书和中间证书是否完整。
举个例子,假设你发现浏览器访问 https://example.com 报错,但不知道原因。你可以这样操作:
# 第一步:抓取证书链
openssl s_client -connect example.com:443 -showcerts 2>/dev/null | sed -n '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' > chain.pem
# 第二步:查看服务器证书(第一张)
openssl x509 -in chain.pem -text -noout | head -30
# 第三步:查看中间证书(第二张)
# 需要手动拆分 chain.pem 文件,或者用 awk 按 -----BEGIN 分割
# 然后对每张证书分别执行 x509 命令
# 第四步:本地校验(假设你有根证书 root.pem)
openssl verify -CAfile root.pem -untrusted intermediate.pem server.pem
s_client 负责“拿”,x509 负责“看”,verify 负责“验”。三个命令配合使用,基本能覆盖证书信任链故障排查的各个环节。我个人习惯把常用参数记在笔记里,遇到问题直接复制粘贴,省得每次都要查 man 手册。