惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
The Blog of Author Tim Ferriss
WordPress大学
WordPress大学
博客园 - Franky
The Cloudflare Blog
T
Tailwind CSS Blog
宝玉的分享
宝玉的分享
小众软件
小众软件
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Apple Machine Learning Research
Apple Machine Learning Research
月光博客
月光博客
B
Blog
Y
Y Combinator Blog
V
V2EX
有赞技术团队
有赞技术团队
M
MIT News - Artificial intelligence
博客园 - 司徒正美
IT之家
IT之家
G
Google Developers Blog
C
Check Point Blog
Engineering at Meta
Engineering at Meta
Microsoft Security Blog
Microsoft Security Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
GbyAI
GbyAI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻

OhYee 博客

小鹏辅助驾驶测评|OhYee 博客 小鹏非支持手机开启自动解锁|OhYee 博客 使用函数计算实现 301 重定向|OhYee 博客 针对 HTML 内容使用 Ant Design 图片弹框|OhYee 博客 博客进程泄露及僵尸进程解决|OhYee 博客 蓝易云服务器体验|OhYee 博客 SSH 调起本地 VSCode|OhYee 博客 【2022 秋招内推】阿里云后端研发工程师|OhYee 博客 使用函数计算获取 IP 地址信息|OhYee 博客 正确获取客户端 IP/HTTP Header 也可能重复|OhYee 博客 评测 Oculus Quest2 及 BigScreen|OhYee 博客 NextJS 热重载保留状态|OhYee 博客 如何优雅地贴 gist 代码|OhYee 博客 Linux 精细化文件权限|OhYee 博客 VSCode 容器开发环境|OhYee 博客 Clash 的不兼容更新排查|OhYee 博客 Zeek 导出 PCAP|OhYee 博客 记一次 ssh 配置问题|OhYee 博客 Git Commit 规范化工具|OhYee 博客 谈谈《星之卡比-探索发现》|OhYee 博客 VSCode 快捷键绑定 Shell 命令|OhYee 博客 ASN.1 语法及 X.509 证书格式解析解析|OhYee 博客 腾讯企业邮箱忽略 MX 记录发信|OhYee 博客 Chrome/Edge 标签组插件|OhYee 博客 【应届内推】阿里云后端研发工程师|OhYee 博客 损坏的 Typecho 备份处理为 JSON|OhYee 博客 VS Code VIM 插件高效使用|OhYee 博客 SSH 正反向代理|OhYee 博客 OpenWRT 忽略内核依赖|OhYee 博客 V2Ray + TLS + WS(WSS) Docker 部署|OhYee 博客
Let's Encrypt 根证书过期引发的问题|OhYee 博客
2021-12-04 · via OhYee 博客

Let's Encrypt 根证书过期引发的问题

Let's Encrypt 曾经通知由于根证书问题导致可能会存在验证失败问题

2021年9月30日起,较旧的浏览器和设备对Let’s Encrypt证书的信任方式将发生一些小变化。如果您运营着一个普通网站,您将不会察觉到任何不同——绝大多数访问者仍会接受您的Let’s Encrypt证书。如果您提供API或必须支持IoT设备,则您可能需要对此变化加以留意。

虽然我只是一个普通网站,原则上应该不会受到影响,但是由于还运行着一个 git 仓库,所以不完全是一个普通网站。在 vultr 的服务器上,以及 Gitee 的仓库克隆,都遇到了提示证书验证失败的问题。而与此同时,电脑浏览器访问却丝毫不受影响。

到底证书是合法,还是不合法呢?

Let's Encrypt 根证书

Let’s Encrypt有一个称为ISRG Root X1的“根证书”。现代浏览器和设备信任您网站上安装的Let’s Encrypt证书,因为它们的根证书列表中包含了ISRG Root X1。同时为了确保我们颁发的证书能够在较旧的设备上依然受信任,Let’s Encrypt同时还具有一个较旧的根证书的“交叉签名”: DST Root CA X3。

