今天突然间,我的 Ubuntu 14 服务器向使用 Let's Encrypt 颁发的 SSL 证书的网站发送的所有 HTTPS 请求都开始失败。cURL 生成的错误是:
curl: (60) SSL certificate problem: certificate has expired
当我使用此命令检查网站证书时:
echo -n | openssl s_client -showcerts -connect website.com:443 -servername website.com
我看到所有证书链都是最新的。
那么,为什么我会收到过期错误?该如何修复?
答案1
原因是“DST Root CA X3”证书昨天已过期。
要修复此问题,只需在服务器上禁用证书。运行:
sudo dpkg-reconfigure ca-certificates
在第一个提示“信任来自证书颁发机构的新证书吗?”的屏幕上,选择“是”。在下一个屏幕上,按键盘上的向下箭头键,直到找到mozilla/DST_Root_CA_X3.crt
,按空格键取消选择它(应该[*]
变成[ ]
),然后按 Enter。
答案2
编辑文件 /etc/ca-certificates.conf
找到并注释掉!
以下行
!mozilla/DST_Root_CA_X3.crt
保存文件并使用命令更新证书
sudo update-ca-certificates
答案3
仅供参考,在类似 CentOS(基于 RPM)的系统上,使用:
yum reinstall ca-certificates
答案4
那么为什么我会收到过期错误?
Android 在设计时决定忽略根证书的过期问题(可以说,根证书的过期问题从一开始就没有多大意义)。
“lets encrypt” 是一个相对较新的 CA,为了支持现有系统,其根证书由 DST“交叉签名”*。DST 根证书现已过期,但由于上述 Android 行为,交叉签名对于支持运行旧版 Android 的客户端仍然有用。
当在具有现代根证书列表的系统上使用此类链时,应忽略交叉签名并使用 IRSG(让加密)根。不幸的是,openssl 1.0.x 无法正确处理这种情况。
可以通过删除旧的 DST 根证书来解决此问题。完成此操作后,链将正确构建到 IRSG 根。
* 我的理解是,从技术上讲,“交叉签名”由具有与 Lets Encrypt 的根证书相同的内容和密钥的“中间证书”组成。