Ubuntu 18.04上ROR应用SSL证书验证失败问题求助
问题描述
我们公司生产环境的ROR应用部署在多台EC2实例上,部分实例运行Ubuntu 14.04.5 LTS,部分运行Ubuntu 18.04.2 LTS。运行Ubuntu 18.04.2 LTS的服务器偶尔会在连接S3(实际是任意HTTPS URL)时出现以下错误:
Error Occurred: SSL_connect returned=1 errno=0 state=error: certificate verify failed (unable to get local issuer certificate)
无需修改代码,仅重启应用即可恢复正常。进一步排查发现:
- 出现错误的服务器使用OpenSSL 1.1.1
- 无错误的服务器使用OpenSSL 1.0.1f
我们在GitHub上发现有其他用户遇到相同问题,重启后解决。现求助两个问题:
- 该问题如何解决?是否有相关经验?
- 重启后未修改代码为何能恢复正常?
问题解答
1. 问题解决方法及相关经验
结合OpenSSL 1.1.1特性和这类偶发证书验证问题的常见诱因,推荐以下排查和解决方向:
- 更新系统根证书包:Ubuntu 18.04的ca-certificates包可能存在旧版根证书或缓存异常,执行
sudo apt update && sudo apt install --reinstall ca-certificates重新安装并更新根证书,确保系统信任的CA列表完整且最新。 - 指定Ruby使用系统根证书:ROR的Ruby环境可能未正确加载系统根证书,可在应用启动脚本中添加
export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt,或在应用初始化文件中设置ENV['SSL_CERT_FILE'] = '/etc/ssl/certs/ca-certificates.crt',强制Ruby使用系统默认的根证书集合。 - 排查OpenSSL会话缓存问题:OpenSSL 1.1.1的会话缓存机制与1.0.1f存在差异,偶发的缓存损坏可能导致验证失败。可在Ruby的HTTPS请求配置中禁用会话复用,比如在Net::HTTP代码里添加
http.ssl_session = nil,避免复用异常的会话缓存。 - 确保系统时间同步:证书验证对时间敏感,若服务器时间偏差超出证书有效期范围,会触发验证失败。为所有EC2实例配置NTP服务,同步到可靠时间源(如AWS的NTP服务器)。
2. 重启后恢复正常的原因
重启应用会清除几类导致问题的临时异常状态:
- Ruby进程内的SSL缓存:Ruby运行时会缓存SSL会话、证书链等数据,若这些缓存在运行中损坏或过期,重启进程会清空缓存,重新从系统加载完整的证书与会话配置。
- 临时系统资源异常:偶尔的文件句柄、内存不足等资源问题,可能导致证书文件读取不完整,重启应用会释放占用的资源,重新读取证书时恢复正常。
- OpenSSL内部状态异常:OpenSSL 1.1.1长时间运行后可能出现内部状态冲突(如会话缓存异常),重启应用会重新初始化OpenSSL上下文,重置这些异常状态。
内容的提问来源于stack exchange,提问作者Red Boy
相关产品推荐
相关产品推荐

