错误证书验证失败(证书已过期)):在 Mac OSX 11.6.1 和 ruby 3.0.3 中

Error Certificate verify failed (certificate has expired)): in Mac OSX 11.6.1 and ruby 3.0.3

我在 rails 上有一个 ruby webapp 向第三方 SOAP API 发送请求。当我请求时:

endpoint = "https://www.booking-manager.com/cbm_web_service2/services/CBM?wsdl"
        client = Savon.client(wsdl: endpoint, 
                              #log_level: :info,
                              log_level: :debug,
                              log: true,
                              pretty_print_xml: true,
                              open_timeout: 300, 
                              read_timeout: 300)
      message = {'in0' => xxx, 
               'in1' => 'xxxx', 
               'in2' => 'xxx'}
response = client.call(:get_bases, message: message) 

我遇到下一个错误:

HTTPI::SSLError (SSL_connect returned=1 errno=0 state=error: certificate verify failed (certificate has expired)):

Web 应用程序 运行ning 位于:

Mac OSX Big Sur 11.6.1
ruby 3.0.3p157 (2021-11-24 revision 3fb7d2cadc) [x86_64-darwin20]

这个问题困扰我好几个星期了,我不知道还能做什么。根据很多post,我测试了

openssl s_client -showcerts -host valid-isrgrootx1.letsencrypt.org -port 443

并得到:

CONNECTED(00000005)
depth=1 O = Digital Signature Trust Co., CN = DST Root CA X3
verify error:num=10:certificate has expired
notAfter=Sep 30 14:01:15 2021 GMT
verify return:0
depth=1 O = Digital Signature Trust Co., CN = DST Root CA X3
verify error:num=10:certificate has expired
notAfter=Sep 30 14:01:15 2021 GMT
verify return:0
depth=3 O = Digital Signature Trust Co., CN = DST Root CA X3
verify error:num=10:certificate has expired
notAfter=Sep 30 14:01:15 2021 GMT
verify return:0
---
Certificate chain
 0 s:/CN=origin.letsencrypt.org
   i:/C=US/O=Let's Encrypt/CN=R3

所以,根据这个:https://community.letsencrypt.org/t/help-thread-for-dst-root-ca-x3-expiration-september-2021/149190/970

我手动更新了文件 /etc/ssl/cert.pem 以删除 DST Root CA X3 证书。在那之后,我认为我向前迈进了一步。当运行宁:

openssl s_client -showcerts -host valid-isrgrootx1.letsencrypt.org -port 443

现在,我没有收到错误,我认为看起来不错:

CONNECTED(00000005)
depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = R3
verify return:1
depth=0 CN = origin.letsencrypt.org
verify return:1
---
Certificate chain
 0 s:/CN=origin.letsencrypt.org
   i:/C=US/O=Let's Encrypt/CN=R3

然而,不幸的是,我的 ruby 应用程序中的错误仍然存​​在。据此,我了解到 ruby 是 运行ning 一个没有从该证书中获取信息的 openssl。我对此一点都不熟练,也不知道这是否有意义。

我刚刚阅读了其他 post 并检查了 openssl version

我得到了LibreSSL 2.8.3

which openssl
/usr/bin/openssl

在我的 /usr/local/opt 中,我看到三个 openssl 版本文件夹:

我更新了我的 .zshrc 文件,现在 openssl 版本通知

OpenSSL 3.0.1 14 Dec 2021 (Library: OpenSSL 3.0.1 14 Dec 2021)

和 ruby 似乎在使用:

ruby -ropenssl -e "puts OpenSSL::OPENSSL_VERSION"
OpenSSL 1.1.1l  24 Aug 2021

我知道 ruby OpenSSL 版本是 1.1.1,系统是 运行ning 3.0.1。我不知道如何将 ruby 更新为 运行 OpenSSL 3.0.1,尽管我不确定这是否是根本问题。我在这一点上迷路了。

更新 我想我正在缩小问题范围。我的猜测是 Ruby 使用的是 openSSL 版本,在本例中为 1.1.1,它指向 /Users/Rober/.rbenv/versions/3.0.3/openssl/ssl/certs 捆绑器而不是指向 /etc/ssl/cert.pem

irb
irb(main):001:0> require "openssl"
=> true
irb(main):002:0> puts OpenSSL::OPENSSL_VERSION
OpenSSL 1.1.1l  24 Aug 2021
=> nil
irb(main):003:0> puts "SSL_CERT_FILE: %s" % OpenSSL::X509::DEFAULT_CERT_FILE
irb(main):004:0> puts "SSL_CERT_DIR: %s" % OpenSSL::X509::DEFAULT_CERT_DIR
SSL_CERT_FILE: /Users/Rober/.rbenv/versions/3.0.3/openssl/ssl/cert.pem
SSL_CERT_DIR: /Users/Rober/.rbenv/versions/3.0.3/openssl/ssl/certs

这个文件 /Users/Rober/.rbenv/versions/3.0.3/openssl/ssl/cert.pem ,不幸的是当我检查内容的格式时:

-----BEGIN CERTIFICATE-----
certificate chain
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----

我的意思是,在这个文件 /etc/ssl/cert.pem 中,我可以阅读一些可读的 headers 帮助识别要删除的证书,但在这种情况下 headers 不存在,所以这是不可能的。

我认为我可能只需要将 ruby 配置为 运行 openssl 以指向此文件 /etc/ssl/cert.pem。根据妈妈 posts 的说法,我刚刚将 export SSL_CERT_FILE="/etc/ssl/cert.pem" 添加到我的 .zshrc 文件中,但仍然得到

OpenSSL::X509::DEFAULT_CERT_FILE
SSL_CERT_FILE: /Users/Rober/.rbenv/versions/3.0.3/openssl/ssl/cert.pem

解决方案 感谢@JanGaraj 在我的其他作品中为这个问题提供了正确的解决方案 post: SSL_connect returned=1 errno=0 state=error: certificate verify failed in ruby and Ubuntu 14.04

总结一下,除了上述几点外,我只需要更新指定我的 ca-certificates 文件的 Web 服务请求,例如:Savon.client(ssl_ca_cert_file: "/etc/ssl/certs/ca-certificates.crt ")

@jangaraj

在另一个 post 中提供了这个问题的解决方案

您似乎在使用 Ubuntu 14 和 Savon 2 客户端。 Savon 2 客户端文档:https://www.savonrb.com/version2/globals.html

ssl_ca_cert_file

设置要使用的 SSL ca 证书文件。

Savon.client(ssl_ca_cert_file: "lib/ca_cert.pem")

我会明确地将 ssl_ca_cert_file 指向 /etc/ssl/certs/ca-certificates.crt。