SSH接続拒否の朝、「新しい鍵」の正体をfingerprintで暴いた
SSH接続拒否の朝、「新しい鍵」の正体をfingerprintで暴いた
結論から言う。
SSHの鍵ファイルは、名前や見た目だけでは同一性を判断できない。
比べるべきは、鍵のfingerprint(公開鍵から計算した短い識別値)だ。
秘密鍵の中身を画面に出さずに、新旧の鍵が同じかどうかを確認できる。
しろまえ殿の現場では、この一手間を踏まずに「新しい鍵」を追いかけて、色クルーたちが遠回りをしたことがあった。
拒否から始まった調査
ある接続先へSSHで入ろうとしたところ、Permission denied (publickey) が返ってきた。
公開鍵認証で、サーバーに受け入れてもらえなかったという意味だ。
色クルーはまず、鍵ファイルから公開鍵を導出してみた。
ssh-keygen -y -f ./candidate-key > /tmp/candidate-key.pub
-y は、秘密鍵から公開鍵を取り出す指定だ。
ここでエラーにならなければ、少なくとも鍵ファイルを読み取れる状態だとわかる。
「別ファイル」なのに、開く扉は同じだった
次に、鍵のfingerprintを表示した。
ssh-keygen -lf ./candidate-key
-l はfingerprintの表示、-f は対象ファイルの指定だ。
過去に試した鍵でも同じコマンドを実行し、表示されたSHA256 fingerprintを見比べる。
たとえば、同じ家の合鍵でも、金属の形を紙に写したものと専用ケースに入れたものでは見た目が違う。
しかし、開く扉が同じなら、鍵としての正体は変わっていない。
今回もそうだった。
ファイルのヘッダーと保存形式は、たしかに違っていた。
一方は従来形式、もう一方はOpenSSH形式。
それでもfingerprintは一致した。
ファイルは別物でも、鍵ペアは同一だった。
「新しい鍵」と呼ばれていたものは、形式を変えて保存し直しただけのものだった。
色クルーたちの間に、拍子抜けと安堵の混じった空気が流れた。
接続ログで、確認範囲を切り分ける
もっとも、fingerprintの比較だけで、サーバーへの接続可否がすべて説明できるわけではない。
鍵ファイルが読めることと、サーバーがその公開鍵を登録していることは、別の確認だ。
詳細ログを有効にして接続すると、どこまで進んだかがわかる。
ssh -v -i ./candidate-key user@example.invalid
-v は詳細ログを出す指定だ。
ネットワーク接続、ホスト鍵の交換、公開鍵の提示まで進んだ後に拒否されているなら、通信経路より認証情報の登録を疑う。
たとえば、受付まで荷物が届いているのに入館できないなら、疑うべきは配送ではなく受付名簿だ。
SSHでも同じように、クライアント側の鍵が正常か、サーバー側の公開鍵登録が正しいかを分けて見る。
読者へ:安全な照合の順番
同じ状況に遭遇したら、次の順番で確認するとよい。
まず、秘密鍵の中身を画面へ出さずに、過去の鍵と候補のfingerprintを取得する。
ssh-keygen -lf ./old-key
ssh-keygen -lf ./candidate-key
次に、サーバー側のauthorized keys(ログインを許可する公開鍵の一覧)に登録された公開鍵のfingerprintを、管理画面や管理者の確認手順で照合する。
新旧の値が一致し、サーバー側の値と一致しないなら、形式変換ではなく別の鍵ペアを用意する必要がある。
新しい秘密鍵を作る場合は、秘密鍵を共有せず、対応する公開鍵だけを登録する。
ファイル名、拡張子、ヘッダーだけで「新しい」と判断しないことが重要だ。
指紋を使えば、秘密情報を公開せずに同一性を客観的に示せる。
「また拒否された」で止まっていた調査が、どの鍵を登録し直すべきかという具体的な依頼に変わった。
見た目ではなく、fingerprintを照合する。
その一手が、鍵トラブルの迷路から色クルーたちを抜け出させた。