SSH(Secure Shell)は、リモートコンピューターと暗号化された通信を行い、コマンドを実行するためのプロトコルです。この接続では、双方向の確認が必要です。クライアントは接続したサーバーが期待したサーバーであるかを確認し、サーバーは接続したユーザーがログインする権限があるかを確認します。ユーザー公開鍵認証が成功したからといって、初めて接続したサーバーの身元まで確認されたとは限りません。
SSHでDockerソケットにアクセスする記事とMacリモートツール比較に続き、本稿ではサーバーホストキーを信頼するプロセスに焦点を当てます。特に、ssh-keyscanで収集したキーと独立して検証したキーを区別します。
例はすべて架空のlab-vm.exampleと図式用のキーA/Bです。A/Bは実際のSSHキーやフィンガープリントではありません。実際のサーバーに接続したり、認証キーを生成したり、以下のSSHコマンドを実行したりしていません。公式ドキュメントは2026年10月15日に確認しました。

AIで生成された概念イメージ。実際のSSH画面・キー・フィンガープリントや試験結果ではありません。
1. サーバーキーとユーザーキーは異なる質問に答える
サーバーホストキーはサーバーの身元を確認するために使用されます。クライアントが期待するホストの公開鍵と、接続相手が提示するキーの関係を確認します。ユーザー公開鍵認証では、ユーザーが該当する秘密鍵で認証できるか、その公開鍵が該当アカウントに許可されているかをサーバーが確認します。秘密鍵をサーバーにコピーする手順ではありません。OpenSSH認証とホストキー検証
클라이언트 ── 서버 호스트 키 확인 ──→ 기대한 lab-vm.example인가?
클라이언트 ── 사용자 공개키 인증 ──→ 이 사용자의 로그인을 서버가 허용하는가?
これをファイルの役割で分けると、より明確になります。
| 項目 | 主に誰が確認するか | 内容 | 答える質問 |
|---|---|---|---|
クライアントのknown_hosts |
SSHクライアント | 記憶または事前登録されたサーバーホスト公開鍵 | 今回のサーバーキーは期待した記録と一致するか? |
サーバーアカウントのauthorized_keys |
SSHサーバー | そのアカウントに許可されたユーザー公開鍵 | このユーザーキーで該当アカウントにログインできるか? |
一般的なユーザーごとのファイル以外に、システム全体のホストキーリストや他の認証設定も存在する可能性があります。本稿では、証明書・ホストCAがない単純なホスト公開鍵記録とユーザー公開鍵認証を基準とします。すべてのSSHディストリビューションがこれら2つのファイルのみで動作するという説明ではありません。
例えば、authorized_keysにユーザーの公開鍵が正しく登録されていても、クライアントが誤ったサーバーに初めて接続し、そのキーを信頼した場合、サーバーの身元確認の前提が誤っています。逆に、サーバーキーが一致してもユーザー公開鍵が許可されていない場合、ログインは失敗する可能性があります。これら2つの成功条件を別々に記録することで、原因を区別できます。

