02:40 にアカウントがロックされ、キーボードの前には誰もいない。棚の上のクライアントが先月保存したパスワードを提示し続け、ゲートウェイはそれを拒否し続け、ロックアウトの背後にあるカウンターは人の関与なしに増えていく。これは攻撃ではなく再試行ループであり、アカウントを復旧できるようになる前に止めなければならない。

これを、決まった順序の二つの問題として扱い、まず送信元を止めてからアクセスを復元する。逆の順序では数分のうちにループが再開してしまう。

どのプロセスが失敗を送っているのかを特定する

ID システムのタイムスタンプから始め、アカウントを持つ各クライアントと突き合わせる。管理対象プロファイル、無人で動くサービス、引き出しの中のスマートフォン、古い認証情報が残った予備のノート PC は、いずれも同じ人物として認証しうる。数秒ごとに失敗するものがループであり、日に一度だけ失敗するものは通常、忘れた人間だ。どちらも同じカウンターを進めるところに罠がある。

確認するあいだ、拒否とゲートウェイへの到達不能を区別する。タイムアウト、名前解決の失敗、閉じたポートは通常は失敗カウンターを増やさないが、認証情報の誤りという結果を返す完了済みの認証交換はカウンターを増やす。両者を混同すると誤った対処になるが、片方はクライアントを止める必要があり、もう片方は経路を直す必要があるからだ。

対応を決める三つの条件

三つの事実が答えを一つに絞る。第一に、記録が明示的な拒否を示しているのか、転送の失敗を示しているのか。第二に、その ID が複数の端末やサービスで共有されているのか。第三に、再試行しているクライアントが自分が管理するものか、他人が管理するものか。

自分が管理する単一のクライアントからの明示的な拒否なら、そのクライアントを止め、承認された経路でロックを解除し、意図したログインを一度だけ行う。共有 ID の場合は、もう一方の端末が再接続した瞬間にループが再開するため、解除よりも払い出しに答えが傾く。転送の失敗はネットワーク層の問題であり、アカウント保護はそもそも論点ではない。

どの分岐も保護を弱めることにはならない。ロックアウトのしきい値やレート制限があるのは、障害時に煩わしいと感じるその信号が、パスワード総当たりを遅くする信号でもあるからだ。

ロック解除の前に送信元を止める

認証を続けているユニットまたは接続を止め、再起動しても戻らない形で止める。サービスの起動時自動開始が設定されている場合、クライアントを一時停止するだけでは足りない。

# which unit is presenting the credential?
journalctl -u openvpn-client@home --since '20 min ago' | grep -i 'auth\|error'

# stop it, and keep it stopped across reboots
sudo systemctl stop openvpn-client@home
sudo systemctl disable openvpn-client@home
systemctl is-active openvpn-client@home

数分待ち、失敗カウンターが動かなくなったことを確認する。その停止が、正しい送信元を見つけた証拠である。失敗が続くならループは別の場所から来ており、ロック解除の手順は無駄になる。

そのうえで初めて、事業者が文書化したロック解除または復旧の手順を使い、残すつもりの端末から管理されたログインをちょうど一度だけ行う。正確なしきい値、クールダウン期間、復旧の文言はサービスごとに異なるので、数字を推測せずに読むこと。

原因を取り除き、再発させない

保存された認証情報は、OS のキーチェーン、クライアントのプロファイル、サービスアカウントの設定のいずれか、所有されている場所で更新する。一か所で消したのに別の場所にコピーが残っていると、多くはオフラインだったノート PC が戻りキャッシュされた値を再生したときに、ループは一週間後に戻ってくる。

自動化には独自の ID を持たせる。専用に払い出したアカウントに固有の認証情報と固有の上限を持たせれば、マシンの障害が人間をメールから締め出すことはなくなり、ログでも障害を帰属できる。クライアントにバックオフを追加することで拒否された認証情報は再試行を繰り返さず停止し、さらに認証失敗の繰り返しにアラームを設定すれば、次のループは 02:40 ではなく数分で気づける。

レポートをサポートに送るときは、アカウント識別子、タイムスタンプ、クライアント名を残す。パスワードと復旧用の資料はその記録に含めてはならない。

関連記事