在 ruby 1.9 中使用 mechanize(甚至 Net::HTTP)返回'OpenSSL::SSL::SSLError' - 如何强制 SSLv3?



在过去的两天里,我想我已经浏览了关于Net::HTTP的SSL错误的每一篇可用的帖子:OpenSSL::SSL::SSLError: SSL_connect SYSCALL returned=5 errno=0 state=SSLv2/v3 read server hello A

我最初尝试的是连接到EtherPad服务器(https://test.titanpad.com),登录,并通过使用rubygems&机械化;然而,不幸的是,由于所说的SSL-Error,我甚至没有达到这一点。在尝试从mechanize对象中调试问题(例如,通过在脚本中手动设置cert、ca_file、cert_store、verify_mode等)后,我更接近实际的问题,尝试连接到https://test.titanpad.com通过简单地使用Net::HTTP:

(在本例中,我首先连接到https://encrypted.google.com为了确保SSL应该工作;连接到EtherPad服务器的尝试从第6)行开始

irb(main):001:0> require 'net/https'
=> true
irb(main):002:0> google = Net::HTTP.new('encrypted.google.com', 443)
=> #<Net::HTTP encrypted.google.com:443 open=false>
irb(main):003:0> google.use_ssl = true
=> true
irb(main):004:0> google.ca_file = '/opt/local/share/curl/curl-ca-bundle.crt' if File.exists?('/opt/local/share/curl/curl-ca-bundle.crt')
=> "/opt/local/share/curl/curl-ca-bundle.crt"
irb(main):005:0> google.request_get('/')
=> #<Net::HTTPOK 200 OK readbody=true>
irb(main):006:0> etherpad = Net::HTTP.new('test.titanpad.com', 443)
=> #<Net::HTTP test.titanpad.com:443 open=false>
irb(main):007:0> etherpad.use_ssl = true
=> true
irb(main):008:0> etherpad.ca_file = '/opt/local/share/curl/curl-ca-bundle.crt' if File.exists?('/opt/local/share/curl/curl-ca-bundle.crt')
=> "/opt/local/share/curl/curl-ca-bundle.crt"
irb(main):009:0> etherpad.request_get('/')
OpenSSL::SSL::SSLError: SSL_connect SYSCALL returned=5 errno=0 state=SSLv2/v3 read server hello A
    from /opt/local/lib/ruby1.9/1.9.1/net/http.rb:799:in `connect'
    from /opt/local/lib/ruby1.9/1.9.1/net/http.rb:799:in `block in connect'
    from /opt/local/lib/ruby1.9/1.9.1/timeout.rb:54:in `timeout'
    from /opt/local/lib/ruby1.9/1.9.1/timeout.rb:99:in `timeout'
    from /opt/local/lib/ruby1.9/1.9.1/net/http.rb:799:in `connect'
    from /opt/local/lib/ruby1.9/1.9.1/net/http.rb:755:in `do_start'
    from /opt/local/lib/ruby1.9/1.9.1/net/http.rb:744:in `start'
    from /opt/local/lib/ruby1.9/1.9.1/net/http.rb:1284:in `request'
    from /opt/local/lib/ruby1.9/1.9.1/net/http.rb:1195:in `request_get'
    from (irb):9
    from /opt/local/bin/irb:12:in `<main>'

即使在使用verify_mode OpenSSL::SSL::VERIFY_NONE时,OpenSSL也会退出:

irb(main):010:0> etherpad.verify_mode = OpenSSL::SSL::VERIFY_NONE
=> 0
irb(main):011:0> etherpad.request_get('/')
OpenSSL::SSL::SSLError: SSL_connect SYSCALL returned=5 errno=0 state=SSLv2/v3 read server hello A
    from /opt/local/lib/ruby1.9/1.9.1/net/http.rb:799:in `connect'
    from /opt/local/lib/ruby1.9/1.9.1/net/http.rb:799:in `block in connect'
    from /opt/local/lib/ruby1.9/1.9.1/timeout.rb:54:in `timeout'
    from /opt/local/lib/ruby1.9/1.9.1/timeout.rb:99:in `timeout'
    from /opt/local/lib/ruby1.9/1.9.1/net/http.rb:799:in `connect'
    from /opt/local/lib/ruby1.9/1.9.1/net/http.rb:755:in `do_start'
    from /opt/local/lib/ruby1.9/1.9.1/net/http.rb:744:in `start'
    from /opt/local/lib/ruby1.9/1.9.1/net/http.rb:1284:in `request'
    from /opt/local/lib/ruby1.9/1.9.1/net/http.rb:1195:in `request_get'
    from (irb):11
    from /opt/local/bin/irb:12:in `<main>'

经过对openssl本身的进一步研究,在这种情况下,真正的问题是必须强制使用SSLv3才能与titanpad.com背后的Jetty 6.1.20 server进行握手:

irb(main):001:0> require 'net/https'
=> true
irb(main):002:0> etherpad = Net::HTTP.new('test.titanpad.com', 443)
=> #<Net::HTTP test.titanpad.com:443 open=false>
irb(main):003:0> etherpad.use_ssl = true
=> true
irb(main):004:0> etherpad.ssl_version = "SSLv3"
=> "SSLv3"
irb(main):005:0> etherpad.ca_file = '/opt/local/share/curl/curl-ca-bundle.crt' if File.exists?('/opt/local/share/curl/curl-ca-bundle.crt')
=> "/opt/local/share/curl/curl-ca-bundle.crt"
irb(main):006:0> etherpad.request_get('/')
=> #<Net::HTTPFound 302 Found readbody=true>

现在,虽然这在使用Net::HTTP时显然有效,但没有这样的选项,即设置SSL版本以在机械化中使用。。。因此,如果有人能向我指出我如何通过上述gem o.o 执行SSLv3,我将非常高兴

再次感谢!

系统:Mac OSX 10.6.8ruby 1.9.3p0(2011-10-30修订版33570)[x86_64-darwin10]安装了mechanize的rubygems:domain_name(0.5.2)、mechanize(2.1.1)、net-http-digest_auth(1.2)、nethttp persistent(2.4.1)、nokogiri(1.5.0)、ntlm-http(0.1.1)、unf(0.0.4)、unf_ext(0.0.4)、webrobots(0.0.13)

已通过将ssl_version功能从Net::HTTP(通过nethttp持久化)移植到机械化v.2.1.2(请参阅https://github.com/tenderlove/mechanize/commit/4a228899855e0676ab69c2bf548170c8717465d8)。

最新更新