[ruby-list:50827] Re: OpenSSLのセキュリティレベルの変更

From: Tadashi Saito <tad.a.digger@...>
Date: 2019-09-28 00:23:26 UTC
List: ruby-list #50827
斎藤と申します。

自分もbusterを常用しているので興味を惹かれて、今ざっくり、ソースを
見ていました。

> この件ですが、少なくとも現時点でのRubyでは不可能なようなので、Rubyの方
> に以下のようなパッチを当てるという、反則技のような方法を採ることにしま
> した。

こちらの単なる別案ですが、内部的に set_params を利用できそうだと考えて、
以下のようなモンキーパッチを書いてみました。( `attr_accessor` は同じです)

class Net::HTTP
  attr_accessor :security_level
  SSL_IVNAMES << :@security_level
  SSL_ATTRIBUTES << :security_level
end

これのあとに以下を実行すると、ちゃんと「2」が表示されます。
また適当な数値(42とか100とか)をレベルに設定すると、失敗することまでは
確認できると思います。

https = Net::HTTP.new("www.example.org", 443)
https.use_ssl = true
https.security_level = 2 # この行で設定できる

# Contextの設定のために適当に繋ぐ。例外は発生しない
https.start {}
# 中身を強引に覗くと 2 になっている
pp https.instance_variable_get(:@ssl_context).security_level

ちなみに確認したのは、Ruby 2.6.4です。

サーバーとのやり取りまでは確認しておらず、また参考になるかも
分かりませんが、共有でした。


2019年9月28日(土) 8:08 Yasuhiro KIMURA <yasu@utahime.org>:

> 木村です。
>
> From: Yasuhiro KIMURA <yasu@utahime.org>
> Subject: [ruby-list:50812] OpenSSLのセキュリティレベルの変更
> Date: Sat, 24 Aug 2019 07:14:43 +0900 (JST)
>
> > それで質問なのですが、Rubyのプログラムの中からOpenSSLのセキュリティレ
> > ベルを変更することは可能でしょうか。標準ライブラリのドキュメントを検索
> > して、OpenSSL::SSL::SSLContext#security_level=というメソッドがあるのは
> > 判ったのですが、これとNet::HTTPをどう組み合わせたら良いのかがわかりま
> > せん。この辺の具体的な手順が解る方がいらっしゃいましたら、教えてくださ
> > い。
>
> この件ですが、少なくとも現時点でのRubyでは不可能なようなので、Rubyの方
> に以下のようなパッチを当てるという、反則技のような方法を採ることにしま
> した。
>
> ----------------------------------------------------------------------
> diff --git a/lib/net/http.rb b/lib/net/http.rb
> index 31cbb7a866..a760a4a918 100644
> --- a/lib/net/http.rb
> +++ b/lib/net/http.rb
> @@ -689,6 +689,7 @@ def initialize(address, port = nil)
>        SSL_IVNAMES.each do |ivname|
>          instance_variable_set ivname, nil
>        end
> +      @security_level = OpenSSL::SSL::SSLContext.new.security_level
>      end
>
>      def inspect
> @@ -746,6 +747,9 @@ def set_debug_output(output)
>      # Net::WriteTimeout is not raised on Windows.
>      attr_reader :write_timeout
>
> +    # Security level applied to OpenSSL when HTTPS is used.
> +    attr_accessor :security_level
> +
>      # Maximum number of times to retry an idempotent request in case of
>      # Net::ReadTimeout, IOError, EOFError, Errno::ECONNRESET,
>      # Errno::ECONNABORTED, Errno::EPIPE, OpenSSL::SSL::SSLError,
> @@ -979,6 +983,7 @@ def connect
>            end
>          end
>          @ssl_context = OpenSSL::SSL::SSLContext.new
> +        @ssl_context.security_level = @security_level
>          @ssl_context.set_params(ssl_parameters)
>          @ssl_context.session_cache_mode =
>            OpenSSL::SSL::SSLContext::SESSION_CACHE_CLIENT |
> ----------------------------------------------------------------------
>
> これによって例えば、
>
> ----------------------------------------------------------------------
> require 'net/http'
>
> https = Net::HTTP.new("www.example.org", 443)
> https.use_ssl
> https.security_level = 0
> ----------------------------------------------------------------------
>
> などとすればセキュリティレベルを変更することが出来ます。
>
> あまり他の方に役立ちそうな気がしませんが、一応ご報告まで。
>
> ---
> 木村 康浩
>


-- 
斎藤 匡

In This Thread

Prev Next