ARM5系 QNAP の wget で "Unable to establish SSL connection."


OpenSSL で alert handshake failure エラー

QNAP に SSH で接続して wget しようとすると以下のエラーでダウンロードできません。

[~] # wget https://*****.com/******_linux-arm.tar.gz
--2021-02-17 12:11:46--  https://*****.com/******_linux-arm.tar.gz
Resolving *****.com... XXX.XXX.XXX.XXX, ffff:ffff:ffff::ffff
Connecting to *****.com|XXX.XXX.XXX.XXX|:443... connected.
OpenSSL: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
Unable to establish SSL connection.

[~] # wget --version | head -n1
GNU Wget 1.16 built on linux-gnueabi.

どうも HTTPS でダウンロードする際の SSL handshake に失敗して SSL 接続が確立できないでいるようです。

  • 環境: QNAP TS-119P+ (v4.3.3.1432, 2020/10/06), Entware-std v1.03

TL; DR (今北産業)

  1. QNAP のデフォルトの wget のバージョンが古い。
  2. 認証局リスト(ca-certificates)が登録されていない。
  3. opkgwgetca-certificates をインストールして再ログイン後リトライしてください。

TS; DR (細かいこと)

--verbose --debug でエラーの具体的な内容を確認する

[~] # wget --verbose --debug https://*****.com/******_linux-arm.tar.gz
DEBUG output created by Wget 1.16 on linux-gnueabi.

--2021-02-17 12:32:58--  https://*****.com/******_linux-arm.tar.gz
Resolving *****.com... XXX.XXX.XXX.XXX, ffff:ffff:ffff::ffff
Caching *****.com => XXX.XXX.XXX.XXX, ffff:ffff:ffff::ffff
Connecting to *****.com|XXX.XXX.XXX.XXX|:443... connected.
Created socket 3.
Releasing 0xffffffff (new refcount 1).
Initiating SSL handshake.
SSL handshake failed.
OpenSSL: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
Closed fd 3
Unable to establish SSL connection.

上記の内容から、Connecting to ... connected. でソケット(443ポート)への接続まではできているものの、その後の証明書の相互確認(SSL handshake)が SSL handshake failed. で失敗していることがわかります。

そして、接続先が求めて来ている認証方式(プロトコル)が OpenSSL: 〜 routines:ssl3_read_bytes:sslv3 alert handshake failure により SSLv3 であることがわかります。

切り分け(試してみたこと)

--no-check-certificate で証明書を使わないで試してみる → NG

QNAP のアップデートは行っているのですがローカルの証明書が壊れているのかもと思い、危険なのですが --no-check-certificate で証明書を使わないで試してみました。

[~] # wget --no-check-certificate https://*****.com/******_linux-arm.tar.gz
--2021-02-17 12:20:14--  https://*****.com/******_linux-arm.tar.gz
Resolving *****.com... XXX.XXX.XXX.XXX, ffff:ffff:ffff::ffff
Connecting to *****.com|XXX.XXX.XXX.XXX|:443... connected.
OpenSSL: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
Unable to establish SSL connection.

失敗します。となると、証明書の問題ではなく認証方式なのかと踏んでみました。

--secure-protocol=SSLv3 で認証方式(プロトコル)を決めうちしてみる → NG

まずは、そもそも現在の wgetSSLv3 に対応しているのか確認する必要があります。

[~] # # 使えるプロトコルの確認(--secure-protocol)
[~] # wget --help | grep SSL            
HTTPS (SSL/TLS) options:
       --secure-protocol=PR        choose secure protocol, one of auto, SSLv2,
                                     SSLv3, TLSv1, TLSv1_1, TLSv1_2 and PFS
       --random-file=FILE          file with random data for seeding the SSL PRNG
       --ciphers=STR           Set the priority string (GnuTLS) or cipher list string (OpenSSL) directly.
                                   The format and syntax of this string depend on the specific SSL/TLS engine.
       --ftps-resume-ssl               resume the SSL/TLS session started in the control connection when

SSLv3 があるので大丈夫そうです。しかし、プロトコルを決めうちしてもダメでした。デフォルトで auto なので SSLv3 が選ばれていたようです。

[~] # wget --secure-protocol=SSLv3 https://*****.com/******_linux-arm.tar.gz
--2021-02-17 12:24:04--  https://*****.com/******_linux-arm.tar.gz
Resolving *****.com... XXX.XXX.XXX.XXX, ffff:ffff:ffff::ffff
Connecting to *****.com|XXX.XXX.XXX.XXX|:443... connected.
OpenSSL: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
Unable to establish SSL connection.

