VGW か TGW か。AWS Site-to-Site の IPsec トンネルはどこで終わるのか
IPsec トンネルが終わるのは VGW か TGW の VPN アタッチメントであり、インスタンスではありません。三つの端点を名指しし、残る各ホップを何が守るのかを確認します。
AWS Site-to-Site VPN がパケットを守らなくなる場所を尋ねると、人は「ゲートウェイで終わる」という単一の答えを期待します。役に立つのはその答えのうち「どのゲートウェイか」を名指しする版です。仮想プライベートゲートウェイとトランジットゲートウェイは別のアタッチメントオブジェクトを持つ別の構成であり、誤ったほうを前提にしたレビュアーは、存在しない図の上に評価の残りを組み立ててしまいます。以下の三つの確認を順に行えば、どれも境界を確定するか、前の答えが別のリソースの話だったと教えてくれます。
何かを評価する前に三つの端点を名指しする
この経路の暗号化レビューには、カスタマーゲートウェイ、IPsec を終端する AWS VPN ターゲット、内側のパケットを受け取るアプリケーションの端点という、名前を付けた三つのものが必要です。コンソールのページを一枚も開く前に、ここから先の議論はすべてその三つのどれかについての主張になるのだから、リソース識別子とともに書き留めてください。
カスタマーゲートウェイはあなたのもので設定も見えますが、AWS 側のターゲットはマネージドリソースであり、これを前提にしてしまうのが誤りです。VPN 接続は仮想プライベートゲートウェイにも、トランジットゲートウェイに直接にも接続でき、どちらか一方が他方を意味しません。三つ目の端点は見落とされがちですが、アプリケーションデータについての本当の問いに答えるのはこれだけです。
確認 1: 実際にトンネルを終端するのはどのゲートウェイか
どちらの構成もサポートされており、 Site-to-Site VPN のアーキテクチャガイド が両者を並べて説明しているので、一年前の図ではなく API に問い合わせてください。一つの接続に対する読み取り専用クエリは VPN ターゲットのフィールドを返します:
aws ec2 describe-vpn-connections --region eu-west-1 --vpn-connection-ids vpn-0123456789abcdef0 --query 'VpnConnections[0].{VGW:VpnGatewayId,TGW:TransitGatewayId,CGW:CustomerGatewayId,Category:Category}'
判別に使うのは TransitGatewayId であり、VpnGatewayId ではありません。TransitGatewayId が空の接続は単独の仮想プライベートゲートウェイで終端し、このフィールドが設定された接続は トランジットゲートウェイの VPN アタッチメントで終端しますが、その場合でも VpnGatewayId はアタッチメントの土台となるゲートウェイを指せるため埋まっていることがあります。そのトランジットゲートウェイ上の VPC アタッチメントは VPN アタッチメントではないので、まず TGW のフィールドを読み、次にアタッチメントの種別をフィールド名ではなくアタッチメント一覧で確認してください。接続済みの VPC で宛先インスタンスを見つけても、どの VPN アタッチメントがパケットを運んだかは分かりません。
ついでにトンネルも確認します。接続は冗長化のために二本の IPsec トンネルを持ち、二本目が一度も上がっていない接続は、暗号化の境界を何も変えないとしても、可用性の観点で実際の指摘になります:
aws ec2 describe-vpn-tunnels --region eu-west-1 --filters Name=vpn-connection-id,Values=vpn-0123456789abcdef0 --query 'VpnTunnels[].{Outside:OutsideIpAddress,State:State,Status:Status}'
確認 2: 内側のパケットは何をまだ運んでいるか
IPsec が終わると AWS はカプセル化を解いたパケットをそれに一致したルートで転送し、そこから先のトラフィックは通常の VPC トラフィックになって VPN の保護は終わっています。これはサービスの穴ではなく、境界の意味がそういうことであり、チェックリストの項目は、それをはっきり書くことです。「VPN は暗号化されている」に「データは端から端まで暗号化されている」を代弁させないことです。
次に内側が何だったかを見ます。内側のパケットが平文のアプリケーションプロトコルなら、別の何かが暗号化するまで、下流で機密性は加わりません。内側のパケットがすでに TLS セッションを運んでいるなら、外側の IPsec を取り除いてもそのセッションは変わらず、自分自身の端点まで守られたままであり、端点がどこにあっても同じです。
よくある過剰修正は、ゲートウェイの背後はすべて露出していると結論することですが、そうではありません。サービスの転送、ストレージの暗号化、アプリケーションの TLS はそれぞれ別の条件を持つ別の仕組みであり、VPN の形から推測するのではなく、それぞれの条件で評価する必要があります。ACCEPT を示すフローログの記録は、ルーティングが機能したことの証明であり、機密性については何も語りません。このチェックリストはまさにその誤りを防ぐためにあります。
確認 3: ゲートウェイの背後で TLS を終端するのは何か
住所ではなくリスナーを追うと、ロードバランサーやプロキシが TLS を終端するなら、クライアントが持つ接続はそこで終わり、プロキシはバックエンドへ二本目の接続を開きます。その接続は平文かもしれませんし、別の信頼チェーンを持つ TLS かもしれません。プライベート IP アドレスと一致するルートは、その二本目の接続の証拠にはなりません。
本当に重要な端点を、VPC の内側から、一度だけ名前解決した IP ではなくアプリケーションが使う名前で試験してください:
openssl s_client -connect internal.example:443 -servername internal.example -verify_return_error
リクエストが通る各ホップについて同じことを繰り返します。クライアント向けの名前とバックエンドの名前で答えが違うなら、VPN が決して覆わなかった区間を正確に見つけたことになり、それが書き留めるべき指摘です。
結果は判定ではなく区間として記録する
このチェックリストの出力は、カスタマーゲートウェイから AWS VPN ターゲット、ゲートウェイからワークロード、ワークロードからデータストア、その間のプロキシのホップという、区間ごとに一行の小さな表です。各行は何がそれを守り、その保護が何に依存するかを示します。仕組みも端点もない「暗号化されている」は行になりません。
そのうえで、元の要件に、それが問われたのと同じ言葉で答えます。要件が、ワークロードが受け取るまでデータが機密であり続けることなら、VPN が満たすのは最初の区間だけであり、残りの行にはアプリケーションの転送、サービスの TLS、ストレージの暗号化を別々に設定し検証する必要があります。
接続識別子、トンネルの状態、証明書のサブジェクトを記録に残してください。半年後に誰かが設計を見直すとき、その三つの成果物があれば、図から議論をやり直さずに数分で境界の問いに答えられます。