Использование механизма (или даже Net::HTTP) с ruby ​​1.9 возвращает «OpenSSL::SSL::SSLError» — как заставить SSLv3?

Я думаю, что за последние 2 дня я просмотрел все доступные (доступные для Google) сообщения об этой ошибке SSL в связи с Net::HTTP: OpenSSL::SSL::SSLError: SSL_connect SYSCALL returned=5 errno=0 state=SSLv2/v3 read server hello A

В первую очередь я пытался подключиться к серверу EtherPad (https://test.titanpad.com), войти в систему и загрузить zip-архив с помощью rubygems & mechanize; однако, к сожалению, я даже не дохожу до этого момента из-за упомянутого SSL-Error. После попытки отладить проблему из объекта механизма (например, установив 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 выяснилось, что настоящая проблема в этом случае заключается в том, что для работы рукопожатия с Jetty 6.1.20 server за titanpad.com необходимо принудительно использовать SSLv3:

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 для использования в Mechanize... и поэтому я был бы очень рад, если бы кто-нибудь мог указать мне как как я могу применить SSLv3 через указанный драгоценный камень oO

Еще раз спасибо!

Система: Mac OSX 10.6.8 ruby ​​1.9.3p0 (30.10.2011, редакция 33570) [x86_64-darwin10] rubygems, установленные с помощью механизма: имя_домена (0.5.2), механизм (2.1.1), net-http-digest_auth ( 1.2), net-http-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)


person astera    schedule 05.02.2012    source источник
comment
На самом деле, я начинаю думать, что это проблема OpenSSL с веб-сервером за titanpad.com, очевидно, Jetty 6.1.20...   -  person astera    schedule 05.02.2012
comment
Хокей, обновление ... Я искал не те стороны проблемы - похоже, это разница между использованием любого типа SSL и SSLv3. Таким образом, хотя openssl s_client -connect test.titanpad.com:443 выдаст ошибку, форсирование v3 с openssl s_client -no_tls1 -no_ssl2 -ssl3 -connect test.titanpad.com:443 работает просто отлично.   -  person astera    schedule 05.02.2012


Ответы (1)


Исправлено путем переноса функциональности ssl_version из Net::HTTP (через net-http-persistent) в Mechanize v. 2.1.2 (см. " rel="nofollow">https://github.com/tenderlove/mechanize/commit/4a228899855e0676ab69c2bf548170c8717465d8).

person astera    schedule 07.02.2012
comment
@astera- У меня такая же проблема даже при использовании Mechanize v. 2.7.3. Ссылка, которую вы указали выше, не найдена. Не могли бы вы помочь в решении этого? - person owgitt; 27.05.2015