AWS Client VPN エンドポイントの DNS: 解決済み IP を固定すると失敗する理由
AWS Client VPN エンドポイントの名前を解決したアドレスに置き換えると、後でトンネルが動かなくなります。エクスポートされた名前とそのランダムな接頭辞を保ってください。
先週、dig +short が AWS Client VPN プロファイルのエンドポイント名に対して一つのアドレスを返し、トンネルは接続しました。今週、同じプロファイルはノート PC で「Connecting」のまま止まり、同僚の手を加えていないコピーはまだ動いています。何もブロックされておらず、証明書も失効していません。誰かがエンドポイントのホスト名をその解決済みアドレスに置き換えたため、サービスはそこでは応答しなくなりました。エクスポートされた名前は、その変化に耐えるために作られた部分です。
プロファイルの名前は、問い合わせられている名前ではないかもしれません
Client VPN からエクスポートされたプロファイルには、たいてい remote-random-hostname が含まれています。このオプションが有効だと、クライアントは使い捨てのラベルを作り、ドットでエンドポイント名につなぎ、合成した名前を解決します。エンドポイントのゾーンのワイルドカードレコードがどのラベルにも応答するため、でっち上げた接頭辞でも解決し、手作業でクエリを再現しようとしてもこの仕掛けは見えません。
つまり、エンドポイント名をターミナルに貼り付けて答えが返っても、クライアントが接続時に使う名前とは別の名前を解決しているのです。この食い違いはプロファイルで直すべき欠陥ではありません。ラベルは意図的に作り直されます。このオプションはキャッシュが古い答えを保持するのを防ぎ、あなたのマシンやセッションを識別することは決してありません。
クライアントがこのオプションを完全に無視する互換性の事例にも出会いました。AWS は回避策を文書化しています。実際のエンドポイント名を保ち、その前にランダムな文字列とドットを付けるのです。貼り付ける値ではなく命名パターンとして扱います。古いクライアントに適用するのは妥当ですが、接頭辞付きの文字列をエンドポイントとして固定するのは妥当ではありません。
保存した答えが正しいままでいられない理由
Client VPN のエンドポイントアドレスは AWS が管理し、時間とともに変わります。ベストプラクティスの文書も明言しています。取得した答えは一回の解決のスナップショットです。それを固定したプロファイルは、サービスが移った瞬間に廃止されたホストを狙うプロファイルになり、障害は DNS らしく見えません。接続タイムアウトや止まったハンドシェイクになり、人はルーティングや証明書を追いかけます。
/etc/hosts の同じ答えも同じ失効を引き継ぎ、さらに問題が増えます。hosts の項目は再起動、再エクスポート、「クライアントを再インストール」の修正を生き延びるので、アドレスが移るたびに障害が戻ります。何週間も無害に置かれ、その後それを載せたすべてのマシンを止め、新しいインストールは普通につながった例を見ました。同じアカウントで一方のグループが失敗し他方は正常というこの分裂が、最も安上がりな手がかりです。
ランダム化の範囲も正しく押さえます。これは接続の試行ごとに起きます。確立したトンネルはエンドポイントを再解決せず、セッションの途中でサーバーを切り替えず、個々のアプリケーション要求がそれぞれ新しい VPN ホストを選ぶわけでもありません。次の試行だけが再び解決するので、午後じゅう動くセッションも翌朝の保証にはなりません。
トンネルが上がるときにサービスが確認すること
Client VPN は、接続しているアドレスがエンドポイントの DNS 名に対して解決されたアドレスと一致することを求めます。この一つの要件が、無関係に見えるいくつもの障害を説明します。別の場所を指す独自の DNS レコード、実際のエンドポイントアドレスへ転送する独自のフロントエンド、生のアドレスに書き換えたプロファイルです。AWS は独自レコードと転送の組み合わせを、新しい AWS 提供クライアントでの障害として文書化しています。検査は狭く、すべての別名を禁じる判断ではありません。
VPN プロトコル一般の規則でもありません。数値の remote は普通の OpenVPN 配備で完全に有効で、多くがそう動いています。制約は管理された仕組みから来るのであって、その下のプロトコルからではありません。
だから証明書検証を緩めるのは誤った反射です。アドレス交換の後にプロファイルが失敗したとき、サーバー検証を切ると解決やアドレス一致の要件を直す代わりにエラーを移すだけで、何でも信じるクライアントを残します。エクスポートされた CA、サーバー検証、相互認証の設定は届いたままに保ってください。
許可リスト、外向け通信、プライベート DNS は三つの別問題
ノート PC が接続する前に宛先を許可しなければならないファイアウォール規則は、外側のリスナーに関するものです。ネットワークの所有者にエンドポイント名、トランスポート、設定されたポートを渡し、その制御がサービスの DNS の振る舞いを追えるか尋ねます。取得した一つのアドレスを保持する規則は、書かれていない失効を持つスナップショットです。制御が不変の宛先しか受け付けないなら、黙って答えを固定するのではなく、展開前にその隙間を埋めてください。
トンネルが上がった後の要求に固定の送信元アドレスを必要とする相手には、別の要件があります。外向けの通信です。ウェブサイトが見るものはアプリケーションの経路と分割トンネルの方針で決まり、クライアントが接続したアドレスでは決まりません。分割トンネルの通信は AWS にまったく触れないこともあります。
トンネル内のプライベート DNS は第三の層です。クライアントに渡されるリゾルバーは接続後に内部名へ答え、トンネルができる前に公開エンドポイントを解決することはできません。エンドポイントの解決失敗と内部アプリケーションの解決失敗は別の段階で起き、混ぜると間違ったログへ導かれます。
アドレスファミリーも同じ一覧に入ります。IPv4 の答えは IPv6 やデュアルスタックのエンドポイントで許される経路について何も語らないので、一方のファミリーで取ったスナップショットは他方の証拠になりません。
何も固定せずに接続を確認する
エクスポートされたままのプロファイルから始め、実際に何を求めているかを読みます。
grep -nE '^remote|remote-random-hostname' profile.ovpn
dig +short cvpn-endpoint-ID.prod.clientvpn.REGION.amazonaws.com
ss -tnp | grep -E ':(443|1194)'次に三つを比べます。プロファイルが持つエンドポイント名、新しい試行のためにクライアントが報告するアドレス、そして名前が今どこへ解決するかです。解決する名前はレコードが応答する証拠にすぎません。トランスポートと認証は別で、エンドポイントが ping に応答する必要もありません。真ん中の項目の唯一の出所はクライアント自身のログなので、試行の後にではなく試行の間に取得します。
| What you see | Usual cause | Next check |
|---|---|---|
| One machine fails, others connect | Pinned address or stale hosts entry on that machine | Diff its profile and hosts file against a working copy |
| Everyone fails at once, no config change | The endpoint address rotated | Confirm the current endpoint configuration with the account owner |
| Tunnel up, internal names fail | Client DNS policy, not endpoint resolution | Inspect the resolver pushed after connection |
今日応答するアドレスは今日についての証拠です。名前こそがサービスが有効に保つものです。観察を記録し、エンドポイントを所有する人へ送り、プロファイルは名前を指したままにします。
やめるべき習慣が二つあります。止まったハンドシェイクを抜けるために証明書検査を切ること、そして一つでも残ればとエンドポイント名の前にラベルを積むことです。ラベルはワイルドカードレコードで解決するか、問題は別の場所にあります。正しく設定したプロファイルがそれでも失敗するなら、より長いホスト名ではなく、正確なクエリと接続イベントを送ってください。
閉じる前に確認します。プロファイルはエクスポートされたエンドポイント名を保ち、hosts ファイルはアドレスを固定せず、クライアントログの remote は現在の解決と一致し、ファイアウォール規則はアドレスではなくエンドポイントを示しています。これが次の人に渡す状態でもあります。