図:ホストキーとユーザー公開鍵の役割。公式ドキュメントに基づいて再構成された概念図であり、実際のキーや接続テストを示すものではありません。公式根拠1 · 公式根拠2
2. 初めて見たキーを保存することと、身元を検証することは異なる
初めて接続したlab-vm.exampleがキーAを提示したと仮定します。まだクライアントに記録がない場合、比較する基準もありません。このとき画面に表示されたフィンガープリントは、現在応答している相手の公開鍵を要約した値です。それが表示されたという事実だけでは、相手が運営者が準備したサーバーであるとは証明されません。
フィンガープリントは、長い公開鍵を照合しやすくするための識別表現です。期待するフィンガープリントを既に知っている場合、提示された値と比較できます。OpenSSHマニュアルも、サーバーのホスト公開鍵フィンガープリントを取得し、既知のフィンガープリントと一致するかを確認する手順を説明しています。ホストキーフィンガープリントの確認
ここで基準値を得る経路が重要です。著者の推奨は、検証しようとする新しいSSH接続とは別に、信頼できる管理コンソール、確認済みの運用担当経路、または事前に承認された配布記録を利用することです。同じ未確認の接続経路からキーと「正解フィンガープリント」を一緒に取得すると、独立した照合にはなりません。
キーAと信頼できる基準Aが一致する場合、その記録を該当対象に紐付けて管理できます。基準がない場合やA/Bが異なる場合は、まず対象と変更内容を確認します。図式のA/Bを実際のフィンガープリントの形に装飾して公開する必要はありません。
3. ssh-keyscanは収集ツールであり、信頼の出発点ではない
ssh-keyscanは、サーバーが提示するホスト公開鍵を収集するツールです。公式マニュアルは、収集したキーを検証せずにホストリストを作成すると、中間者攻撃のリスクが残ると警告しています。ssh-keyscan公式ドキュメント
以下は、架空の候補キーファイルを作成する未実行の例です。実際のサーバーやキーファイルを準備した実習ではありません。
# 未実行: 応答した相手のキーを別の候補ファイルとして収集する形式
ssh-keyscan -t ed25519 lab-vm.example > candidate-hostkeys.txt
# 未実行: 既に収集した候補ファイルのフィンガープリントを表示する形式
ssh-keygen -l -f candidate-hostkeys.txt
2番目のコマンドは、ファイルのキーをフィンガープリントとして表示するだけであり、ファイルの出所を認証するものではありません。ssh-keygenの-lはキーフィンガープリントを表示するオプションであり、この例では新しい認証キーを生成するコマンドとして使用されたものではありません。ssh-keygenオプション
既存の/589のCI接続例のように、収集結果をホスト記録に追加する動作を使用する場合でも、サーバーの身元確認には別途検証済みの基準が必要です。今回の続編が補完する部分は、収集 → 信頼経路の基準との照合 → 承認された記録の登録です。登録によって接続エラーが解消されたという事実と、キーの真偽確認は異なる結果です。
未検証の候補Bをすぐに「期待するキーB」として保存すると、その後の接続ではBが常に一致する可能性があります。記録が安定して維持されるという事実は、最初にBを信頼した判断が正しかったという証明にはなりません。
登録する基準と接続で観測した値を分離する
公開鍵は秘密の値ではないため、キー文字列が見えるという事実だけでは、サーバーがそのキーの秘密鍵を所有しているとは証明されません。実際のSSH接続は、サーバーが提示するホストキーとプロトコルの暗号学的証明を共に扱います。ssh-keyscan候補ファイルは、その接続検証を代替するログイン成功の証拠ではありません。OpenSSHホストキー確認
簡単な検討記録も3つの欄に分けると役立ちます。接続しようとする対象とポート、信頼された経路から得られた期待キー、実際の接続が提示したキーです。図式用のAとBが一致するモデルは、この比較の論理のみを表現します。実際の署名検証やDNS・経由サーバー構成まで試験したとは読みません。
4. accept-newが果たす役割の範囲を理解する
StrictHostKeyCheckingは、未知または変更されたホストキーをどのように処理するかを決定します。以下の表は、本稿で使用する単純なキー記録状況の説明です。追加の信頼構成や自動キー更新機能は別です。
図式で見ると、2つの状況は異なります。
기록 없음 + 제시 B + accept-new → B를 최초 기록으로 삼음
기록 A + 제시 B + accept-new → 변경으로 거절
自動化では、検証済みのホストキーリストを事前に提供する方法を検討できます。どの名前・ポート・接続経路のキーであるかも管理する必要があります。本稿でStrictHostKeyChecking=no、ホスト記録の無視、またはファイル全体の削除を接続失敗の一般的な解決策として提示しない理由は、確認しようとする基準そのものをなくしてしまうためです。
5. キー変更警告は、対象と変更理由から確認する
昨日記録したAと今日提示されたBが異なる場合、原因は一つに限定されません。計画されたサーバーの再インストール・キー交換、対象アドレスや接続経路の変化、予期せぬ相手などがすべて確認すべき仮説です。警告だけで侵害を確定することも、正常な変更だと断定することもできません。
著者の点検順序は以下の通りです。
- 該当接続を停止し、対象を確認します。入力した名前、ポート、エイリアス・経由設定が意図した対象であるかを確認します。
- 既存記録Aと変更警告を保存します。警告をなくすために
known_hosts全体を削除しません。実際の警告や識別値を公開記事にコピーしません。 - 信頼できる経路で変更理由と新しい基準を確認します。計画された交換であるか、該当対象が正しいか、キーの種類とフィンガープリントの照合基準が正しいかを確認します。
- 確認された範囲のみを更新します。Bを期待する新しいキーとする根拠が確保された場合、該当対象の記録のみを承認された手順で変更します。根拠が不足する場合は保留します。
- 再接続時に同じ基準で確認します。サーバーキーの確認結果とユーザーログイン結果を分けて確認します。
名前やポートごとに保存された記録を検索するオプションもあります。以下も文法説明用の未実行の例であり、この作業で実際にknown_hostsを読み取っていません。
# 未実行: 特定の対象の記録を検索する形式
ssh-keygen -F lab-vm.example
ssh-keygen -F '[lab-vm.example]:2222'
全体削除後にBが「新しいキー」として受け入れられるのは、警告があった問題を検証した結果ではありません。比較記録をなくし、最初の信頼問題に戻っただけです。安全な更新は、削除コマンドを最初に選ぶことではなく、変更されたキーを期待する根拠を最初に確保することです。
6. 実際の接続ではなく、合成ポリシーモデルで境界を確認した
添付のverify_ssh_trust_model.pyは、実際のOpenSSHではなく、キーA/Bという文字列で作成されたポリシーモデルです。外部接続・キー生成・フィンガープリント計算・実際の認証ファイル読み込みは行いません。
python3 verify_ssh_trust_model.py --output results.json
Python 3.9.6で8つの合成論理検査すべてが合格しました。未知のキーの拒否、初回キー自動記録の未検証状態、A→B変更の拒否、サーバーキーの一致とユーザー権限の独立性、収集値と信頼基準の不一致、検証済み基準の登録と既存記録削除の影響を検査しました。名前・ポートを分けて管理する仮想事例も含まれます。
このPASSは、モデルに記述された判断規則が例において一貫していることを意味します。SSHハンドシェイク、暗号学的署名、実際のフィンガープリント、またはユーザー環境での設定動作を検証した結果ではありません。読者の環境では、使用中のOpenSSHバージョンと信頼構成に合わせて別途確認する必要があります。
ログイン成功を判断する際には、質問を2つに保つと良いでしょう。期待したサーバーのキーであるという根拠があるか、そのサーバーがユーザーのログインを許可したか。暗号化された接続とユーザー公開鍵認証にサーバーの身元確認が加わることで、どの相手と通信しているのかを説明できます。
コメントを残す