💎
Ruby: SSL_CTX_load_verify_file: system lib (OpenSSL::SSL::SSLError)
OpenSSL まわりでちょっとハマったのでメモ。
こんな Ruby のコードを動かすと環境によって warning になったりエラーになったりする。
require 'faraday'
ssl_opts = {ca_file: OpenSSL::X509::DEFAULT_CERT_FILE}
Faraday::Connection.new('https://tmtms.net', ssl: ssl_opts).get
puts 'OK'
環境1:
warning になるが成功する。
% ruby -w hoge.rb
/usr/local/lib/ruby/3.1.0/net/http.rb:1081: warning: can't set verify locations
OK
環境2:
エラーになる。
% ruby -w hoge.rb
/usr/lib/ruby/3.0.0/net/http.rb:1030:in `initialize': SSL_CTX_load_verify_file: system lib (Faraday::SSLError)
from /usr/lib/ruby/3.0.0/net/http.rb:1030:in `new'
from /usr/lib/ruby/3.0.0/net/http.rb:1030:in `connect'
from /usr/lib/ruby/3.0.0/net/http.rb:970:in `do_start'
from /usr/lib/ruby/3.0.0/net/http.rb:959:in `start'
from /var/lib/gems/3.0.0/gems/faraday-net_http-3.0.2/lib/faraday/adapter/net_http.rb:112:in `request_with_wrapped_block'
from /var/lib/gems/3.0.0/gems/faraday-net_http-3.0.2/lib/faraday/adapter/net_http.rb:102:in `perform_request'
from /var/lib/gems/3.0.0/gems/faraday-net_http-3.0.2/lib/faraday/adapter/net_http.rb:66:in `block in call'
from /var/lib/gems/3.0.0/gems/faraday-2.7.2/lib/faraday/adapter.rb:45:in `connection'
from /var/lib/gems/3.0.0/gems/faraday-net_http-3.0.2/lib/faraday/adapter/net_http.rb:65:in `call'
from /var/lib/gems/3.0.0/gems/faraday-2.7.2/lib/faraday/request/url_encoded.rb:25:in `call'
from /var/lib/gems/3.0.0/gems/faraday-2.7.2/lib/faraday/rack_builder.rb:153:in `build_response'
from /var/lib/gems/3.0.0/gems/faraday-2.7.2/lib/faraday/connection.rb:445:in `run_request'
from /var/lib/gems/3.0.0/gems/faraday-2.7.2/lib/faraday/connection.rb:200:in `get'
from hoge.rb:3:in `<main>'
/usr/lib/ruby/3.0.0/net/http.rb:1030:in `initialize': SSL_CTX_load_verify_file: system lib (OpenSSL::SSL::SSLError)
from /usr/lib/ruby/3.0.0/net/http.rb:1030:in `new'
from /usr/lib/ruby/3.0.0/net/http.rb:1030:in `connect'
from /usr/lib/ruby/3.0.0/net/http.rb:970:in `do_start'
from /usr/lib/ruby/3.0.0/net/http.rb:959:in `start'
from /var/lib/gems/3.0.0/gems/faraday-net_http-3.0.2/lib/faraday/adapter/net_http.rb:112:in `request_with_wrapped_block'
from /var/lib/gems/3.0.0/gems/faraday-net_http-3.0.2/lib/faraday/adapter/net_http.rb:102:in `perform_request'
from /var/lib/gems/3.0.0/gems/faraday-net_http-3.0.2/lib/faraday/adapter/net_http.rb:66:in `block in call'
from /var/lib/gems/3.0.0/gems/faraday-2.7.2/lib/faraday/adapter.rb:45:in `connection'
from /var/lib/gems/3.0.0/gems/faraday-net_http-3.0.2/lib/faraday/adapter/net_http.rb:65:in `call'
from /var/lib/gems/3.0.0/gems/faraday-2.7.2/lib/faraday/request/url_encoded.rb:25:in `call'
from /var/lib/gems/3.0.0/gems/faraday-2.7.2/lib/faraday/rack_builder.rb:153:in `build_response'
from /var/lib/gems/3.0.0/gems/faraday-2.7.2/lib/faraday/connection.rb:445:in `run_request'
from /var/lib/gems/3.0.0/gems/faraday-2.7.2/lib/faraday/connection.rb:200:in `get'
from hoge.rb:3:in `<main>'
Faraday 使わずに OpenSSL だけで再現させるとこんな感じ。
require 'openssl'
sock = Socket.tcp('tmtms.net', 443)
store = OpenSSL::X509::Store.new
store.set_default_paths
ctx = OpenSSL::SSL::SSLContext.new
ctx.set_params(ca_file: OpenSSL::X509::DEFAULT_CERT_FILE, cert_store: store)
tls = OpenSSL::SSL::SSLSocket.new(sock, ctx)
tls.hostname = 'tmtms.net'
tls.sync_close = true
tls.connect
puts 'OK'
環境1:
% ruby -w hoge.rb
hoge.rb:7: warning: can't set verify locations
OK
環境2:
% ruby -w hoge.rb
hoge.rb:7:in `initialize': SSL_CTX_load_verify_file: system lib (OpenSSL::SSL::SSLError)
from hoge.rb:7:in `new'
from hoge.rb:7:in `<main>'
エラーになるのは、Ruby の openssl ライブラリが 3.0 で、かつ OS の OpenSSL ライブラリ(libssl)が 3.x で、OpenSSL::X509::DEFAULT_CERT_FILE
のファイルが存在していない場合。たとえば、Ubuntu 22.04 とか。
Ubuntu では以前から OpenSSL::X509::DEFAULT_CERT_FILE
が存在ないファイル(/usr/lib/ssl/cert.pem
)になってるんだけど、Ubuntu 22.04 で libssl が 3.0 になって発生するようになった。
libssl の問題かと思ったんだけど、調べてみたら Ruby の openssl の方だった。
ca_file
が読めないときに OpenSSL 3.x (HAVE_SSL_CTX_LOAD_VERIFY_FILE
が真) だと SSLError 例外になるけど、OpenSSL 1.x だと warning になる。
ca_file
に存在しないファイルを指定するのが悪いんだけど、Ubuntu では OpenSSL::X509::DEFAULT_CERT_FILE
が存在してないファイルというところが罠。
デフォルトでいいなら ca_file
は指定しない方が良さそう。
Discussion