[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
> ----------------------------------------------------------------------
>
> などとすればセキュリティレベルを変更することが出来ます。
>
> あまり他の方に役立ちそうな気がしませんが、一応ご報告まで。
>
> ---
> 木村 康浩
>
--
斎藤 匡