Ruby 2.6.8-bullseye Docker镜像SSL证书验证失败如何解决?
Docker ruby:2.6.8-bullseye镜像SSL证书验证失败解决方案
问题根因
该镜像内置的ca-certificates包仍保留了已过期的Let's Encrypt DST Root CA X3根证书,同时镜像内置的旧版OpenSSL校验逻辑会优先匹配过期根证书,导致所有HTTPS请求触发证书验证失败报错。
可行解决方案
方案一:更新系统证书包并删除过期根证书(推荐,全局生效)
直接在Dockerfile中添加如下配置,构建新镜像即可永久解决问题:
# 临时切换apt为http源跳过SSL校验,更新证书包 RUN sed -i 's/https:/http:/g' /etc/apt/sources.list \ && apt-get update \ && apt-get install -y --only-upgrade ca-certificates \ # 彻底删除过期的DST Root CA X3根证书 && rm -f /usr/share/ca-certificates/mozilla/DST_Root_CA_X3.crt \ && echo "mozilla/DST_Root_CA_X3.crt" > /etc/ca-certificates.conf.d/remove-expired-root.conf \ && update-ca-certificates --fresh \ # 恢复apt为https源 && sed -i 's/http:/https:/g' /etc/apt/sources.list
方案二:为RestClient单独配置证书路径
如果不想修改系统级配置,可以在Rails项目中单独配置RestClient的证书路径:
- 你之前本地下载的
cacert.pem放在项目根目录,随代码一起打包进镜像 - 在
config/initializers目录下新建rest_client_ssl_config.rb,写入如下内容:
# 指定证书文件路径 RestClient::SSLCERTIFICATE_FILE = Rails.root.join('cacert.pem').to_s
方案三:容器内临时操作的临时修复
如果需要在运行中的容器内执行下载等HTTPS操作,可以临时跳过证书校验:
- wget命令添加参数:
wget --no-check-certificate https://xxx.xxx/xxx - curl命令添加参数:
curl -k https://xxx.xxx/xxx
常见疑问说明
- 执行
update-ca-certificates出现的ca-certificates.crt does not contain exactly one certificate or CRL: skipping警告属于正常现象,该警告是因为你导入的pem文件是多证书集合,不符合单证书校验规则,不影响证书的正常使用。 curl -Lks 'https://git.io/rg-ssl' | ruby检测全绿只代表Ruby读取证书的路径配置正确,不会校验证书本身是否有效,因此无法检测到根证书过期问题。
内容的提问来源于stack exchange,提问作者Don Giulio
相关产品推荐
相关产品推荐

