macOS Big Sur下Ruby调用API因TLSv1.0握手出现SSL连接错误如何解决
排查与解决思路
1. 确认Ruby绑定的SSL库及默认TLS配置
系统层面的openssl、curl正常不代表Ruby调用的是同一套依赖,先打开irb执行以下代码确认:
require 'openssl' # 查看Ruby用的OpenSSL版本,需和你系统的1.1.1l一致才为正常 puts OpenSSL::OPENSSL_VERSION # 查看默认TLS参数,确认min_version是否被限制到了TLSv1.0 p OpenSSL::SSL::SSLContext::DEFAULT_PARAMS
如果输出的OpenSSL版本不是你brew安装的1.1.1l,说明之前编译Ruby时没有关联到正确的openssl路径。
2. 强制指定TLS版本验证问题
从日志可以判断你使用了Ethon作为HTTP底层库,可先加全局配置强制指定TLSv1.2验证是否能解决问题:
# 放在项目初始化位置即可,如Rails项目可在config/initializers下新建ethon.rb写入 Ethon::Easy.default_options[:sslversion] = :tlsv1_2
如果是Net::HTTP的使用场景,请求时添加对应配置即可:
http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true http.ssl_version = :TLSv1_2
如果强制指定版本后请求正常,即可确认是默认TLS版本配置异常导致的问题。
3. 重新编译Ruby关联正确的SSL路径
之前重新编译RVM时没有显式指定openssl路径,会导致Ruby默认调用系统自带的旧版SSL,执行以下命令重新编译即可:
# 先确认brew安装的openssl路径 brew --prefix openssl@1.1 # 替换<你的Ruby版本>为实际使用的版本号,比如2.7.4 rvm reinstall <你的Ruby版本> --with-openssl-dir=$(brew --prefix openssl@1.1)
编译完成后再重复第一步的检查,确认OpenSSL版本匹配。
4. 排查项目中的硬编码低版本TLS配置
重点检查以下位置是否有写死TLS版本为v1.0的配置:
- 第三方API客户端的初始化参数
- HTTP库的全局配置(Net::HTTP、Typhoeus、Faraday等)
- 项目内涉及SSL配置的初始化脚本
5. 最小场景测试验证
编写独立Ruby脚本发起请求,排除项目配置的干扰:
require 'typhoeus' # 先强制指定TLSv1.2测试 response = Typhoeus.get('https://bolmaster2.com', sslversion: :tlsv1_2) puts "指定TLSv1.2响应状态:#{response.code}" # 不指定版本测试 response = Typhoeus.get('https://bolmaster2.com') puts "默认配置响应状态:#{response.code}"
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

