VPC への VPN は機能するが、マネージドサービスがタイムアウトする
トンネルは自社のエッジで終わり、プロバイダーの玄関では終わらない。ルートを変える前に、対象が VM 上か、VPC 接続か、公開のみかを分類する。
VPN 経由でマネージドデータベースに到達できないとき、原因はたいていランブックに書かれていないところにある。トンネルは自分のネットワークのエッジで終わっているのに、サービスはそもそもそちら側には置かれておらず、ルートテーブルは正しく見え、トンネルは稼働中と報告するのに接続はタイムアウトする。以下の四つの確認を順に行い、合格条件が満たされない最初の確認で止めるのは、それ以降の確認が前の確認の成立を前提としているからだ。
確認一:エンドポイントは実際どこにあるのか?
VPN ゲートウェイは、自分がアドレスを管理する二つのネットワークをつなぐ。マネージドサービスはプロバイダー自身の玄関の内側で運用されており、その玄関は製品によって三つの形のいずれかを取る。どの形を相手にしているのか分からなければ、障害がルーティングの障害とは限らないため、どれだけルートをいじっても解決しない。
| Shape | What it means | Pass condition |
|---|---|---|
| Software on your VM | Ordinary subnet addressing | Route and security group permit the client |
| Attached to your VPC | Private, but only inside that VPC | Endpoint associated, source allowed, route present |
| Provider-hosted, public endpoint | Optional private link, not private by default | A private endpoint exists and DNS points at it |
無駄にした午後のほとんどは、この分類を飛ばしていきなりルートテーブルへ向かうことから生じる。公開エンドポイントを持つプロバイダー側ホストのサービスは、図がどう言おうと自分のトンネルの内側にはなく、VPC 接続のサービスは公開 DNS の応答に決して現れない。
確認二:ElastiCache のような VPC 接続サービス
この種のキャッシュは自分の VPC 内でアドレス指定され、インターネット向けのリスナーを一切持たない。同じ VPC で終端するクライアント VPN からは到達できるが、それは三つの条件が同時に揃ったときだけだ。キャッシュのエンドポイントがトンネルから見えるサブネットに関連付けられていること、そのセキュリティグループがクライアントの送信元アドレスを許可していること、クライアント側にキャッシュのサブネットを覆うルートがあることが必要になる。
よくある誤りは、近くのどこかにつながっていれば十分だと考えることだ。VPN を別の VPC に接続したり、ピアリングだけに頼ったりしても、キャッシュのセキュリティグループやそのサブネットのルートテーブルがクライアントまで広がるわけではない。既存のトンネルが別の場所で終わっている場合、その VPC の中に置いたジャンプホストや VPN サーバーがよく使われる代替になる。その代替は設計ではなく回避策であり、ランブックでもそのように記すべきだ。
確認三:公開名を持つ PaaS エンドポイント
Azure Database for PostgreSQL は公開のサーバー名を提示する。hosts ファイルに固定してゲートウェイ経由でルーティングできるようなプライベートアドレスは渡してくれない。仮想ネットワークのサービスエンドポイントは、どのサブネットがリソースに到達できるかを制限するものであり、VPN 経由で来るオンプレミスのクライアントを許可するものではない。
プライベートアクセスを得るには、プライベートエンドポイントやプライベートリンクの設計を導入し、そのうえでプライベート DNS ゾーンを追加して、公開名がインターネットではなくそのエンドポイントで応答するようにする。VPN とサービスエンドポイントの規則を組み合わせたものは別のアーキテクチャであり、図の上でだけ似て見える。App Service は同じ論理を逆方向からたどり、VNet 統合はアプリが VNet へ外向きの呼び出しを行うことを可能にするが、トンネルからの内向きのプライベート経路は作らない。したがって内向きのプライベートアクセスには、プライベートエンドポイント、App Service 環境、またはアプリの手前に置くゲートウェイが必要で、どれを使えるかはプランによって変わる。
確認四:独自の玄関を持つ製品
Firebase Hosting は Cloud VPN に接続できない。ホスティング層がプロジェクト VPC の内側の何かではなく、グローバルなフロントエンドだからだ。文書化された代替は、プロキシインスタンスやバケットに支えられたロードバランサーを使って、制御された入口を自分で作ることだ。いずれにせよサイトは純粋なホスティング製品ではなくなり、自分が運用するインフラになるが、その取引はトンネルがそれを覆うと誰かが約束する前に明言しておく価値がある。
Private API Gateway は VPC サービスの側に近く、interface 型の VPC エンドポイントは応答がプライベートアドレスになるホスト名を公開し、拠点からのトラフィックはトンネルまたは専用の相互接続を通って届く。エンドポイントは API に関連付けられている必要があり、証明書とホスト名は呼び出し側が使うカスタムドメインと一致していなければならない。
Google Cloud VPN のトンネルは名前ではなくピアの IP アドレスに結び付く。DNS 転送は別に構成するため、トンネルが完全に健全でも、リモートのプライベートゾーンでの名前解決は失敗し続けることがある。
次に境界を特定する
VPC 内の VM から同じ接続を実行し、そこで成功して VPN クライアントから失敗するなら、隙間はクライアントの経路とサービスのエンドポイントの間にある。ルート、セキュリティグループ、エンドポイントポリシー、あるいは名前だ。両方の試行が失敗するなら、そのネットワークのどこからもサービスに届いておらず、VPN は最初から障害ではなかった。
getent hosts db.internal.example
nc -vz db.internal.example 5432
名前解決とポート確認は、失敗する理由が異なりこの二つを並べれば経路のどちら半分が壊れているか分かるため、別々に行う。公開アドレスに解決される名前は、プライベート DNS ゾーンが効いていないことを示している。