パスワードは正しいのに VPN ログインが失敗し、RADIUS サーバーは指示されたとおりに動いていたのかもしれません。ゲートウェイはおそらく Access-Challenge を受け取り、役立つものを何も表示せず、そのままタイムアウトするか、その応答を拒否と解釈しました。クライアント側からは、認証情報の誤りか壊れたトンネルに見えます。原因はたいてい、誰も記録していない会話の途中にあります。

一度のログイン、二度の RADIUS 交換

バックエンドが第二要素を求める場合、最初の要求に許可や拒否で答えるのではありません。コード 11 で応答し、利用者の次の応答を待ちます。ゲートウェイはそれを後続の要求で送り返さなければなりません。その後続要求は同じ認証会話に属し、新しいログイン試行ではありません。

正常な構成では、利用者に 二度目のプロンプトが表示されます。まずパスワード、次にワンタイムコード、あるいは運用担当者が文書化していれば 一つの統合プロンプトです。壊れた構成では 二度目のプロンプトが現れず、ログインは単に失敗します。

追うべき症状はこれで、クライアント側だけで簡単に確認できます。VPN クライアントが求める秘密がちょうど一つだけなのに、正しいと分かっているパスワードを拒否するなら、やり取りはチャレンジで終わった可能性が高いです。

チャレンジが実際に運ぶもの

RADIUS 仕様は 4.4 節でコード 11 を説明し、ここで重要な 二つの属性を認めています。Reply-Message は利用者向けのテキストを保持し、State はサーバーがそのまま返してほしい不透明な値を保持します。NAS は State を解釈せず、変更せずに返すだけです。

後続要求は新しい Identifier と新しい Request Authenticator を使い、同じ State 値と利用者の応答を運ばなければなりません。サーバーはその State によって保留中のチャレンジと突き合わせます。だから属性を作り直したり落としたりするゲートウェイはこの手順を完了できません。各応答の response authenticator も検証される必要があり、そうでなければ NAS はパケットを捨てるべきです。

4.4 節は、ほとんどの沈黙の失敗を説明する詳細を加えます。チャレンジをサポートできない NAS は Access-Challenge を拒否として扱います。ゲートウェイの VPN サービスがこのサポートより古いか省略しているなら、バックエンドの第二要素要求はプロンプトなしの即時の「認証失敗」になります。

連鎖した要求が失われる場所

最初の容疑者は認証情報ではなくプロンプトの経路です。Web ログイン用に OTP 欄を表示するポータルは、VPN サービスに対して自動的に同じことをするわけではなく、一部のゲートウェイは能力を通知するクライアントにしかチャレンジを渡しません。同じアカウントを両方の入口で試してください。ポータルが動いて VPN が動かないなら、見ているのは受け渡しであり、トークンではありません。

二番目の容疑者は入力形式です。ベンダーが文書化した区切り文字なしでパスワードとコードを連結したり、保存された認証情報に古いコードを再生させたりすると、誤ったパスワードとまったく同じに見える失敗になります。運用担当者が文書化した個別プロンプトか統合形式を使い、区切り文字を自分で考案しないでください。

リリース固有の不具合は存在しますが、何年も前の修正版の一覧は今日の配備に対する診断ではありません。実際に動かしているソフトウェアのリリースノートを読み、観察した交換段階を証拠として残してください。

一度の試行を最初から最後まで追跡する

サーバー側のデバッグを有効にして 一度再現し、他のセッションはすべてキャプチャの時間帯から外してください。

$ sudo radsniff -i eth0 -x -f 'udp port 1812'
$ sudo freeradius -X
$ radtest alice 'password' 127.0.0.1 0 testing123

出力では一行ではなく会話の形を探してください。Identifier 3 の最初の Access-Request、State を運ぶ Access-Challenge、次にその State を繰り返し利用者の応答を含む Identifier 4 の 二番目の Access-Request です。二番目の要求がなければ、ゲートウェイは決して後続していません。State なしで届いたなら、サーバーは保留中のチャレンジと一致させられず、通常は拒否します。

トレースを共有するときは認証情報、トークン、不要な身元データを伏せ、複数のブラウザータブの再試行を混ぜるのではなく 一度の試行のイベントを関連付けます。ここではタイムスタンプが味方です。クライアントが諦めた後に届くチャレンジは、利用者には拒否に、ログには遅い応答に見えます。

望む最終状態は、完了して認可された会話と、その後の意図したサービスアクセスです。RADIUS サーバーから応答が届いたことは、それよりはるかに少ないことしか証明しません。

関連記事