繁体   English   中英

OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=error: certificate verify failed (unable to get local issuer certificate)

[英]OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=error: certificate verify failed (unable to get local issuer certificate)

有很多关于这个的帖子。 我看过很多。 零个修复程序似乎有效。

(main)> PayPal::SDK::Subscriptions::Plan.all
Request[post]: https://api.sandbox.paypal.com/v1/oauth2/token
Request.body=grant_type=client_credentials  request.header={"User-Agent"=>"PayPalSDK/PayPal-Subscriptions-Ruby-SDK 0.3.1 (paypal-sdk-core 1.7.4; ruby 2.6.6p146-x86_64-linux;OpenSSL 1.1.1d  10 Sep 2019)", "Content-Type"=>"application/x-www-form-urlencoded", "Authorization"=>"Basic xxx"}
OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=error: certificate verify failed (unable to get local issuer certificate)
from /usr/local/lib/ruby/2.6.0/net/protocol.rb:44:in `connect_nonblock'

我试过 rvm 2.6.6、2.7.0 和 Debian Buster 系统 ruby。

我遵循了所有这些: https://bundler.io/v2.0/guides/rubygems_tls_ssl_troubleshooting_guide.html#troubleshooting-certificate-errors

我运行了自动 SSL 检查,一切顺利: https://bundler.io/v2.0/guides/rubygems_tls_ssl_troubleshooting_guide.html#automated-ssl-check

root@19ab47f15632:/usr/src/app# curl -Lks 'https://git.io/rg-ssl' | ruby
Here's your Ruby and OpenSSL environment:

Ruby:           2.6.6p146 (2020-03-31 revision 67876) [x86_64-linux]
RubyGems:       3.0.3
Bundler:        2.1.2
Compiled with:  OpenSSL 1.1.1d  10 Sep 2019
Loaded version: OpenSSL 1.1.1d  10 Sep 2019
SSL_CERT_FILE:  /usr/lib/ssl/cert.pem
SSL_CERT_DIR:   /usr/lib/ssl/certs

With that out of the way, let's see if you can connect to rubygems.org...

Bundler connection to rubygems.org:       success ✅
RubyGems connection to rubygems.org:      success ✅
Ruby net/http connection to rubygems.org: success ✅

Hooray! This Ruby can connect to rubygems.org. You are all set to use Bundler and RubyGems. 👌

我试过gem update --system ,捆绑器已更新。

我尝试将新 CA 卷曲到 ruby 的默认 SSL 文件的位置:

curl -fsSL curl.haxx.se/ca/cacert.pem -o "$(ruby -ropenssl -e 'puts OpenSSL::X509::DEFAULT_CERT_FILE')"

我检查了我的系统时间是否准确(准确到 UTC)。

我不知道从这里做什么。 PayPal SDK 订阅 gem 在幕后使用 .net/http,因为它依赖于核心 PayPal SDK gem。 我尝试将日志级别提高到 DEBUG,但它没有打印出任何额外的详细信息,因为它似乎在同一个确切的地方失败了,而且我无法弄清楚那个失败到底在哪里。

我不知所措。 除了禁用 SSL 验证,我不知道该怎么做。 有没有办法在此处获得更多回溯/更多错误以进一步排除故障? 直接对 PayPal API 使用 .net/http 工作正常(没有 SSL 错误)。 所以这是在初始请求之后发生的事情

可以通过使用服务器自己的 CA 文件来修复此问题。

尝试设置ssl_options: { ca_file: nil }

这会导致与 paypal-sdk gem 捆绑在一起的paypal.crt CA 文件被忽略。

对于使用 PayPal::SDK.configure(...) 的应用

PayPal::SDK.configure(
  mode: ...,
  client_id: ...,
  client_secret: ...,

  # Deliberately set ca_file to nil so the system's Cert Authority is used,
  # instead of the bundled paypal.crt file which is out-of-date due to:
  # https://www.paypal.com/va/smarthelp/article/discontinue-use-of-verisign-g5-root-certificates-ts2240
  ssl_options: { ca_file: nil }
)

对于使用 YAML 配置文件的应用程序

config/paypal.yml或您的配置文件所在的任何位置:

ssl_options:
  ca_file: null

我把它留在这里,但 RidingRails 的回答是我认为“正确”的。 这是处理这种长期问题的正确解决方案,尽管真正的解决方案是转移到 PayPal 的更新 gem。

我在下面的回答是为了帮助您快速使 PayPal 重新工作,而无需推出代码更新。


这真的很难看,因为 PayPal 将证书与他们的 gem 打包在一起。 要启动并运行,您需要在您的包中找到 gem,特别是找到文件“paypal.crt”。 最后,您需要添加缺少的两个证书。 我不打算在这里复制/粘贴它们,但它们很容易找到。 实际上,它们已经在我的 Ubuntu 系统的 /etc/ssl/certs 中:

DigiCert_Global_Root_G2.pem

DigiCert_High_Assurance_EV_Root_CA.pem

PayPal 在这里提供链接:

https://www.paypal.com/va/smarthelp/article/discontinue-use-of-verisign-g5-root-certificates-ts2240

修复步骤:

  1. 在您使用的 gem 版本中找到 paypal.crt 文件。 这对我来说是这样的:

    cd 应用程序/生产/共享/捆绑包

    寻找。 -名称 paypal.crt

    此时,我在 gem 的 1.7.3 和 1.7.4 版本中有一个文件。 我使用的是 1.7.4 版本,所以我编辑了那个文件。

  2. 将这两个证书添加到底部。 您应该将证书的名称放在一行中,一行重复“=”以形成一个很好的分隔符,然后是包括 BEGIN 和 END 行的整个证书。

  3. 重新启动您的应用程序。

这不是一个长期的解决方案,但可以让您快速恢复运行。 长期 - 升级到新的宝石。

这是我们最终在我的团队中所做的事情。

我们添加了 Michael 在中提到的 2 个证书

config/api.paypal.com.crt

然后在 paypal.yml

 ssl_options:
    ca_file: config/api.paypal.com.crt

我们按原样离开了宝石。 最初我们通过 gem 来寻找答案,但最终我们保留了 gem 并添加了 crt 并更新了 yaml,如上所示。

如果您不使用PayPal::SDK.configure 在paypal.yml中添加

  ssl_options:
    ca_file: null

由于 PayPal 已更改 TLS,因此最简单(最快)的方法是解析为猴子补丁。 这个补丁说要使用所有默认设置

module PayPal::SDK::Core
  module Util
    module HTTPHelper
      def configure_ssl(http)
        http.tap do |https|
          https.use_ssl = true
          https.verify_mode = OpenSSL::SSL::VERIFY_PEER
          add_certificate(https)
        end
      end
    end
  end
end

与@kritik 类似但侵入性略小的解决方案

module PayPal::SDK::Core::Util::HTTPHelper
  def default_ca_file
    nil # packaged CA file was out of date, use the system file
  end
end

这仍然允许您更改初始化程序中的其他 SSL 设置,并且仅删除默认的 CA 文件。

你想在config/initializers中创建一个文件,并将上面的代码放入其中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM