カスタムVPCのEC2インターネット接続不可を解決する — Internet GatewayとRoute Tableの設定手順
カスタムVPCを作成してパブリックサブネットにEC2インスタンスを起動したのに、ping google.comが通らない。この問題はVPC構築時に最もよく遭遇するトラブルで、原因はほぼ必ずInternet GatewayのアタッチかRoute Tableのルート設定の抜け漏れにある。デフォルトVPCと違い、カスタムVPCはこれらのリソースを明示的に構成しなければインターネット疎通は一切得られない。
TL;DR — EC2インターネット接続不可の原因と対処
| 確認レイヤー | よくある原因 | 対処 |
|---|---|---|
| Internet Gateway | 作成済みだがVPCにアタッチされていない | IGWをVPCにアタッチ |
| Route Table | 0.0.0.0/0のルートが存在しない | IGWへのデフォルトルートを追加 |
| サブネット関連付け | パブリックサブネットがカスタムRoute Tableに関連付けられていない | サブネットをRoute Tableに明示的に関連付け |
| パブリックIPアドレス | インスタンスにパブリックIPが割り当てられていない | サブネットの自動割り当て設定を有効化、またはElastic IPを割り当て |
| Security Group | アウトバウンドルールが制限されている | アウトバウンド0.0.0.0/0を許可 |
| Network ACL | サブネットレベルのACLがトラフィックを拒否している | インバウンド/アウトバウンドルールを確認 |
カスタムVPCのインターネット接続がどのように機能するか
デフォルトVPCはAWSが自動的にIGWのアタッチとRoute Tableの設定を済ませた状態で提供される。カスタムVPCにはそれがない。EC2インスタンスがインターネットに到達するには、パケットが通過しなければならないレイヤーが複数存在する。
パブリックIP必須"] --> SG["Security Group
ステートフル"] SG --> NACL["Network ACL
ステートレス"] NACL --> RT["Route Table
0.0.0.0/0 → IGW"] RT --> IGW["Internet Gateway
VPCにアタッチ済み"] IGW --> NET["インターネット"] style EC2 fill:#FF9900,color:#fff style IGW fill:#232F3E,color:#fff style RT fill:#1A73E8,color:#fff style NET fill:#34A853,color:#fff
- EC2インスタンス — パブリックIPが割り当てられていることが前提。なければパケットは返ってこない。
- Security Group (インスタンスレベル) — ステートフルなファイアウォール。アウトバウンドが許可されていればレスポンスは自動的に許可される。
- Route Table (サブネットレベル) — 0.0.0.0/0のルートがIGWを指していなければ、パケットはVPC内で行き場を失う。
- Network ACL (サブネットレベル) — ステートレスなフィルター。アウトバウンドとインバウンド両方のルールが必要。
- Internet Gateway — VPCにアタッチされていなければ、ルートが存在しても通信できない。
IGWはVPCの玄関ドアに相当する。Route Tableはその玄関への道順だ。どちらか一方が欠けていれば、もう一方が存在しても外には出られない。
EC2インターネット接続不可を診断する — 確認順序
問題を最短で特定するには、パケットが通過するレイヤーを外側から内側へ順番に確認する。IGWとRoute Tableから始めるのが効率的で、この2つで大半のケースが解決する。
アタッチされているか?"} CHK1 -- No --> FIX1["IGWを作成/アタッチする"] CHK1 -- Yes --> CHK2{"Route Tableに
0.0.0.0/0ルートがあるか?"} FIX1 --> CHK2 CHK2 -- No --> FIX2["デフォルトルートを追加する"] CHK2 -- Yes --> CHK3{"サブネットは正しい
Route Tableに関連付けられているか?"} FIX2 --> CHK3 CHK3 -- No --> FIX3["サブネットをRoute Tableに関連付ける"] CHK3 -- Yes --> CHK4{"インスタンスに
パブリックIPがあるか?"} FIX3 --> CHK4 CHK4 -- No --> FIX4["EIPを割り当てる"] CHK4 -- Yes --> CHK5{"SGアウトバウンドは
許可されているか?"} FIX4 --> CHK5 CHK5 -- No --> FIX5["SGアウトバウンドルールを追加"] CHK5 -- Yes --> CHK6{"Network ACLは
通過を許可しているか?"} FIX5 --> CHK6 CHK6 -- No --> FIX6["ACLルールを修正する"] CHK6 -- Yes --> DONE(["接続確認: ping google.com"]) FIX6 --> DONE style START fill:#FF9900,color:#fff style DONE fill:#34A853,color:#fff
ステップ1 — Internet GatewayのVPCアタッチ状態を確認する
IGWが存在していてもVPCにアタッチされていなければ意味がない。detached状態のIGWはよく見落とされる。コンソールで作成した直後にアタッチを忘れるケースが多い。
# 対象VPCにアタッチされているIGWを確認
aws ec2 describe-internet-gateways \
--filters 'Name=attachment.vpc-id,Values=vpc-0123456789abcdef0' \
--query 'InternetGateways[*].{IGW_ID:InternetGatewayId,State:Attachments[0].State}' \
--output table
出力に何も表示されない場合、またはStateがdetachedの場合はアタッチが必要だ。IGWが存在しない場合は作成から始める。
# IGWを作成する
aws ec2 create-internet-gateway \
--tag-specifications 'ResourceType=internet-gateway,Tags=[{Key=Name,Value=my-igw}]'
# 出力されたInternetGatewayIdを使ってVPCにアタッチする
aws ec2 attach-internet-gateway \
--internet-gateway-id igw-0123456789abcdef0 \
--vpc-id vpc-0123456789abcdef0
ステップ2 — Route Tableにデフォルトルートを追加する
IGWがアタッチされていても、Route Tableに0.0.0.0/0 → IGWのルートがなければパケットはVPC内に閉じ込められる。まず対象サブネットがどのRoute Tableに関連付けられているかを確認する。
# サブネットに関連付けられているRoute Tableを確認
aws ec2 describe-route-tables \
--filters 'Name=association.subnet-id,Values=subnet-0123456789abcdef0' \
--query 'RouteTables[*].{RT_ID:RouteTableId,Routes:Routes}' \
--output json
出力のRoutesの中にDestinationCidrBlock: 0.0.0.0/0のエントリが存在しない場合、またはサブネットがメインRoute Tableに暗黙的に関連付けられているだけの場合は、カスタムRoute Tableを作成してルートを追加する。
# カスタムRoute Tableを作成する
aws ec2 create-route-table \
--vpc-id vpc-0123456789abcdef0 \
--tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=public-rt}]'
# IGWへのデフォルトルートを追加する
aws ec2 create-route \
--route-table-id rtb-0123456789abcdef0 \
--destination-cidr-block 0.0.0.0/0 \
--gateway-id igw-0123456789abcdef0
# パブリックサブネットをRoute Tableに関連付ける
aws ec2 associate-route-table \
--route-table-id rtb-0123456789abcdef0 \
--subnet-id subnet-0123456789abcdef0
ステップ3 — EC2インスタンスのパブリックIPアドレスを確認する
IGWとRoute Tableが正しく設定されていても、インスタンス自体にパブリックIPがなければインターネット側からの応答は返ってこない。これは見落としやすい。Route Tableを直した後に「まだ繋がらない」と悩む場合の多くはここが原因だ。
# インスタンスのパブリックIPアドレスを確認する
aws ec2 describe-instances \
--instance-ids i-0123456789abcdef0 \
--query 'Reservations[*].Instances[*].{InstanceId:InstanceId,PublicIP:PublicIpAddress,State:State.Name}' \
--output table
PublicIPがNoneの場合、サブネットのパブリックIP自動割り当て設定を有効化するか、Elastic IPを割り当てる。
# サブネットのパブリックIP自動割り当てを有効化する
aws ec2 modify-subnet-attribute \
--subnet-id subnet-0123456789abcdef0 \
--map-public-ip-on-launch
# 既存インスタンスにはElastic IPを割り当てる
# まずElastic IPを確保する
aws ec2 allocate-address --domain vpc
# 出力されたAllocationIdを使ってインスタンスに関連付ける
aws ec2 associate-address \
--instance-id i-0123456789abcdef0 \
--allocation-id eipalloc-0123456789abcdef0
ステップ4 — Security Groupのアウトバウンドルールを確認する
Security Groupはステートフルなので、アウトバウンドが許可されていればレスポンスは自動的に許可される。ただし、セキュリティ強化のためにアウトバウンドを制限している場合は明示的な許可が必要になる。IGWとRoute Tableが正しくてもpingが通らないなら、ここを疑う。
# インスタンスのSecurity Groupを確認する
aws ec2 describe-instances \
--instance-ids i-0123456789abcdef0 \
--query 'Reservations[*].Instances[*].SecurityGroups' \
--output json
# Security Groupのアウトバウンドルールを確認する
aws ec2 describe-security-groups \
--group-ids sg-0123456789abcdef0 \
--query 'SecurityGroups[*].{GroupId:GroupId,Outbound:IpPermissionsEgress}' \
--output json
アウトバウンドルールが空またはHTTPS/HTTPのみに制限されている場合、ICMPを許可するルールを追加する。
# ICMPアウトバウンドを許可する (ping用)
aws ec2 authorize-security-group-egress \
--group-id sg-0123456789abcdef0 \
--protocol icmp \
--port -1 \
--cidr 0.0.0.0/0
ステップ5 — Network ACLのルールを確認する
Network ACLはステートレスなため、アウトバウンドとインバウンド両方のルールを個別に設定する必要がある。Security Groupと違い、レスポンストラフィックは自動的に許可されない。pingのレスポンス(ICMPタイプ0)が戻ってこない場合、ACLのインバウンドルールがブロックしている可能性がある。
# サブネットに関連付けられているNetwork ACLを確認する
aws ec2 describe-network-acls \
--filters 'Name=association.subnet-id,Values=subnet-0123456789abcdef0' \
--query 'NetworkAcls[*].{AclId:NetworkAclId,Entries:Entries}' \
--output json
デフォルトのNetwork ACLはすべてのトラフィックを許可する。カスタムACLを使用している場合は、ICMPのインバウンド(エフェメラルポートを含む)とアウトバウンドの両方が許可されていることを確認する。
実際の障害パターン — IGWはアタッチ済みなのに繋がらない
IGWをVPCにアタッチしてRoute Tableにデフォルトルートも追加した。それでもpingが通らない。コンソールを見ると設定は正しそうに見える。こういうとき、次に疑うべきはサブネットとRoute Tableの関連付けだ。
カスタムRoute Tableを作成してルートを追加しても、サブネットをそのRoute Tableに明示的に関連付けなければ、サブネットはメインRoute Tableを使い続ける。メインRoute Tableにはデフォルトルートがない。コンソールでRoute Tableを見ると正しいルートが表示されているのに繋がらない、という状況の正体はこれだ。
# サブネットの現在のRoute Table関連付けを確認する
aws ec2 describe-route-tables \
--filters 'Name=association.subnet-id,Values=subnet-0123456789abcdef0' \
--query 'RouteTables[*].{RT_ID:RouteTableId,Main:Associations[0].Main}' \
--output table
Main: trueが返ってきた場合、そのサブネットはメインRoute Tableに関連付けられている。カスタムRoute Tableへの明示的な関連付けが必要だ。ステップ2のassociate-route-tableコマンドを実行する。
設定変更後に接続を確認するには、EC2 Instance ConnectまたはSSMセッションマネージャーでインスタンスに接続してpingを実行する。
# SSM Session Managerで接続確認 (SSMエージェントが必要)
aws ssm start-session --target i-0123456789abcdef0
最小権限IAMポリシー — VPCネットワーク設定に必要な権限
VPCのネットワーク設定を行うオペレーターには、以下の権限が必要になる。本番環境では管理者権限を使わず、必要な権限のみを付与したロールを使うこと。
🔽 IAMポリシーを展開して確認する
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VPCNetworkConfiguration",
"Effect": "Allow",
"Action": [
"ec2:CreateInternetGateway",
"ec2:AttachInternetGateway",
"ec2:DetachInternetGateway",
"ec2:DeleteInternetGateway",
"ec2:DescribeInternetGateways",
"ec2:CreateRouteTable",
"ec2:CreateRoute",
"ec2:DeleteRoute",
"ec2:AssociateRouteTable",
"ec2:DisassociateRouteTable",
"ec2:DescribeRouteTables",
"ec2:ModifySubnetAttribute",
"ec2:DescribeSubnets",
"ec2:AllocateAddress",
"ec2:AssociateAddress",
"ec2:DescribeAddresses",
"ec2:DescribeInstances",
"ec2:DescribeSecurityGroups",
"ec2:AuthorizeSecurityGroupEgress",
"ec2:DescribeNetworkAcls",
"ec2:CreateTags"
],
"Resource": "*"
}
]
}
Read/Describe系のアクションはリソースレベルの制限をサポートしていないものが多く、"Resource": "*"が必要になる。Write系のアクションについては、AWS Service Authorization Referenceで各アクションがサポートするリソースタイプを確認した上で、可能な範囲でARN制限を追加することを推奨する。
EC2インターネット接続不可 — 完全な診断フロー
- IGWがVPCにアタッチされているかを最初に確認する。ここが未設定なら後続の確認は不要。
- Route Tableに0.0.0.0/0のルートが存在し、かつ対象サブネットがそのRoute Tableに関連付けられているかを確認する。
- インスタンスにパブリックIPが割り当てられているかを確認する。
- Security Groupのアウトバウンドルールを確認する。
- Network ACLのインバウンド/アウトバウンド両方のルールを確認する。
まとめとネクストステップ — EC2インターネット接続の確立
カスタムVPCでEC2インターネット接続不可になる原因の大半は、IGWのアタッチ漏れ、Route Tableのデフォルトルート未設定、またはサブネットとRoute Tableの関連付け漏れの3つに集約される。パブリックIPの割り当て確認はその次に確認すべき項目だ。
本番環境でこの構成を管理する場合は、AWS CloudFormationまたはTerraformでインフラをコード化することで、手動設定の抜け漏れを防ぐことができる。また、プライベートサブネットのEC2インスタンスからインターネットへのアウトバウンド通信が必要な場合は、NAT GatewayをパブリックサブネットにデプロイしてRoute Tableを設定する構成が必要になる。
用語集
| 用語 | 説明 |
|---|---|
| Internet Gateway (IGW) | VPCとインターネット間の通信を可能にする水平スケーリング対応のVPCコンポーネント。VPCに1つアタッチする。 |
| Route Table | サブネット内のトラフィックのルーティングルールを定義するテーブル。各サブネットは1つのRoute Tableに関連付けられる。 |
| パブリックサブネット | IGWへのルートを持つRoute Tableに関連付けられたサブネット。インターネットへの直接疎通が可能。 |
| Elastic IP (EIP) | AWSアカウントに割り当てられる静的なパブリックIPアドレス。インスタンスの停止/起動後もIPアドレスが変わらない。 |
| Network ACL | サブネットレベルで動作するステートレスなパケットフィルター。インバウンドとアウトバウンドを個別に制御する。 |
コメント
コメントを投稿