【実務・中級編】 VPCピアリングにおけるセキュリティグループのクロスアカウント参照とIPアドレス指定 – クラウドインフラと仮想化ネットワーク実践ガイド

クロスアカウントVPCピアリングの罠と真実:セキュリティグループ間参照でスマートにマルチVPCを繋ぐ方法

こんにちは。大規模なAWSインフラの設計から、深夜のパケットキャプチャによる障害切り分けまで、数々の修羅場をくぐり抜けてきたシニアSREの私だ。

今日のテーマは、マルチVPC環境におけるネットワーク設計の王道でありながら、一歩間違えるとセキュリティホールやデバッグ地獄を生み出す「VPCピアリングとセキュリティグループのクロスアカウント参照」だ。

「VPC間を通信させたいなら、ピアリング組んで相手のプライベートIPをセキュリティグループ(SG)に直接書けばいいじゃないか」——そう思っていないだろうか? 確かにそれでも動く。だが、動くことと、モダンでスケーラブルなインフラストラクチャであることは全く別次元の話だ。

今回は、AWSの裏側でパケットがどうルーティングされ、なぜIPアドレス直指定ではなくセキュリティグループIDの参照(Cross-Account SG Reference)を使うべきなのか、その理由と実践的なハンズオンを叩き込んでいこう。

—

1. なぜ「IPアドレス指定」ではなく「セキュリティグループ参照」なのか?

VPCピアリング(VPC Peering)を結んだとき、パケットはインターネットに出ることなく、AWSの巨大なバックボーンネットワーク上をダイレクトに駆け巡る。これは非常に高速かつセキュアだ。

しかし、ここで多くのジュニアエンジニアが陥るアンチパターンがある。それが「宛先VPCのプライベートIPアドレスをセキュリティグループのインバウンドルールに直接ハードコーディングする」という手法だ。

[VPC A (Client)] ---(VPC Peering)---> [VPC B (API Server: 10.2.0.5)]

この構成、一見するとシンプルで良さそうに見える。しかし、次のような現場の現実を想像してほしい。

  • オートスケーリングによって、APIサーバーのIPアドレスが 10.2.0.5 から 10.2.0.84 に変わった。
  • マイクロサービスの分割に伴い、バックエンドVPCのCIDRブロックが拡張・変更された。
  • 複数の環境(Staging / Production)で設定を流用する際、IPアドレスがハードコーディングされているためスクリプトが破綻した。

IPアドレスは「流動的なもの」だ。それを静的なファイアウォールのルールに埋め込むのは、技術的負債の何ものでもない。

セキュリティグループのクロスアカウント参照という「解」

AWSのVPCピアリングでは、異なるAWSアカウント間(クロスアカウント)であっても、送信元/宛先のセキュリティグループIDを直接参照ルールに指定できる。

これにより、IPアドレスがどのように変動しようとも、特定のセキュリティグループに属するリソースからの通信であれば、自動的に追従して許可・不許可を制御できるのだ。クラウドネイティブなインフラとは、こうあるべきだ。

—

2. 通信の裏側:パケットはどのように流れるのか

ここで、クロスアカウントVPCピアリングを経由したセキュリティグループ参照の通信フローを整理しておこう。

[Client (VPC A)] 
       │
       ▼ (1. リクエスト送信: src=10.1.0.5, dst=10.2.0.10)
[VPC A ルートテーブル] 
       │
       ▼ (2. 10.2.0.0/16 宛てのパケットを VPC Peering (pcx-xxxx) へ転送)
[VPC ピアリング接続 (AWSバックボーン)]
       │
       ▼ (3. VPC Bに到着)
[VPC B ルートテーブル] 
       │
       ▼ (4. 宛先EC2に到達する直前に、VPC Bのセキュリティグループを評価)
       │    ※ ここで「VPC A側のSG(sg-xxxx)」からの通信許可を確認!
[Target EC2 (VPC B)]

ここで重要なポイントがある。AWSのセキュリティグループはステートフル(Stateful)であるということだ。
インバウンドで許可されていれば、アウトバウンドの戻りパケットは明示的なルールを書かなくても自動的に通る。しかし、クロスアカウント参照を行う場合、「ピアリングの両端で正しいルートテーブルと名前解決、そしてクロスアカウントの所有権承認」が正しく設定されていなければ、パケットはそもそも宛先に到達すらしない。

—

3. 実践:クロスアカウントSG参照の設定手順(AWS CLI)

口で言うだけではSREの名折れだ。実際に、アカウントA(クライアント側)の特定のセキュリティグループから、アカウントB(APIサーバー側)のセキュリティグループを参照する設定をハンズオン形式で見ていこう。

前提条件として、すでにVPC A(アカウントA: 111122223333)とVPC B(アカウントB: 444455556666)の間でVPCピアリング(pcx-0123456789abcdef0)が確立され、双方のルートテーブルが正しくルーティングされているものとする。