となると、振り出しに戻って「証明書の問題」に絞ってみます。

ca-certificates を入れてみる → NG

証明書は壊れていないと過程すると、次に考えられるのが「そもそも必要な証明書が入っていない」パターンです。

つまり、証明する先がわからないので「接続先が発行した公開鍵が正しいものであるかを証明するデータがない」ケースです。この証明を行うのが CA と呼ばれる認証局です。

しかし Docker のイメージなどではよくあるのですが、必要最低限の認証局のみで、主要な認証局が追加されていないことがあります。その場合にハンドシェイクが失敗することが、まれによくあります。ダウンロードした接続先の公開鍵が正しいものであることを確認したくても、肝心の認証局がわからないからです。

一般的には、パッケージマネージャーなどで ca-certificates パッケージで最新の主要な認証局一覧を取得・更新します。

そこで QNAP で使えるパッケージマネージャーの opkg コマンドで、ca-certificates がインストールできるか確認します。(opkg コマンドは別途インストールが必要です

パッケージの検索と確認
[~] # # パッケージの検索
[~] # opkg find ca-certificates
ca-certificates - 20200601-1 - System CA certificates

[~] # # パッケージ情報の確認
[~] # opkg info ca-certificates
Package: ca-certificates
Version: 20200601-1
Depends: libc, libssp, librt, libpthread
Provides: ca-certs
Status: unknown ok not-installed
Section: base
Architecture: all
Size: 125728
Filename: ca-certificates_20200601-1_all.ipk
Description: System CA certificates

幸いなことに ca-certificates パッケージは提供されているようです。

パッケージのインストール
[~] # opkg install ca-certificates
Installing ca-certificates (20200601-1) to root...
Downloading http://bin.entware.net/armv5sf-k3.2/ca-certificates_20200601-1_all.ipk
Configuring ca-certificates.

しかし、残念なことにダウンロードできませんでした。

ca-certificatesを入れた状態でwget
[~] # wget https://*****.com/******_linux-arm.tar.gz
--2021-02-17 12:24:04--  https://*****.com/******_linux-arm.tar.gz
Resolving *****.com... XXX.XXX.XXX.XXX, ffff:ffff:ffff::ffff
Connecting to *****.com|XXX.XXX.XXX.XXX|:443... connected.
OpenSSL: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
Unable to establish SSL connection.

そうなると、次に考えられるのが wget のバージョンです。

現在の wget のバージョンは v1.16 で 2014 年のものです。2021/02/17 現在、GNU wget v1 系の最新は v1.21です。これは、SHA-1 や MD5 の脆弱性が指摘される前の古いバージョンで、いささか古いバージョンすぎると思い、なるべく新しい wget のバージョンにしてみました。

wget を更新してみる → OK

opkgwget があったので、インストールしてみました。

opkgでwgetをインストール
[~] # opkg install wget
Installing wget (1.20.3-4) to root...
Downloading http://bin.entware.net/armv5sf-k3.2/wget_1.20.3-4_armv5-3.2.ipk
Configuring wget.

QNAP 同梱(デフォルト)の wget とは別の場所にインストールされるためパスが変わる(環境変数の PATH に追加される)ので、ログインしなおして反映させます。

wget のバージョンは最新ではありませんが、比較的新しい安定版の v1.20.3 がインストールされました。

wgetのバージョン確認
[~] # wget --version | head -n1
GNU Wget 1.20.3 built on linux-gnu.

今度は、ダウンロードも正常にできました。

wgetで再度ダウンロード
[~] # wget https://*****.com/******_linux-arm.tar.gz                 
--2021-02-17 15:14:00--  https://*****.com/******_linux-arm.tar.gz
Resolving *****.com... XXX.XXX.XXX.XXX, ffff:ffff:ffff::ffff
Connecting to *****.com|XXX.XXX.XXX.XXX|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 21087228 (20M) [application/gzip]
Saving to: '******_linux-arm.tar.gz'

******_linux-arm.tar.gz                          100%

逆に、ca-certificates のインストールが不要なのかと思い opkg remove ca-certificates でアンインストールしてみましたが、エラーが再発したので、wget のアップデートと ca-certificates のインストールが必要、と言う結論になりました。