【问题标题】:certificate Error SSL_connect returned=1 errno=0 state=error: certificate verify failed证书错误 SSL_connect 返回=1 errno=0 状态=错误:证书验证失败
【发布时间】:2018-02-09 01:25:30
【问题描述】:

我正在使用一个 ruby​​/rails 应用程序,它通过 rest/API 从另一个 ruby​​/rails 应用程序接收一些信息。

第二个 rails 应用程序的地址如下:https://railsapp2.domain.org(这是我在第一个应用程序中使用的授权 URL)

但是当作业在我的第一个应用程序上运行时出现错误。

错误是:SSL_connect returned=1 errno=0 state=error: certificate verify failed

我相信问题是因为我的应用程序中的这段代码:

 def self.fetch(url)
   authorized_url = RemoteRequestBuilder.authorize_and_decorate!(url)

   RestClient.get(authorized_url, { accept: :json }) { |response, request, result, &block|
    raise SparcApiError unless response.code == 200

    @response = response
  }

  Yajl::Parser.parse @response
end

我找了一些答案,发现我可以使用 verify_ssl: false ,但我不知道在哪里使用它。还有如何使用 verify_ssl 使它工作:true。

我还安装了经过认证的 gem,但它不会改变任何输出。

我正在使用centOS7。

编辑

所以我这样做了

   RestClient::Resource.new(
   authorized_url,
   :ssl_client_cert  => OpenSSL::X509::Certificate.new(File.read("/etc/certs/mycert.pem")),
   :ssl_client_key   =>  OpenSSL::PKey::RSA.new(File.read("/etc/private/mykey.key")),
   :ssl_ca_file      =>  "/etc/certs/mycert.pem",
   :verify_ssl       =>  OpenSSL::SSL::VERIFY_PEER
   ).get(authorized_url, { accept: :json }) { |response, request, result, &block|
  raise SparcApiError unless response.code == 200

  @response = response
}

现在它给了我错误的 get 参数数量。

|参数数量错误(2 代表 0..1) /home/capistrano/opt/shared/bundle/ruby/2.1.0/gems/rest-client-2.0.2/lib/restclient/resource.rb:49:in `get'

所以我从 get 中删除了 authorized_url 参数,然后它开始给我错误证书验证失败。

所以我放了

 :verify_ssl       =>  OpenSSL::SSL::VERIFY_NONE

现在它给了我错误:对等方重置连接 - SSL_connect

【问题讨论】:

    标签: ruby-on-rails ssl


    【解决方案1】:

    根据 Rest-Client gem 的documentation

    RestClient::Resource.new(
      'https://example.com',
      :ssl_client_cert  =>  OpenSSL::X509::Certificate.new(File.read("cert.pem")),
      :ssl_client_key   =>  OpenSSL::PKey::RSA.new(File.read("key.pem"), "passphrase, if any"),
      :ssl_ca_file      =>  "ca_certificate.pem",
      :verify_ssl       =>  OpenSSL::SSL::VERIFY_PEER
    ).get
    

    可用于指定 ca-certificate 并对其进行验证。如果不想验证,修改verify-ssl键为OpenSSL::SSL::VERIFY_NONE

    根据RestClient.get() 和RestClient::Resource.new(...).get 的RestClient gem 源代码,这两个方法都调用Request.execute()。因此,您的参数将保持不变,除非您需要将授权 url 传递给 .new 的参数。所以你的代码会变成这样:

    my_client = RestClient::Resource.new(
      authorized_url,
      :ssl_client_cert  =>  OpenSSL::X509::Certificate.new(File.read("cert.pem")),
      :ssl_client_key   =>  OpenSSL::PKey::RSA.new(File.read("key.pem"), "passphrase, if any"),
      :ssl_ca_file      =>  "ca_certificate.pem",
      :verify_ssl       =>  OpenSSL::SSL::VERIFY_PEER
    )
    
    my_client.get({ accept: :json }) { |response, request, result, &block|
        raise SparcApiError unless response.code == 200
    
        @response = response
      }
    

    这样,您可以重复使用my_client 对象来发送具有相同ssl 选项和url 的GET/POST/PUT/PATCH/DELETE 请求。例如my_client.post(...){...}


    注意:

    1. 不应在生产中跳过验证 ssl 证书。这只能在开发/测试环境中使用,否则您将容易受到中间人攻击。
    2. 如果您信任 CA 证书,则应将其添加到主机安装的证书包中。

    【讨论】:

    • 但并不是说不验证意味着您对未检测到的中间人攻击持开放态度。因此,提供适当的 CA 证书是除仅测试代码之外的任何内容的推荐选项。
    • 如何按照我的方式解析这段代码的响应,检查我的代码。
    • 我已经用正确的用法更新了我的答案。你不应该再次将authorized_url 传递给.get 方法。
    • 谢谢,它正在工作。唯一的问题是为什么当我启用 verify_ssl 时它不起作用,我复制了授权提供的证书,这是一个通配符证书,我复制了 .pem 和私钥来分隔文件并在代码中链接它,但它仍然抛出证书不已验证。
    • 根据您编辑的代码,它表明您的 CA 证书与您的客户端证书相同。自签名证书意味着您创建了自己的 CA 证书并使用它来签署您自己生成的服务器证书。另外,授权的 url 服务器是否具有由您的my_cert.pem 签名的服务器证书?如果没有,那么您应该在用于签署您的 railsapp2.domain.org 的参数中提供正确的 CA 证书。
    猜你喜欢
    • 1970-01-01
    • 2013-09-08
    • 2020-11-22
    • 2011-05-30
    相关资源
    最近更新 更多