如何在Ruby中设置TLS上下文选项(如OpenSSL :: SSL :: SSL_OP_NO_SSLv2)

jww*_*jww 11 ruby ssl openssl options

在C中使用OpenSSL时,我们在上下文中设置选项以删除弱受损和受伤的协议,如SSLv2和SSLv3.从ssl.h,这里是一些有用的选项的位掩码:

#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
Run Code Online (Sandbox Code Playgroud)

但是,我在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
Run Code Online (Sandbox Code Playgroud)

结果是:

$ ./TestCert.rb
./TestCert.rb:12:in `<main>': uninitialized constant OpenSSL::SSL::SSL_OP_SSL2 (NameError)
Run Code Online (Sandbox Code Playgroud)

1.9.3(和2.0.0)的Ruby文档甚至都不愿提及它.

如何在Ruby中设置TLS上下文选项?


相关:在ruby中设置SSLContext选项.但是没有办法将上下文附加到http何时http.use_ssl = true.

Gra*_*ray 15

在Ruby OpenSSL库中,选项常量不以"SSL_"为前缀.您可以通过在irb/console中运行类似的东西来查看选项常量列表:OpenSSL::SSL.constants.grep(/OP_/).以下是定义它们的相关ruby C源:https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_ssl.c#L2225.

编辑: 开箱即用,似乎没有办法为net http设置SSL选项.请参阅https://bugs.ruby-lang.org/issues/9450.

但是暂时你可以使用这个小黑客:

(Net::HTTP::SSL_IVNAMES << :@ssl_options).uniq!
(Net::HTTP::SSL_ATTRIBUTES << :options).uniq!

Net::HTTP.class_eval do
  attr_accessor :ssl_options
end
Run Code Online (Sandbox Code Playgroud)

现在只需在Net :: HTTP实例上设置ssl_options访问器.用法示例:

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
Run Code Online (Sandbox Code Playgroud)

我正在测试ruby 2.1.2所以你在其他版本的红宝石上的里程可能会有所不同.如果它对您的首选版本不起作用,请告诉我.

对于那些感兴趣的人,我看到了ruby代码的相关部分来创建这个hack:https://github.com/ruby/ruby/blob/e9dce8d1b482200685996f64cc2c3bd6ba790110/lib/net/http.rb#L886