ステップ1: アカウントB(APIサーバー側)でインバウンドルールを追加する

アカウントBのAPIサーバーにアタッチされているセキュリティグループ(例: sg-bbbbbbbbbbbbbbbbb)に対して、アカウントAのセキュリティグループ(例: sg-aaaaaaaaa)からのTCP/443(HTTPS)を許可するルールを追加する。

ここで肝なのが、プレフィックスとして相手のアカウントIDを指定することだ。

aws ec2 authorize-security-group-ingress \
    --group-id sg-bbbbbbbbbbbbbbbbb \
    --protocol tcp \
    --port 443 \
    --source-group sg-aaaaaaaaa \
    --cidr-account 111122223333 \
    --region ap-northeast-1 \
    --profile account-b

> シニアのTips: --cidr-account を忘れると、AWSは同一アカウント内でのセキュリティグループ検索を試みるため、クロスアカウントの場合はエラーになる。必ずピアリング先のAWSアカウントIDを明記しよう。

—

4. アプリケーションコードからの実証と疎通確認

設定が完了したら、実際にアプリケーション層から正しく通信できるかを確認する。今回は実務でよく使われる Python (requests ライブラリ) と curl コマンドの例を紹介する。

PythonによるAPIリクエスト例

VPC A内のクライアントインスタンスから、VPC B側の内部ALBまたはEC2へAPIリクエストを投げるスクリプトだ。

import requests
import sys

# VPC B側にある内部APIサーバーのエンドポイント(プライベートIPまたは内部DNS)
API_ENDPOINT = "https://internal-api.vcp-b.internal/v1/status"

def check_api_connectivity():
    try:
        # タイムアウトを3秒に設定し、内部ネットワークの詰まりを素早く検知する
        response = requests.get(API_ENDPOINT, timeout=3, verify=True)
        
        if response.status_code == 200:
            print(f"[SUCCESS] API通信成功: ステータスコード {response.status_code}")
            print(f"レスポンスボディ: {response.json()}")
        else:
            print(f"[WARNING] APIは応答しましたが、異常ステータスです: {response.status_code}", file=sys.stderr)
            
    except requests.exceptions.RequestException as e:
        print(f"[ERROR] ネットワークまたはセキュリティグループによるブロックの可能性があります: {e}", file=sys.stderr)
        sys.exit(1)

if __name__ == "__main__":
    check_api_connectivity()

デバッグのための curl コマンド

もしPythonスクリプトでタイムアウトや接続拒否(Connection Refused / Connection Timed Out)が発生した場合、以下の curl コマンドに -v(詳細出力)と --connect-timeout を付与して実行し、どのレイヤーで止まっているかを切り分ける。

curl -v --connect-timeout 5 https://internal-api.vcp-b.internal/v1/status
  • Connection timed out の場合: ルートテーブルのルーティングミス、またはセキュリティグループのインバウンド/アウトバウンドで完全にパケットがドロップされている。
  • Could not resolve host の場合: Route 53のプライベートホストゾーンの関連付け(VPCアソシエーション)が漏れている。

—

5. トラブルシューティング:よくあるハマりポイント

現場でクロスアカウントSG参照を導入した際、大体ハマるポイントは決まっている。以下のチェックリストを頭に叩き込んでおいてほしい。

1. DNS解決の有効化を忘れている
VPCピアリング接続の設定で、DNSホスト名の解決 (Enable DNS resolution) が双方のVPCで有効になっていないと、プライベートDNS名で名前解決ができず通信できない。
2. セキュリティグループの「循環参照」や「カスケード」の限界
SG参照は便利だが、複雑に多段でクロスアカウント参照しすぎると、セキュリティ監査の際に「どのトラフィックがどこから来ているのか」を人間が追えなくなる。参照は原則として「クライアント側 → サーバー側」の単方向の階層構造にとどめるべきだ。
3. トランジットゲートウェイ(TGW)への移行時の罠
将来的にシステムが拡大し、VPCピアリングからAWS Transit Gateway (TGW) に移行する際、TGW環境ではセキュリティグループのクロスアカウント参照が直接利用できない(TGWの仕様制限)。TGW環境ではIPアドレスベース、あるいはAWS Network FirewallやVPC Endpoint Servicesを組み合わせたアーキテクチャ設計が必要になる点に注意してほしい。

—

まとめ

VPCピアリングにおけるセキュリティグループのクロスアカウント参照は、マルチVPC環境のセキュリティを保ちつつ、動的なインフラの変化に柔軟に対応するための強力な武器だ。

IPアドレスのハードコーディングという泥臭い手法を捨て、IDベースのスマートな参照を活用することで、変更に強く、監査にも耐えうる堅牢なクラウドインフラストラクチャ築き上げてほしい。

君たちのインフラが、深夜のPagerDutyの嵐から解放されることを切に願っている。それでは、また次の現場で会おう。

コメント

タイトルとURLをコピーしました