最新のLinuxサーバーから古いLinuxサーバーにSSHで接続しようとしたら、エラーが表示され接続ができません。
原因は簡単です。サポートが切れサービス停止された技術を使っているからです。セキュリティが弱く、利用停止を推奨されているレガシー技術をわざわざ有効化する必要があります。
- 古いサーバーにSSHでアクセスできない
- 「no matching host key type found」エラーがでる
- 「error in libcrypto」エラーがでる
古くても動き続けるサーバーって色々不具合がでるので運用が面倒くさいです。だからと言って停止することも出来ないので文句をいいながら使い続けます。
古いサーバーにSSHでエラーが出力される原因
no matching host key type found が表示される経緯と説明
最近リリースされたLinuxサーバーから、古いLinuxサーバーにSSHで接続しようとするとエラーが出力される場合があります。
Unable to negotiate with x.x.x.x port 22: no matching host key type found. Their offer: ssh-rsa,ssh-dss
始めてエラーを見たときは、原因が直ぐにわからず、ネットワークやファイアーウォールを疑って調査をおこなってしまいました。最終的にたどり着いたのは「OpenSSH」そのものでした。
OpenSSHは署名にSHA-1のRSA鍵を利用していました。しかし、SHA-1は2005年に攻撃方法が発見された結果、2021年9月にリリースされたOpenSSH8.8で、SHA-1の鍵をデフォルトで無効化しました。
そのため、新しいOpenSSHクライアントから、SHA-1 RSA鍵を使っている古いサーバーに接続するとエラーが出力されるようになります。
error in libcrypto が表示される経緯と説明
RHEL 9 ベースの OS は、SHA-1 を使用した接続機能が禁止されています。OSでSHA-1を禁止している場合は、sshサービスでSHA-1を有効化しても接続することができません。
ssh_dispatch_run_fatal: Connection to x.x.x.x port 22: error in libcrypto
CentOS 5 や CentOS 6 は SHA-1 がデフォルトの暗号化ポリシーです。新しいOpenSSHクライアントから、SHA-1 RSA鍵を使ってリモート接続するとエラーが出力されるようになります。
SHA-1の鍵を有効化する(OS)これで直る
システム全体の暗号化ポリシーを確認する
私の環境はRHEL系 Rocky Linux を利用しています。AlmaLinuxも同様の設定になっていると思います。
RHEL 8 以降のOSは、アプリケーションに明示的に要求しない限り、ポリシーを満たさないアルゴリズムやプロトコルの使用を拒否します。
OpenSSLの設定ファイル「/etc/ssl/openssl.cnf (/etc/pki/tls/openssl.cnf)」に暗号化に関する設定が記述されています。
「.include = /etc/crypto-policies/back-ends/opensslcnf.config」
OpenSSLは、crypto-policiesパッケージを参照していることが分かります。
どのポリシーが適応させているか確認します。
# update-crypto-policies --show DEFAULT
システム全体の暗号化ポリシーは「DEFAULT」が判明しましたので、このポリシーにSHA1を追加する必要があります。
許可されている暗号化スイート等を確認したい場合は次のファイルを確認してください。
「/usr/share/crypto-policies/policies/DEFAULT.pol」
/usr/share/crypto-policies/policies/DEFAULT.pol
(抜粋)
hash = SHA2-256 SHA2-384 SHA2-512 SHA3-256 SHA3-384 SHA3-512 SHA2-224 SHA3-224 \
SHAKE-256 ⇐「SHA1」が無い
「DEFAULT」には「SHA1」関連の設定が除外されていることが分かります。
システム全体の暗号化ポリシーにSHA1を追加する
SHA-1 がデフォルトの暗号化ポリシーである古いサーバーへアクセスする場合は、明示的に有効化する必要があります。
SHA-1の有効化は設定ファイルを書き換えず、SHA1関連のモジュールを追加するだけで可能です。「/usr/share/crypto-policies/policies/modules」内に格納されている「SHA1.pmod」を利用します。次のコマンドを実行します。
# update-crypto-policies --set DEFAULT:SHA1 Setting system policy to DEFAULT:SHA1 Note: System-wide crypto policies are applied on application start-up. It is recommended to restart the system for the change of policies to fully take place.
システム全体の暗号化ポリシーの状態を確認します。
# update-crypto-policies --show DEFAULT:SHA1
システム全体の暗号化ポリシーが書き換わりました。設定変更は直ぐに反映しますので sshd サービスの再起動は不要です。
SHA-1の鍵を有効化する 2つの方法(sshd)
一時的な方法(引数を与える)
一番簡単で手軽な方法です。SSHで接続する際に引数でSHA1を有効化させる方法です。
# ssh -oHostKeyAlgorithms=+ssh-rsa -oPubkeyAcceptedAlgorithms=ssh-rsa [xxx.xxx.xxx.xxx]
接続するたびに引数を与える必要があるので面倒ですが簡単なので、頻度がない場合には有効な方法です。
恒久的な方法(設定ファイル)
設定ファイルにSHA1を有効化させるパラメーターを記入します。最初に設定したら次回からはエラーも出ませんので、おすすめな方法です。
~/.ssh/config に設定を記述します。もしファイルが無ければ新規作成してください。
Host * HostkeyAlgorithms +ssh-rsa PubkeyAcceptedAlgorithms +ssh-rsa
全ての宛先ホストでSHA1を有効化させる設定です。単一の宛先ホストのみ有効化させる場合は「*」を書き換えてください。
あとがき
2021年9月にリリースされた、OpenSSH 8.8は、SHA-1ハッシュアルゴリズムを使用したRSA署名を廃止しました。これ以降のバージョンではSHA-1の鍵を利用したものは利用できなくなっています。
ただ、SHA1を有効にするオプション設定があるので、古いサーバーにアクセスする場合はSHA1を有効化させる必要があります。