【问题标题】:Why does accessing a SSL site with Mechanize on Windows fail, but on Mac work?为什么在 Windows 上使用 Mechanize 访问 SSL 站点会失败,但在 Mac 上可以工作?
【发布时间】:2012-01-23 23:24:30
【问题描述】:

这是我用来连接 SSL 站点的代码。

require 'mechanize'
a = Mechanize.new
page = a.get 'https://site.com'

我正在使用 Ruby 1.9.3 和 Mechanize 2.1pre1 + 依赖项。在 Mac 上,上面的代码工作并返回页面。在运行相同版本的 Windows 7 上,它给了我以下错误:

OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3
read server certificate B: certificate verify failed

恢复到 Mechanize 2.0.1 似乎可以解决这个问题,但是我随后被 too many connections reset by peer 问题所困扰。因此,这不是一个解决方案。

我尝试过a.verify_mode = false,但这并没有做任何事情。我读到您可以使用以下方法关闭 SSL 验证:

open(uri,:ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE)

如何在 Mechanize 中将其关闭?为什么我只在 Windows 上收到此错误?

【问题讨论】:

    标签: ruby mechanize


    【解决方案1】:

    您可以简单地执行以下操作:

    agent = Mechanize.new
    agent.verify_mode = OpenSSL::SSL::VERIFY_NONE
    

    这适用于最新版本 2.8

    【讨论】:

      【解决方案2】:

      OpenSSL 版本(用于与Net::HTTPS 建立安全连接的库)无法在​​您的计算机中正确找到证书链。

      不幸的是,OpenSSL 永远无法使用 Windows 安装的证书存储来验证远程服务器,因此失败了。

      从您的示例中,您可以这样做:

      a.agent.http.verify_mode = OpenSSL::SSL::VERIFY_NONE
      

      为了避免验证,但这远非理想(由于明确的安全问题)

      我建议你下载一些证书包(比如 curl 的包):

      http://curl.haxx.se/ca

      并将您的代码修改为如下内容:

      require "rbconfig"
      require "mechanize"
      
      a = Mechanize.new
      
      # conditionally set certificate under Windows
      # http://blog.emptyway.com/2009/11/03/proper-way-to-detect-windows-platform-in-ruby/
      if RbConfig::CONFIG["host_os"] =~ /mingw|mswin/
        # http://curl.haxx.se/ca
        ca_path = File.expand_path "~/Tools/bin/curl-ca-bundle.crt"
      
        a.agent.http.ca_file = ca_path
      end
      
      page = a.get "https://github.com/"
      

      这似乎可行,Ruby 1.9.3-p0 (i386-mingw32)、Windows 7 x64 和 mechanize 2.1.pre.1

      希望对您有所帮助。

      【讨论】:

      • 如果您正在测试已知主机的 SSL,则无需检查它是否有效。只要加密仍然有效?如果平台是 windows,你知道如何有条件地添加这个吗?
      • @KassymDorsel 更新了使用平台条件的代码,希望对您有所帮助。
      • 我在许多项目中使用了 a.agent.http.verify_mode = OpenSSL::SSL::VERIFY_NONE 但现在当我使用相同的东西时它没有效果。我仍然收到 SSL 错误 OpenSSL::SSL::SSLError Exception: SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: (null) 而在其他项目中它工作正常... ruby​​ 1.9.2 和 rails 3.2.0
      • 这对我有用(至少是一般方法)。我知道验证根 CA 位于 /opt/local/etc/openssl/cert.pem,因此告诉机甲使用该文件安全地解决了错误。但是谁能告诉我 Mechanize 默认使用什么证书包?据我所知,它没有使用 MacPorts openssl、OSX 钥匙串或 curl 附带的包。宝石本身似乎不包含一个。
      • 对于机械化 v=2.7.x,self.m_agent.verify_mode = OpenSSL::SSL::VERIFY_NONE
      【解决方案3】:

      Luis 的回答看起来不错,但更笼统:

      OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
      

      【讨论】:

      • 您应该避免执行 VERIFY_NONE,如果您不验证对方,这首先会破坏使用 HTTPS/SSL 的目的。如果我们通过透明代理或修改过的 DNS 将您重定向到假货是真实的地方进行连接,您将永远不会知道...
      • 是的,但是你在抓取网页时通常不会关心这些事情。
      • 仍然出现同样的错误OpenSSL::SSL::SSLError Exception: SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: (null)
      • @RAJ... 不知道您正在尝试什么版本的 Mechanize,但最新版本简化了对证书的访问。请查看有关使用证书的机械化文档。
      • @RAJ... 我在 Ruby 1.9.3 下遇到了完全相同的神秘错误read server hello A: (null。最后降级到 1.9.2-p290 一切正常。很奇怪。对不起,线程劫持家伙,但这是唯一的谷歌结果。
      猜你喜欢
      • 1970-01-01
      • 2015-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-22
      • 1970-01-01
      • 1970-01-01
      • 2011-03-04
      相关资源
      最近更新 更多