unable - Cómo establecer las opciones de contexto de TLS en Ruby(como OpenSSL:: SSL:: SSL_OP_NO_SSLv2)
unable to download data from https rubygems org no such name https rubygems org specs 4.8 gz (1)
En la biblioteca Ruby OpenSSL, las constantes de las opciones no tienen el prefijo ''SSL_''. Puede ver una lista de las constantes de las opciones ejecutando algo como esto en irb / console: OpenSSL::SSL.constants.grep(/OP_/)
. Aquí está la fuente relevante de Ruby C donde están definidos: https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_ssl.c#L2225 .
Editar: no parece haber una manera, fuera de la caja, de configurar las opciones SSL para net http. Ver https://bugs.ruby-lang.org/issues/9450 .
Sin embargo, por el momento puedes usar este pequeño truco:
(Net::HTTP::SSL_IVNAMES << :@ssl_options).uniq!
(Net::HTTP::SSL_ATTRIBUTES << :options).uniq!
Net::HTTP.class_eval do
attr_accessor :ssl_options
end
Ahora, simplemente configure el accesoador ssl_options en la instancia de Net :: HTTP. Ejemplo de uso:
uri = URI(''https://google.com:443'')
options_mask = OpenSSL::SSL::OP_NO_SSLv2 + OpenSSL::SSL::OP_NO_SSLv3 +
OpenSSL::SSL::OP_NO_COMPRESSION
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri)
if uri.scheme == "https"
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
http.ssl_options = options_mask
end
response = http.request request
# To Test
ssl_context = http.instance_variable_get(:@ssl_context)
ssl_context.options == options_mask # => true
Estaba probando con ruby 2.1.2 por lo que su kilometraje en otras versiones de ruby puede variar. Avíseme si no funciona en su versión preferida.
Para los interesados, la parte relevante del código Ruby que miré para crear este truco: https://github.com/ruby/ruby/blob/e9dce8d1b482200685996f64cc2c3bd6ba790110/lib/net/http.rb#L886
Al usar OpenSSL en C, establecemos opciones en el contexto para eliminar protocolos débiles y heridos como SSLv2 y SSLv3. Desde ssl.h
, aquí hay una máscara de algunas de las opciones que son útiles:
#define SSL_OP_NO_SSLv2 0x01000000L
#define SSL_OP_NO_SSLv3 0x02000000L
#define SSL_OP_NO_TLSv1 0x04000000L
#define SSL_OP_NO_TLSv1_2 0x08000000L
#define SSL_OP_NO_TLSv1_1 0x10000000L
Sin embargo, tengo problemas para configurarlos en Ruby:
if uri.scheme == "https"
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
http.options = OpenSSL::SSL::SSL_OP_NO_SSLv2 | OpenSSL::SSL::OP_NO_SSLv3 |
OpenSSL::SSL::SSL_OP_NO_COMPRESSION
end
Resultados en:
$ ./TestCert.rb
./TestCert.rb:12:in `<main>'': uninitialized constant OpenSSL::SSL::SSL_OP_SSL2 (NameError)
Los documentos de Ruby para 1.9.3 (y 2.0.0) ni siquiera se molestan en mencionarlo.
¿Cómo se configuran las opciones de contexto de TLS en Ruby?
Relacionado: estableciendo opciones de SSLContext en ruby . Pero no hay forma de adjuntar el contexto a un http
cuando http.use_ssl = true
.