VPNクライアントを開き、パスワードを入力し、認証アプリの六桁を入れると無効だと返されます。二回、そして三回目も。アカウントは昨日から何も変わっていないので、認証アプリの登録を削除して再スキャンしたくなりますが、それはたいてい間違った修理です。ワンタイムコードは二つ目のパスワードではありません。ゲートウェイは特定のステップで、特定の登録済みエントリから、特定の時間枠の中でそれを要求する必要があり、ほとんどの拒否は数字が比較される前に起きます。登録に触れる前に、自分がどのステップにいるのかを突き止めてください。

プロンプトの順序で、どのフローにいるかがわかる

コードを伴うVPNログインは、ほぼ三つの形に収まります。二段階の形では、クライアントがパスワードを送り、サーバーがチャレンジを発行し、クライアントが再び問い合わせます。複合の形では、ゲートウェイがパスワードとコードを一度の送信で求めます。連結する場合もあれば、運用者だけが文書化している区切り文字の後に入れる場合もあります。ブラウザの形では、クライアントに入力欄がありません。コードはWebページに入力され、あるいはプッシュ承認がそれに代わり、デスクトップクライアントは結果を待ちます。

形を間違えると、悪いコードのように見えます。パスワード専用の欄に新しいコードを貼り付けると、サーバーはそれをパスワードの一部として読みます。クライアント側では、OpenVPN 2.4以降が違いを可視化します。AUTH_FAILED,CRV1: で応答するサーバーはチャレンジ応答を期待するので、プロファイルには static-challenge か SCRV1: 形式のパスワードファイルが必要です。auth-user-pass だけを持つ古いプロファイルはパスワードを認証した後に止まり、ログではOTPの失敗のように見えますが、コードは送られていません。

例外としてWireGuardを挙げておく価値があります。これは人ではなく鍵ペアを認証するので、コード用の欄がありません。プロバイダーがそのようなものを宣伝しているなら、トンネルの外の何かがそれを受け入れています。

サーバーは六桁をどう扱うか

時刻ベースのコードは RFC 6238 に従います。これはRFC 4226の古いカウンタベースの構成を包んだもので、移動要素に対するHMACを既定で六桁に切り詰めます。TOTPでは移動要素は現在のUnix時刻をステップで割ったもので、運用者が変更していなければ30秒です。検証側はあなたの数字を保存値と比較することはありません。共有シードから期待されるコードを再計算し、通常は隣接するステップも受け入れるので、遅い往復でログインが失敗することはありません。

見落とされがちな結果が二つあります。スマートフォンのタイムゾーンは無関係です。シードはローカル時計を決して見ず、実際のUTCからのずれだけが問題になります。二分進んだ端末は、きれいなカウントダウンを表示しながら、どのコードでも失敗します。そしてコードは設計上は一度限りです。検証側はそのシードに対して最後に受け入れたカウンタ値を覚えているので、同じ数字を再送すると同じ時間枠内でも拒否されます。タイムアウト後に再試行するクライアントは、たった今送ったコードを無駄にしかねません。

カウンタベースのトークンは押すたびにカウンタを進めるので、コードが生成されたのに送信されないままになると同期が外れます。通常の修理は、先のいくつかの値を受け入れる再同期の時間枠です。運用者がHOTPを登録したのにアプリがTOTPを表示していると、すべての値が時計の問題のように見える形で間違っています。QRコードの背後にあるプロビジョニングURIは、種類、桁数、周期、ハッシュを示します。

間違ったコードに見える失敗

最も多い原因は登録済みエントリです。認証アプリは発行者とアカウントでエントリにラベルを付けるので、同じVPNに二つの身元を持つ人は、ラベルが一文字だけ違う二つのエントリを持つことになります。コードはそれを生成したシードに対してのみ有効で、それ以外には無効です。スマートフォンのラベルは、サーバーが記録しているユーザー名と比べてください。自分が入力した記憶と比べてはいけません。

二つ目は一致しないパラメータの組です。八桁、60秒の周期、SHA-256で登録されたシードは、六桁、30秒、SHA-1を期待する検証側が拒否するコードを生成し、クライアント側ではそれを間違ったコードと区別できません。これは、QRコードの写真からエントリを追加し直した移行や、トークン記録を既定値で再構築した後に現れます。

三つ目はコードの話ではありません。ゲートウェイは通常、間違ったパスワード、期限切れのコード、無効化されたアカウントに対して、意図的に一つの一般的な認証失敗を返します。どの要素が失敗したかを誰も探れないようにするためです。クライアントのバナーではなく、ゲートウェイやRADIUSのログを読んでください。発行されなかったチャレンジ、OTP属性のないアクセス拒否、ポリシーによる拒否は、画面上では同じに見え、次の手順は異なります。

範囲を絞る短い手順

最も安価な確認から始め、成り立たない最初のステップで止めてください。

  1. 新しいコードを待ち、一度だけ送信し、チャレンジがパスワードの受理前と後のどちらに現れるかを記録します。
  2. 認証アプリのラベルを、サーバーが保存しているユーザー名と照合します。
  3. プロファイルがそもそもチャレンジに応答できるかを確認します。上の CRV1 の場合のように。
  4. 端末の時計を既知の時刻源と比較します。数十秒を超えるずれは、それだけでTOTPを壊します。
  5. トークンがTOTPかHOTPか、どの桁数・周期・ハッシュで登録されたかを運用者に尋ねます。

事態を悪化させないための二つのルールがあります。何度も再試行しないこと。多くのゲートウェイはアカウントごとに失敗を数え、ロックするか応答を遅らせ始めるので、連打は小さな設定ミスをサポートチケットに変えます。そして、診断のためにトークンを再登録しないこと。古いシードが無効になるからです。本当の不具合がクライアントの送らなかったチャレンジだった場合、変更は一つではなく二つになり、説明が難しくなります。

シードとリカバリーコードを輪の外に置く

六桁の数字とその背後の秘密は交換できません。プロビジョニング用のQRコードやBase32シードは、そのアカウントの将来のすべてのコードを生成するので、パスワードと同じ分類に入ります。スクリーンショットに残さない、チケットのコメントに書かない、先に連絡してきた相手とのチャットにも置かないこと。リカバリーコードは別の仕組みです。一度限りで、コード入力を完全に飛ばすことも多く、アカウントのテストに一つ使うと、後で必要になるかもしれない代替手段を失います。

コードがあってもログインページが信頼できるわけではありません。似たドメインのOTPプロンプトは有効なコードを集め、時間枠の中で再再生します。どこに入力しているかを教えるのは、今も証明書です。

手順がチャレンジに応答できないプロファイルに行き着いたら、プロファイルを直し、新しいコード一つで再テストしてください。一致しない登録パラメータに行き着いたら、誰かが何かをスキャンする前に、運用者にトークン記録を読んでもらってください。ロックアウトに行き着いたら、クライアントを変えるのではなく解除を待ってください。妨げになっているのはアプリではなく、アカウントの状態です。

関連記事