SASLは接続指向のプロトコルでの認証のためのフレームワークです。 現時点ではPostgreSQLは2つのSASLの認証機構、SCRAM-SHA-256とSCRAM-SHA-256-PLUSを実装しています。 将来には他の機構が追加されるかもしれません。 以下の手順は、SASLの認証が一般的にどのように行われるかを示したものですが、次の副節ではSCRAM-SHA-256とSCRAM-SHA-256-PLUSにおけるより詳細について説明します。
SASL認証のメッセージフロー
SASL認証の交換を開始するため、サーバはAuthenticationSASLメッセージを送信します。 これにはサーバが受け付けることができるSASLの認証機構を、サーバにとって望ましいものから順に並べたリストが含まれます。
クライアントはリストからサポートされる機構を1つ選択し、サーバにSASLInitialResponseメッセージを送信します。 このメッセージには選択された機構の名前が含まれ、また選択した機構がInitial Client Response(最初のクライアントの応答)を使用するなら、オプションでそれも含まれます。
サーバのチャレンジメッセージおよびクライアントのレスポンスメッセージが1つ以上続きます。 サーバのチャレンジはそれぞれがAuthenticationSASLContinueメッセージで送信され、それにクライアントからのレスポンスがSASLResponseメッセージで続きます。 メッセージの詳細は機構に固有のものです。
最後に、認証の交換が成功裏に終了すると、サーバはAuthenticationSASLFinalメッセージを送信し、その直後にAuthenticationOkメッセージを送信します。 AuthenticationSASLFinalにはサーバからクライアントへの追加のデータが含まれ、その内容は選択した認証機構毎に異なります。 完了時に送信する追加データを認証機構が使用していない場合、AuthenticationSASLFinalメッセージは送信されません。
エラーが発生したときは、サーバは認証を任意の段階で終了してErrorMessageを送信することができます。
今のところ実装されているSASL機構はSCRAM-SHA-256
とチャンネルバインディングを伴う変種のSCRAM-SHA-256-PLUS
です。
詳細はRFC 7677およびRFC 5802で説明されています。
PostgreSQLでSCRAM-SHA-256を使用する場合、クライアントがclient-first-message
で送信するユーザ名をサーバは無視します。
その代わりに、開始メッセージで送信済みのユーザ名が使用されます。
SCRAMはユーザ名としてUTF-8の使用を指示していますが、PostgreSQLは複数の文字符号化方式をサポートするため、PostgreSQLのユーザ名をUTF-8で表現できないかもしれません。
SCRAMの仕様ではパスワードもUTF-8であり、SASLprepアルゴリズムで処理されることが規定されています。 しかしPostgreSQLではパスワードにUTF-8が使用されることを必須としていません。 ユーザのパスワードが設定されたとき、実際に使用された符号化方式に関わらず、それがUTF-8であるかのようにSASLprepで処理されます。 しかし、それが正当なUTF-8バイト列でない場合、あるいはSASLprepが禁止するUTF-8バイト列を含む場合、エラーを発生させるのではなく、SASLprep処理のない生のパスワードが使用されます。 これにより、パスワードがUTF-8であればそれを正規化できる一方で、UTF-8以外のパスワードを使用することもでき、またシステムもパスワードがどの符号化であるかを知る必要もありません。
SSLをサポートするPostgreSQLビルドでチャンネルバインディングがサポートされます。
チャンネルバインディングを伴うSCRAMに対するSASL機構名はSCRAM-SHA-256-PLUS
です。
PostgreSQLで使われるチャンネルバインディングのタイプはtls-server-end-point
です。
チャンネルバインディングを伴わないSCRAMではサーバは、送信されるパスワードハッシュの中でユーザに応じたパスワードと混合してクライアントに送る乱数を選びます。 これはパスワードハッシュが後のセッションで再送信されて認証に成功してしまうことを防止しますが、真のサーバとクライアントの間の偽サーバがサーバのランダム値を中継して認証に成功してしまうことを防止しません。
チャンネルバインディングを伴うSCRAMはこのような中間者攻撃をサーバ証明書のシグネチャを送信されるパスワードハッシュと混合することで防止します。 偽サーバは真のサーバの証明書を再送信できますが、その証明書に一致する秘密鍵にアクセスできず、それゆえ所有者であることを証明できず、結果としてSSL接続は失敗します。
例
サーバはAuthenticationSASLメッセージを送信します。
それにはサーバが受け付けることができるSASL認証機構のリストが含まれます。
サーバがSSLサポート有でビルドされていれば、これはSCRAM-SHA-256-PLUS
とSCRAM-SHA-256
になり、そうでなければ後者のみとなります。
クライアントはSASLInitialResponseメッセージを送信することで応答します。
これは選択した機構、すなわちSCRAM-SHA-256
またはSCRAM-SHA-256-PLUS
を示します。
(クライアントは何れかの機構を自由に選びますが、より良いセキュリティのためサポートされているならチャンネルバインディングを伴うものを選ぶべきです。)
Initial Clientの応答フィールドでは、メッセージにSCRAMのclient-first-message
が含まれます。
client-first-message
にはクライアントが選んだチャンネルバインディングのタイプも含まれます。
サーバがAuthenticationSASLContinueメッセージを送信します。
その内容はSCRAMのserver-first-message
です。
クライアントがSASLResponseメッセージを送信します。
その内容はSCRAMのclient-final-message
です。
サーバがSCRAMのserver-final-message
を含むAuthenticationSASLFinalメッセージを送信し、その直後にAuthenticationOkメッセージを送信します。