当Let’s Encrypt项目启动的时候,这个较旧的根证书DST Root CA X3帮助我们起步,并使Let’s Encrypt的证书几乎立即受到所有设备的信任。较新的根证书(ISRG Root X1)现在也已广受信任——但是某些较旧的设备将永远不会信任它,因为它们没有获得软件更新(例如iPhone 4或HTC Dream)。单击此处以获取信任ISRG Root X1的平台。

DST Root CA X3证书将于2021年9月30日到期。这意味着在此之后那些不信任ISRG Root X1证书的旧设备在访问使用Let’s Encrypt证书的网站时将开始出现证书警告。不过有一个例外很重要:多亏了DST Root CA X3的特殊“交叉签名”机制,Let’s Encrypt的证书依然可以在不信任ISRG Root X1证书的较旧的Android设备上正常工作。交叉签名机制使得Let’s Encrypt的证书的有效期限可以超过根证书的到期时间,此例外仅适用于Android。

简单来说,Let's Encrypt 要证明自己的身份,也需要有一个广受信任的机构来为其证明 —— 大家电脑里都有的根证书 ISRG Root X1。但根证书本身也是有有效期的,这个证书的有效期到 2021 年 9 月 30 日。因此,当证书过期后,就无法证明证书的有效性了

Ubuntu 提示证书错误

既然如此,那理论上在所有地方都不应该有问题,但是如果在一些服务器上,仍然会提示证书不合法

curl: (60) server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none
More details here: http://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). If the default
bundle file isn't adequate, you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.

首先来看我们到底拿到的证书长什么样(省略了无关的内容)

$ openssl s_client -showcerts -host git.ohyee.cc -port 443

Certificate chain
 0 s:CN = *.ohyee.cc
   i:C = US, O = Let's Encrypt, CN = R3

 1 s:C = US, O = Let's Encrypt, CN = R3
   i:C = US, O = Internet Security Research Group, CN = ISRG Root X1

 2 s:C = US, O = Internet Security Research Group, CN = ISRG Root X1
   i:O = Digital Signature Trust Co., CN = DST Root CA X3

可以看到证书链是 DST Root CA X3 -> ISRG Root X1 -> Let's Encrypt -> *.ohyee.cc
由于过老的设备没有把 ISRG Root X1 加入到信任的根证书内,因此为了保证兼容性,Let's Encrypt 使用了由 DST Root CA X3 签发的 ISRG Root X1 证书,由于老版 Android 不会检查信任的根证书的有效期,因此签发出的超过 DST Root CA X3 有效期的 ISRG Root X1 证书有效。从而保证了在老版 Android 仍然可以正常访问 Let’s Encrypt 的证书。

Let's Encrypt 证书链Let's Encrypt 证书链

但由于 OpenSSL 1.0.x 存在 Bug,当检查有证书不合法时,就会停止验证,返回错误。而 OpenSSL 1.1.x 后,则会尝试将所有的证书都进行验证。而这里由于存在 DST Root CA X3、ISRG Root X1 两个证书,前者已经过期。因此在低版本 OpenSSL 时,会验证失败。

解决方案

原则上只要保证 OpenSSL 版本在 1.1.0 以上即可,但是实际上由于 OpenSSL 本身是一个比较底层的依赖,在部分系统可能会由于兼容性不支持直接更新到 OpenSSL 1.1.x

一个选择是直接去下载 OpenSSL 1.1.x 然后替换,但是这有概率导致系统出问题,因此另一个选择就是删除掉系统里的 DST Root CA X3,这样 OpenSSL 就会验证 ISRG Root X1 从而达到目的。

首先是修改证书列表 vim /etc/ca-certificates.conf,在 mozilla/DST_Root_CA_X3.crt 前添加 !,而后使用 update-ca-certificates -f 更新证书即可

(但是由于我们无法修改别人服务器的配置,因此仍然无法保证可访问性。如 Gitee 拉取代码,可能会提示证书错误)

参考资料