SSHアーキテクチャ

パブリックキー認証

SSHは、パブリックキーとプライベートキーのペアでユーザーを認証するメカニズムを提供します。(1) ユーザーはプライベートキーを持っており、サーバーにパブリックキーを提供します。ユーザーがログインしようとすると、サーバーはセッション識別子を送信します。次に、クライアントはこのランダムなセッション識別子とパブリックキーを含むデジタル証明を生成して、秘密キーを持っていることを証明します。(2) サーバーが承認するパブリックキーのプライベートキーをユーザーが所有することを証明できる場合、ユーザーは認証されます。

この認証のメカニズムは、パスワードを使用するよりかなり安全であると見なされます。なぜなら、プライベートキーを推測することの難しさに比べ、パスワードの推測はかなり簡単だからです。(3, 4, 5)

ただし、パブリックキー認証は理想的ではなく、独自の課題を抱えています。1つは、事前に認証するために、サーバーにパブリックキーを認識させる必要がある点です。もう1つは、ユーザーがプライベートキーを保護する方法をサーバーが制御できない点です。ユーザーは、脆弱なパスワード、または完全に暗号化されていない(パスワードのない)プライベートキーでさえ自由に使うことができます。

証明書ベースの認証

証明書ベースのSSH認証は、基本的にパブリックキー認証を拡張した認証方法です。(6) ただし、証明書ベース認証の場合、サーバーは事前にパブリックキーを認識する必要はありません。代わりに、サーバーは、信頼のおける証明機関 (CA) の証明書で構成され、その証明書を使用して、クライアントのパブリックキーが信頼できるCAによって証明されていることを検証します。このようにして、ユーザーはパブリックキーと、そのパブリックキーに対応するプライベートキーを持っていることの証明との両方を、1つのステップで提示します。(パブリックキーは、プライベートキーを所有していることを証明するためにクライアントが署名するメッセージに含まれています。) この認証方法は、「通常」のパブリックキー認証よりも大幅に改善されています。なぜなら、サーバーが承認する必要のあるすべてのパブリックキーを事前に認識しておく必要がないからです。

ただし、まだ対処すべき課題がいくつかあります。具体的には、サーバーはその署名の継続期間中、署名されたキーを盲目的に信頼し、失効リストを同期したり、証明書を失効させることは簡単ではありません。さらに、使用されているプライベートキーを制御したり、これらのキーがどの程度保護されるかを制御することは実行されていません。例えば、ユーザーが自分のプライベートキーを公開Gitリポジトリにチェックインし、証明書の有効期間中、誰でもがそれを使用してログインできます。

アドバンストサーバーアクセスは、証明書ベースの認証を使用し、数分間で期限切れとなる証明書を使用して一時的な資格を発行することで、キーの管理と証明書失効の問題を解決します。発行したすべての証明書が数分以内に有効期限が切れ、自動的に「失効」するため、証明書失効リストは不要です。キーも一時的なものであり、一回しか署名されないものなので、ユーザーがわざわざ取得して、公開Gitリポジトリにコミットする場合、キーは数分以内に役に立たなくなります。

ホストキー認証

ユーザーの本人であるいう主張を認証することは明らかに重要ですが、接続するホストの信頼性を確認することも同様に重要です。(7) ユーザーが接続するホストを認証できない場合、世界中のユーザー検証は、いわゆる「中間者」 (MitM) 攻撃と呼ばれるもので容易にバイパスされます。(8, 9)

MitM

MitM攻撃は、セッションIDがキー交換アルゴリズム(10)を通じてネゴシエートされ、パブリックキーの認証には署名付きメッセージにセッションIDが含まれている必要があるという事実によってある程度防げますが(2)、このような攻撃は依然として可能です (例:ssh-エージェントを悪意のあるホストに転送した場合や、脆弱なKEXを使用した場合(11))。本質的に、ユーザーのクライアントはターゲットホストと信じて接続しますが、実際にはターゲットホストに見せかけたサーバーに過ぎません。この偽者ホスト (MitM) は、ユーザーの転送されたsshエージェントを不正に利用するか、または何らかの方法でターゲットホストとのネゴシエーションに既に使用された同じセッションIDを強制的に利用するなど、ユーザーとして認証するために可能なあらゆるメカニズムを使用します。MitMがいったんログインすると、あたかもユーザーが入力したかのように、あらゆるコマンドを送信するなど、プライベートキーを確認することなく、何でも実行できます。

SSHプロトコルには、ホストキー認証と呼ばれるこの問題に対するソリューションがあり、これは上記で説明したパブリックキー認証と基本的に同じですが、逆方向です。サーバーは、クライアントが認識しているパブリックキーに対応するプライベートキーを備えていることをクライアントに証明することにより、クライアントに対して自己認証します。このソリューションの問題点は、クライアントがパブリックキーを事前に知っておく必要がある点です。(証明書ベースの認証以前のパブリックキー認証と同様。)これに対する解決策として、証明書ベースのホストキー認証もopensshでサポートされていますが、クライアントマシンへの失効の取得は、サーバーの失効よりも信頼性が著しく低く、既に困難な問題でした。

すべてのホストにパブリックキーを交換する安全な既存のプロトコル外の機構を提供することで、アドバンストサーバーアクセスはSSHクライアントがターゲットホストを認証し、安全な接続を確立するために必要な、適正なホストキーを常に持つことを保証します。これにより、大半のSSHユーザーがホストに初めて接続するときに経験する、提示されたキーがそのホストで有効であることを盲目的に信頼する必要がある、いわゆる"Trust On First Use" (TOFU) 問題が完全に回避されます。

The authenticity of host 'web0.example.com (198.51.100.12)' can't be established. RSA key fingerprint is SHA256:v8SbZC97NSdqqj8rEJ+dvK7yh47ex53n8vVfW8Lf/G0. Are you sure you want to continue connecting (yes/no)?

アドバンストサーバーアクセスは、サーバーのパブリックホストキーをソースから直接取得した後、クライアントがそのパブリックキーで構成され、すべての段階でTLS上で安全に処理されていることを確認します。

アドバンストサーバーアクセス以前は、マシンの再イメージングを行うか、前のインスタンスと同一の名前で新しいインスタンスをスピンアップするときに、次のようなメッセージが表示されるのを受け入れていた可能性があります。

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!

アドバンストサーバーアクセスを使用すると、この警告はまれで意味のあるものになり、表示された場合は絶対に先に進むべきではありません。


  1. https://simple.wikipedia.org/wiki/Public-key_cryptography
  2. https://tools.ietf.org/html/rfc4252#section-7
  3. https://help.ubuntu.com/community/SSH/OpenSSH/Keys
  4. https://en.wikipedia.org/wiki/Password_strength
  5. https://en.wikipedia.org/wiki/Key_(cryptography)
  6. http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys?annotate=HEAD
  7. http://link.springer.com/chapter/10.1007/978-3-0348-8295-8_17
  8. https://www.giac.org/paper/gsec/2034/conducting-ssh-man-middle-attacks-sshmitm/103515
  9. https://www.blackhat.com/presentations/bh-usa-03/bh-us-03-ornaghi-valleri.pdf
  10. https://simple.wikipedia.org/wiki/Diffie-Hellman_key_exchange
  11. https://weakdh.org/