LoginSignup
0
0

More than 1 year has passed since last update.

Ubuntu上で、curl使用時やruby/open-uri使用時の"dh key too small"エラー対処法

Last updated at Posted at 2022-09-16

発生した問題

Rubyでopen-uriライブラリを使用してWebスクレイビングをしていたところ、openメソッド実行時に以下のエラーが表示され、サイトにアクセスできなかった。

/home/user/.rbenv/versions/3.0.3/lib/ruby/3.0.0/net/protocol.rb:46:in `connect_nonblock': SSL_connect returned=1 errno=0 state=error: dh key too small (OpenSSL::SSL::SSLError)

この後、Ubuntu上でcurlコマンド使用時に

$ curl (URL)
[1] 3589
curl: (35) error:141A318A:SSL routines:tls_process_ske_dhe:dh key too small

というエラーが表示され、curlコマンドでもサイトにアクセスできなかった。
私が取った解決法を2パターンまとめる。

また、この問題はUbuntuの設定の問題なので、Ruby以外の言語で同様のことが起きた際も解決に役立つかもしれない。
Ubuntu上でcurlコマンドを使ったときに上と同様の表示になる場合は、以下の解決法を試してみてほしい。

前提条件

筆者の環境はWindows11上のWSL2を用いてUbuntu20.04LTSを起動している。また、Ruby3.03を使用して開発している。

$ uname -a
Linux LAPTOP-01OUKT07 5.15.57.1-microsoft-standard-WSL2 #1 SMP Wed Jul 27 02:20:31 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.5 LTS"

$ ruby -v
ruby 3.0.3p157 (2021-11-24 revision 3fb7d2cadc) [x86_64-linux]

2つの解決法の概説

解決法1. OSの設定を変更する

Ubuntuの設定ファイルであるopenssl.cnfを書き換える方法

  • 良い点: 設定が一度で終わり、以降は気にしなくてよくなる
  • 悪い点: OS全体のセキュリティレベルが下がる

解決法2. Rubyのソースコード中に設定を書き込む

ソースコード中で一時的に設定を行う方法

  • 良い点: プログラムの中で設定が完結し、他に影響を与えない
  • 悪い点: プログラムを書くたびにソースコード中に設定を記載しないといけない

開発環境なら解決法1が楽で良いが、プログラムをお客様に納品する場合などは解決法2が適しているだろう。

解決法1

こちらの記事と全く同じ方法なのでこちらを確認してほしい。
https://qiita.com/sidious/items/f9a6eaaf6b1786d6a92c

筆者の場合、openssl.cnfはこの記事の通り"/usr/lib/ssl"配下にあった。
ファイルの編集はviコマンドやnanoコマンドなどでできる。
分からなければ「Ubuntu ファイル編集」などで検索してほしい。

筆者はnanoコマンドが好みなのでそれを使う。

$ sudo nano /usr/lib/ssl

ファイルの冒頭に

openssl_conf = default_conf

を追加し、ファイルの末尾に

[ default_conf ]

ssl_conf = ssl_sect

[ssl_sect]

system_default = system_default_sect

[system_default_sect]
MinProtocol = TLSv1.2
CipherString = DEFAULT:@SECLEVEL=1

を追加する。
Ubuntu等の再起動は不要で、openssl.cnfを書き換えた直後からcurlコマンドが通るようになる。

解決法2

こちらの記事を参考にした。
https://blog.n-z.jp/blog/2020-12-18-dh-key-too-small-workaround-open-uri.html

細かいことは記事を確認してほしいが、要はソースコード中(openメソッド実行前)に

require 'net/http'
Net::HTTP.prepend Module.new {
  def use_ssl=(flag)
    super
    self.ciphers = "DEFAULT:!DH"
  end
}

を貼り付けることで解決できる。

このコードは、cipher(サイファー)の設定からDHを除外するという内容である。
open-uriからはこの設定変更ができないため、net/httpから変更する。

どうしてこのエラーが起こるのか

opensslのセキュリティ設定が強化されたからである。
(参考:https://github.com/openssl/openssl/commit/70b0b977f73cd70e17538af3095d18e0cf59132e)

opensslのバージョンが1.1.1になったタイミングでこの変更が適用され、暗号化に用いる鍵長がデフォルトで2048ビットとなった。
記事冒頭に示したエラー文は、SSL/TLSの暗号化で使われている鍵長が短すぎることを示しており、接続が弾かれている。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0