2011-07-25 61 views
5

我試圖在ruby腳本中連接到服務器https://www.xpiron.com/schedule。然而,當我嘗試連接:Ruby SSL錯誤 - sslv3警報意外消息

require 'open-uri' 
doc = open('https://www.xpiron.com/schedule') 

我收到以下錯誤信息:

OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: sslv3 alert unexpected message   
    from /usr/local/lib/ruby/1.9.1/net/http.rb:678:in `connect' 
    from /usr/local/lib/ruby/1.9.1/net/http.rb:678:in `block in connect' 
    from /usr/local/lib/ruby/1.9.1/timeout.rb:44:in `timeout' 
    from /usr/local/lib/ruby/1.9.1/timeout.rb:87:in `timeout' 
    from /usr/local/lib/ruby/1.9.1/net/http.rb:678:in `connect' 
    from /usr/local/lib/ruby/1.9.1/net/http.rb:637:in `do_start' 
    from /usr/local/lib/ruby/1.9.1/net/http.rb:626:in `start' 
    from /usr/local/lib/ruby/1.9.1/net/http.rb:1168:in `request' 
    from /usr/local/lib/ruby/1.9.1/net/http.rb:888:in `get' 
    from (irb):32 
    from /usr/local/bin/irb:12:in `<main>' 

我跑紅寶石1.9.2p180。它似乎在其他一些機器上工作,所以它可能是OpenSSL或Ruby的配置問題。我嘗試重新安裝所有的SSL庫,並從頭開始重建Ruby,但似乎沒有任何工作。有沒有人遇到過這個問題?

更新

在非工作機,OpenSSL的版本是0.9.8o 01 Jun 2010

在工作機器,它是0.9.8k 25 Mar 2009

所以更近的一個似乎是打破。

而且,如果我使用不同的HTTP客戶端(贊助人的基礎上,libcurl的),它的工作原理:

require 'patron' 

sess = Patron::Session.new 
sess.timeout = 5 
url = 'https://www.xpiron.com/schedule' 
resp = sess.get(url) 
puts "#{resp.body}" 

因此,這似乎是Ruby的OpenSSL的綁定問題。

+0

這是什麼'紅寶石-ropenssl -e「提出的OpenSSL :: OPENSSL_VERSION''在機器上說它不工作,它在那些工作上是什麼? – emboss

+0

Working:'OpenSSL 0.9.8k 2009年3月25日' 不工作:'OpenSSL 0.9.8o 2010年6月1日' 似乎有點不同,在更新的版本。 – marketer

回答

9

只是爲了回答我自己的問題。

這個問題似乎與Ruby如何協商SSL連接有關。 Xpiron的TLS機制存在錯誤,它會引發錯誤而不是重試其他SSL版本。

如果強制SSL版本3.0,它的工作原理:

require 'net/http' 
url = URI.parse('https://www.xpiron.com/schedule') 
req = Net::HTTP::Get.new(url.path) 
sock = Net::HTTP.new(url.host, 443) 
sock.use_ssl = true 
sock.ssl_version="SSLv3" 
sock.start do |http| 
    response = http.request(req) 
end 

我還創建了Ruby的bug tracker的問題。

+1

請告訴我們在哪個文件中進行了這些修改,如果您使用的是RoR – Aleksandrus

2

我認爲這是因爲https URL。有一個平均的,完全不安全的黑客繞過這個,但請谷歌自負風險。我寧願給你做它的安全的方式,使用網:: HTTP:

require 'net/http' 

url = URI.parse('https://www.xpiron.com/schedule') 
req = Net::HTTP::Get.new(url.path) 
sock = Net::HTTP.new(url.host, 443) 
sock.use_ssl = true 
store = OpenSSL::X509::Store.new 
store.add_cert OpenSSL::X509::Certificate.new(File.new('addtrust_ca.pem')) 
store.add_cert OpenSSL::X509::Certificate.new(File.new('utn.pem')) 
store.add_cert OpenSSL::X509::Certificate.new(File.new('user_first_ca.pem')) 
store.add_cert OpenSSL::X509::Certificate.new(File.new('xpiron.pem')) 
sock.cert_store = store 
sock.start do |http| 
    response = http.request(req) 
end 

您可以通過在瀏覽器(如Firefox)的輸入您的網址,然後點擊圖標左側獲得證書文件URL /更多信息/查看證書/詳細信息 - >在那裏點擊鏈中的每個證書,並將其導出爲PEM文件,並使用上面使用的名稱。將這些文件放在與引用它們的腳本相同的目錄中。這應該做的魔術。但我注意到需要cookie來登錄到該頁面,因此可能需要更多的努力來適當地修改您的請求。

+0

非常感謝回覆。我嘗試了所有這些,但錯誤仍然存​​在。我認爲問題在於xpiron SSL服務器配置錯誤。 Chrome警告說:「連接必須使用SSL 3.0重試。這通常意味着服務器正在使用非常舊的軟件,並可能存在其他安全問題。 – marketer

+0

很高興你找到了解決方案! – emboss

0

請注意,rest-client寶石沒有辦法在撰寫本文時對此進行設置。有an outstanding pull request,但不幸的是,寶石似乎並沒有維持。

+0

拉取請求的新URL:https://github.com/rest-client/rest-client/pull/123 –

1

黑客攻擊了一整天后,這一次終於爲我工作:

url = URI.parse("https://full-url?test=1&foo=bar") 
response = Net::HTTP.start(url.host, use_ssl: true, ssl_version: 'SSLv3', verify_mode: OpenSSL::SSL::VERIFY_NONE) do |http| 
    http.get url.request_uri 
end 
0

它可以

require 'openssl' 
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE