Ruby 1.8.7 и Net :: HTTP: сделать запрос SSL GET с сертификатом клиента? - PullRequest
9 голосов
/ 24 января 2012

Я пытаюсь получить ресурс через SSL, используя Net::HTTP.Вот соответствующий фрагмент кода:

req = Net::HTTP::Get.new(ContentURI.path)
https = Net::HTTP.new(ContentURI.host, ContentURI.port)
https.use_ssl = true
https.cert = OpenSSL::X509::Certificate.new(@cert_raw)
https.key = OpenSSL::PKey::RSA.new(@cert_key_raw)
https.verify_mode = OpenSSL::SSL::VERIFY_PEER
https.ca_file = File.join(TestDataPath, 'cacert.pem')
resp = https.start { |cx| cx.request(req) }

или с альтернативной последней строкой:

resp = https.get(ContentURI.path)

Я проверил, что различные биты (сертификат, ключ, сертификат CA, )и т. д. ) верны.

Проблема в том, что cx.request(req) выдает исключение:

OpenSSL::SSL::SSLError: SSL_connect SYSCALL returned=5 errno=0 state=SSLv3 read server session ticket A

Журнал ошибок Apache SSL на сервере содержит следующее:

[Tue Jan 24 11:47:26 2012] [debug] ssl_engine_kernel.c(1876): OpenSSL: Loop: SSLv3 read finished A
[Tue Jan 24 11:47:26 2012] [debug] ssl_engine_kernel.c(1905): OpenSSL: Exit: error in SSLv3 write session ticket A
[Tue Jan 24 11:47:26 2012] [debug] ssl_engine_kernel.c(1905): OpenSSL: Exit: error in SSLv3 write session ticket A
[Tue Jan 24 11:47:26 2012] [info] [client 10.11.88.53] SSL handshake interrupted by system [Hint: Stop button pressed in browser?!]
[Tue Jan 24 11:47:26 2012] [info] [client 10.11.88.53] Connection closed to child 0 with abortive shutdown (server _SERVERNAME_:443

Сертификат, ключ и файл сертификата CA работают с этим хостом SSL через другие инструменты;Мне просто не удается воспроизвести этот успех программно, используя Net::HTTP[S].

Спасибо всем, кто может определить, что я делаю неправильно!

1 Ответ

6 голосов
/ 06 февраля 2012

Я бы сказал, что это связано с настройкой вашего Apache, а не с самим Ruby.

Проверьте это:

$ curl https://palladium.wejn.cz/sslcerttest/
curl: (56) SSL read: error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure, errno 0
$ curl https://palladium.wejn.cz/sslcerttest/ -E client.pem
Yop.

А потом:

#!/usr/bin/ruby
require 'net/http'
require 'net/https'
require 'openssl'
require 'uri'

ContentURI = URI.parse("https://palladium.wejn.cz/sslcerttest/")
@cert_raw = File.read('client.pem')
@cert_key_raw = @cert_raw
TestDataPath = '.'

req = Net::HTTP::Get.new(ContentURI.path)
https = Net::HTTP.new(ContentURI.host, ContentURI.port)
https.use_ssl = true
https.cert = OpenSSL::X509::Certificate.new(@cert_raw)
https.key = OpenSSL::PKey::RSA.new(@cert_key_raw)
https.verify_mode = OpenSSL::SSL::VERIFY_PEER
https.ca_file = File.join(TestDataPath, 'cacert.pem')
resp = https.start { |cx| cx.request(req) }
p resp
p resp.body

Результат:

$ ruby a.rb
#
"Yop.
\ п» $ dpkg -l ruby1.8 | хвост -n1 | awk '{print $ 3}' 1.8.7.302-2squeeze1 $ ruby ​​-v ruby 1.8.7 (2010-08-16, уровень обновления 302) [x86_64-linux]

Конечно, рассматриваемый конфиг apache:

<Directory /var/www/sslcerttest/>
    SSLVerifyClient require
    SSLVerifyDepth 5
    SSLCACertificateFile /var/www/sslcerttest/cacert.pem
    SSLCACertificatePath /var/www/sslcerttest/
    SSLOptions +FakeBasicAuth
    SSLRequireSSL
    SSLRequire %{SSL_CLIENT_S_DN_O} eq "Wejn s.r.o." and %{SSL_CLIENT_S_DN_OU} eq "Server Certificate"
</Directory>

Может быть, публикация дополнительных сведений (конфигурация apache для тестирования) может помочь при поиске этой проблемы ...

...