如何使用 openssl 命令/选项说明检查证书的过期日期

您好,我是来自 Beyond Co., Ltd. 系统解决方案部门的 Naka。
您正在浏览的 Beyond Blog 使用的是 HTTPS 协议。HTTPS 在过去十年中已得到广泛应用,HTTP 网站的数量已显著减少。
目前,HTTPS所需的“SSL证书”通常每年更新一次,因此需要定期进行续期工作。许多人届时会通过浏览器查看SSL证书的有效期。
然而,自然有些人希望使用命令行进行检查,因为“浏览器不可靠,所以我想用命令行检查”或者“我无法使用浏览器检查,因为我还在开发阶段,还没有对外开放任何端口”。但是,在查找那些只偶尔使用的命令行时,就会出现一些问题。
“人们使用命令和选项的方式略有不同?它们之间有什么区别?”“
即使我输入‘man’,也有很多我看不懂的选项。”
对于感兴趣的朋友,我们想解释一下在检查 SSL 证书时,openssl 命令常用选项的含义和用法。
执行环境
・操作系统:AlmaLinux8(WSL2 环境)
・Shell:bash
・OpenSSL:OpenSSL 1.1.1k FIPS 25 Mar 2021
使用 openssl 命令检查“本地”或“远程”连接
openssl 命令由 OpenSSL 项目开发和发布,大多数主流 Linux 发行版默认都包含此命令。该命令功能强大,但本文将用它来检查 SSL 证书的到期日期。
此外,使用此命令进行检查时,有两种方法:“在本地检查 SSL 证书”和“从外部远程检查 SSL 证书”。
首先,让我介绍一下当地情况。
当地环境
以下是我在本地环境中进行检查时经常使用的命令。
openssl 命令用于读取本地存储的证书,并显示通用名称、有效期开始日期和到期日期。
$ openssl x509 -noout -subject -dates -in /etc/pki/tls/certs/example.crt
*输出示例 subject=CN = example.com *通用名称(≒ 域名) notBefore=2022年3月31日 04:42:17 GMT *有效起始日期 notAfter=2023年5月2日 04:42:16 GMT *到期日期
x509
处理 SSL 证书时,请使用“openssl”命令的“x509”子命令。
* “X.509”是公钥证书的标准格式名称,所以如果将它与该格式联系起来,可能更容易记住。
-在
在本地环境中运行时,需要指定要加载的证书的名称,因此请使用此选项。
-主题
此选项输出已加载证书的主题字段(其中写入了通用名称)。
日期
此选项输出导入证书的有效期起始日期和到期日期。
-noout
此选项“不输出除其他选项指定信息之外的任何信息”。如果此选项不可用,则还会显示以下命令加载的未解密证书。
-----证书开始----- MIIGMjCCBRqgAwIBAgIMMGPvI3CXFUjGngZcMA0GCSqGSIb3DQEBCwUAMEwxCzAJ BgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMSIwIAYDVQQDExlB ~以下数十行内容已省略~ -----证书结束-----
另外,还有一个 -nocert 选项,它只会隐藏证书的内容。
远程环境
远程检查时,我常用的命令如下。我使用 openssl s_client 命令访问目标主机,从那里读取证书,并显示通用名称以及有效期起始日期和到期日期。
$openssl s_client -connect beyondjapan.com:443 < /dev/null 2> /dev/null | openssl x509 -noout -subject -dates
※实际输出 subject=CN = beyondjapan.com notBefore=2022年3月31日 04:42:17 GMT notAfter=2023年5月2日 04:42:16 GMT
s_client
使用提供 SSL/TLS 通信所需客户端功能的子命令。
-连接主机:端口
就像在本地使用 `-in` 参数指定文件一样,此选项也适用于远程连接(指定要连接的主机和端口)。
*在本例中,使用了 443(HTTPS)端口,但它也可用于指定其他端口,例如 SMTP,以检查 SSL/TLS 连接。
< /dev/null
“openssl s_client”命令在连接到指定目标后会等待输入,因此我们向标准输入写入空值(/dev/null)来结束输入等待。如果不这样做,用Ctrl+C终止命令会很麻烦,所以我们使用了这种方法。
*这不是一个选项,而是关于 shell(在本环境中为 bash)标准输入的规范。
2> /dev/null
这会将 Linux 中的标准错误输出 (2) 重定向到空设备 (/dev/null) 并将其丢弃,使其不会显示在 shell 中。如果在上一步中使用 `< /dev/null`,则会显示不必要的错误消息,因此此措施旨在消除它。
*这不是一个选项,而是关于 shell(在本环境中为 bash)标准输出的规范。
| openssl x509 -noout -subject -dates
使用“|”(管道符)将通过通信接收到的 SSL 证书的内容传递给读取该证书的命令。管道符后的命令与使用本地模式时的命令几乎相同,但由于证书是通过管道接收的,因此无需使用 -in 选项来指定要读取的证书。
*如果未指定 -in 选项,则此命令 (x509) 的指定是为了处理传递给标准输入的内容。
其他人使用的命令和选项
命令
echo | openssl s_client -connect ~
在远程环境中进行检查时,我使用 `< /dev/null` 来结束输入等待,但这似乎是因为 shell 中使用 `echo` 命令输出到标准输出的优先级更高,从而强制系统结束输入等待状态。其目的与 `< /dev/null` 相同。
~ | openssl x509 -text | grep "Not"
`-text` 选项会解码证书的全部内容并将其输出为文本。这包括所有通过其他选项单独指定和显示的内容,因此在需要检查全部内容时非常有用。然后,输出会通过管道传递给 `grep` 命令,以输出包含“Not”的行。
$ openssl s_client -connect beyondjapan.com:443 < /dev/null 2> /dev/null | openssl x509 -text | grep "Not" Not Before: Mar 31 04:42:17 2022 GMT Not After : May 2 04:42:16 2023 GMT
这将输出有效起始日期和到期日期对应的行。虽然命令很长,但很简单,对于了解基础知识的人来说应该很容易理解。
然而,我觉得如果明明有专门的选项却依赖 grep,那就意味着你最终不会去深入研究这些选项,你对 openssl 命令的理解也会停滞不前,所以我倾向于使用第一个给出的命令。
此外,如果您尝试输出域名(通用名称),由于使用了正则表达式选项,命令的可读性会变差,这是一个问题。
选项
-结束日期
此选项仅显示已加载证书的到期日期。还有一个 `-startdate` 选项,用于显示有效起始日期,但 `-dates` 选项会同时应用这两个选项,因此如果您没有任何特殊偏好,我认为使用 `-dates` 即可。
-文本
如上所述,此选项以文本格式显示证书。输出包含所有配置信息,例如公钥、签名算法、颁发者、主题名称、到期日期等。
没有 -noout 的模式
在这种情况下,命令请求的未解密证书将原样显示,后面会显示到期日期和选项中指定的其他信息。说实话,您不会查看未解密证书的内容,所以保留显示状态更便于阅读。
命令输出中将出现“CERTIFICATE”字样,因此可以清楚地看到证书正在被验证,这可能是一个优势。
< /dev/null 2> 不带 /dev/null 的模式
默认命令会以 Ctrl + C 结束,我认为这样做的目的是为了方便手动输入,并保证命令一目了然。这可能只是个人偏好问题,但我喜欢保留这种模式,因为有时我会不小心输入下一个命令而忘记结束当前命令,这可能会导致输出和日志混乱。
最后
在撰写本文时,我再次意识到 openssl 命令非常容易让人困惑,因为它有很多功能和大量的选项。
这只是其功能的一小部分,加密和认证方法的底层技术非常复杂且逻辑严密。我希望阅读本文能够帮助您消除对 openssl 命令的一些疑虑和抵触情绪!
感谢您阅读至此。
下一篇文章
下面我们解释如何检查“完整性和验证结果”,这些结果通常与“到期日期”一起检查。
如何使用 openssl 命令/选项解释检查证书完整性和验证结果
参考资料
OpenSSL 官方手册中关于 openssl-x509 的页面:
https://www.openssl.org/docs/manmaster/man1/openssl-x509.html
OpenSSL (ArchWiki)
https://wiki.archlinux.jp/index.php/OpenSSL
6