AWS VPC VISUALIZER

AWS VPC ルーティングの仕組み

AWS上に論理的に分離されたプライベートネットワークを構築するサービス

シナリオ
ルートテーブルのエントリをどのように評価してパケットの転送先を決定するかを可視化します
ステップ1 / 6
ステップ
ルートテーブル = Destination と Target のペア一覧
ルートテーブルは Destination(宛先CIDR)と Target(転送先)のペアで構成されます。パケットを送信すると、宛先IPアドレスが各エントリの CIDR 範囲内かどうかを確認し、マッチしたエントリのうち最もプレフィックスが長い(最も具体的な)ものを選択します。
ROUTE TABLE VIEWER
パケットの宛先IPを各エントリと照合し、転送先を決定する流れ
STEP 1
CODE VIEW
── ルートテーブルの構成要素 ──
 
$ aws ec2 describe-route-tables \
--route-table-ids rtb-pub-0abc123
 
RouteTableId: rtb-pub-0abc123
Association: subnet-0a1b2c (Public Subnet A)
 
Routes:
Destination: 10.0.0.0/16 Target: local Origin: CreateRouteTable
Destination: 0.0.0.0/0 Target: igw-0abc123 Origin: CreateRoute
 
◎ Destination = 宛先CIDR、Target = 転送先
◎ パケットの宛先IPを各エントリのCIDR範囲と照合する
マッチ / 選択されたルート
評価中
Blackhole / ドロップ
非マッチ
未評価
解説

📌
ルートテーブルとは何か

ルートテーブル(Route Table)は、サブネット内のリソースがパケットを送信するとき「このパケットはどこに転送すべきか」を決定する道案内表です。現実世界でいえば、郵便局の仕分けシステムに似ています。宛先の郵便番号を見て「この手紙は東京行きの箱に」「この手紙は大阪行きの箱に」と仕分けるように、ルートテーブルはパケットの宛先IPアドレスを見て適切な転送先を決めます。

ルートテーブルは複数の「ルートエントリ」で構成されます。各エントリは「Destination(宛先CIDR)」と「Target(転送先)」のペアです。例えば 10.0.0.0/16 → local は「10.0.0.0/16 宛のパケットはVPC内で処理する」という意味で、0.0.0.0/0 → igw-xxx は「その他全ての宛先はIGW経由でインターネットに送る」という意味です。

VPCを作成すると「メインルートテーブル」が自動作成されます。明示的にルートテーブルを紐付けないサブネットはこのメインルートテーブルを使用します。しかしベストプラクティスとしては、パブリック用・プライベート用に別々のカスタムルートテーブルを作成し、明示的にサブネットに紐付ける(アソシエーション)ことが推奨されます。これにより、設定ミスでメインルートテーブルを変更しても影響範囲を限定できます。

ルートテーブル10.0.0.0/16 → local0.0.0.0/0 → igw-xxxDestination + Target = ルートエントリ
## ルートテーブル作成 & サブネットへの紐付け
$ aws ec2 create-route-table --vpc-id vpc-0abc123
$ aws ec2 create-route \
--route-table-id rtb-xxx \
--destination-cidr-block 0.0.0.0/0 \
--gateway-id igw-0abc123
$ aws ec2 associate-route-table \
--route-table-id rtb-xxx \
--subnet-id subnet-pub

🗺️
サブネットとルートテーブルの関係

VPC内の各サブネットには必ず1つのルートテーブルが紐付いています。EC2がパケットを送ると、そのEC2が所属するサブネットのルートテーブルが自動的に参照されます。つまりルートテーブルはサブネット単位で設定するもので、「このサブネットの通信はこのルールで振り分ける」という役割です。

ここで重要なのは、サブネットに「パブリック」「プライベート」という属性は存在しないということです。紐付いているルートテーブルの中身がサブネットの性質を決めます。デフォルトルート(0.0.0.0/0)がIGWを指していればパブリック、NATを指していればプライベートになります。ルートテーブルを差し替えるだけで性質が変わります。

自分でルートテーブルを紐付けていないサブネットは、VPCの「メインルートテーブル」が自動で使われます。メインルートテーブルにはlocalルートしかないため、紐付けを忘れたサブネットは事実上プライベート(インターネット接続なし)になります。

Public Subnet (10.0.1.0/24) のルートテーブル
Destination
Target
10.0.0.0/16
local
0.0.0.0/0
igw-0abc123
→ IGW行きのルートがある = インターネットと双方向通信できる
Private Subnet (10.0.2.0/24) のルートテーブル
Destination
Target
10.0.0.0/16
local
0.0.0.0/0
nat-0def456
→ NAT行きのルート = 外には出られるが、外から入れない(一方向)
Isolated Subnet (10.0.3.0/24) のルートテーブル
Destination
Target
10.0.0.0/16
local
→ local のみ = VPC内通信だけ。インターネット接続なし(DB専用など)
ポイント: 3つのサブネットの違いはルートテーブルのデフォルトルート(0.0.0.0/0)の有無とターゲットだけです。localルートは全て同じです。

🎯
最長プレフィックスマッチとは何か

最長プレフィックスマッチ(Longest Prefix Match)は、複数のルートが宛先IPアドレスにマッチする場合に、最も具体的な(プレフィックス長が最大の)ルートを選択するルールです。これはAWS固有の概念ではなく、インターネットのルーティングプロトコル全般で使われる基本原則です。

例えば宛先が 10.0.1.50 の場合、10.0.1.0/24(24ビット一致)、10.0.0.0/16(16ビット一致)、0.0.0.0/0(0ビット一致)の3つにマッチしますが、24ビットが最長なので /24 のルートが選ばれます。直感的には「最も詳しい住所を知っているルートに任せる」と理解できます。

この仕組みにより、VPC内通信(local)とインターネット通信(IGW/NAT)を1つのルートテーブルで正しく振り分けることができます。10.0.0.0/16 → local は /16 で、0.0.0.0/0 → IGW は /0 なので、VPC内宛のパケットは常にlocalが優先されます。

0.0.0.0/0 → IGW (プレフィックス長: 0)10.0.0.0/16 → local (プレフィックス長: 16)10.0.1.0/24← 最長! (24ビット)範囲が狭い(具体的な)ルートほど優先される

🏠
local ルートの役割

localルートはVPC作成時に自動的に全てのルートテーブルに追加されるルートで、削除できません。VPCのCIDRブロック宛のパケットをVPC内部のルーターが直接処理することを意味します。例えばVPCが10.0.0.0/16の場合、10.0.x.xの範囲内宛のパケットはIGWやNATを経由せず、VPC内で直接ルーティングされます。

localルートがあるおかげで、同じVPC内の異なるサブネット間の通信は自動的に行えます。パブリックサブネットのALBからプライベートサブネットのEC2への通信、プライベートサブネット間のRDS接続など、VPC内通信はlocalルートが処理します。追加の設定は不要で、セキュリティグループとNACLのみで制御します。

最長プレフィックスマッチにより、localルート(/16)はデフォルトルート(/0)よりも常に優先されます。つまり、VPC内宛のパケットがIGW経由でインターネットに出てしまうことは絶対にありません。VPC内通信が確実にVPC内で完結するこのメカニズムは、セキュリティとパフォーマンスの両面で重要です。

例: ALB (10.0.1.10) → EC2 (10.0.2.50) への通信
Destination
Target
10.0.2.50 は?
10.0.0.0/16
local
✓ 範囲内 → 選択!
0.0.0.0/0
igw-0abc123
マッチするが /0 < /16
→ local が選択される = VPC内ルーターが直接 10.0.2.50 に転送。IGW は経由しない
ポイント: サブネットが違っても VPC 内なら local ルートが処理します。ALB → EC2、EC2 → RDS、Lambda → ElastiCache など、VPC 内通信に IGW や NAT は不要で、追加設定もコストもかかりません。

🚪
デフォルトルート(0.0.0.0/0)とは何か

デフォルトルート(0.0.0.0/0)は「他のどのルートにもマッチしなかったパケットの行き先」を指定するルートです。0.0.0.0/0は全てのIPアドレスにマッチしますが、プレフィックス長が0なので最長プレフィックスマッチにより最も優先度が低くなります。つまり「最後の砦」として機能します。

パブリックサブネットでは 0.0.0.0/0 → igw-xxx と設定し、VPC外宛のパケットをIGW経由でインターネットに送ります。プライベートサブネットでは 0.0.0.0/0 → nat-xxx と設定し、NAT Gateway経由でインターネットに出ます。

デフォルトルートが存在しないサブネットでは、VPC外宛のパケットはルートが見つからず破棄されます。これは意図的にインターネット通信を禁止したい場合(DB専用サブネット等)には正しい設定ですが、多くの場合は設定ミスです。EC2からOSパッチが取得できない等の障害の原因として最も多いのがこのデフォルトルートの未設定です。

EC2 (10.0.1.50) → 8.8.8.8 宛のパケット
Destination
Target
8.8.8.8 は?
10.0.0.0/16
local
✕ 範囲外
0.0.0.0/0
igw-0abc123
✓ マッチ → 選択!
→ デフォルトルートがあるから 8.8.8.8 にたどり着ける
デフォルトルートがない場合: EC2 (10.0.3.50) → 8.8.8.8
Destination
Target
8.8.8.8 は?
10.0.0.0/16
local
✕ 範囲外
→ 他にエントリがない → パケットは破棄される(Connection timed out)
ポイント: 0.0.0.0/0 は全てのIPにマッチしますが、プレフィックス長が /0(最短)なので常に最後に評価されます。「他にマッチするルートがなかったときの受け皿」として機能する、いわば「最後の砦」です。

📎
メインルートテーブル

VPCを作成すると「メインルートテーブル」が1つ自動で作られます。このテーブルには local ルートだけが入っています。サブネットを作った直後は、このメインルートテーブルが暗黙的に紐付きます。

自分で別のルートテーブル(カスタムルートテーブル)を作成してサブネットに明示的に紐付けると、そのサブネットはメインルートテーブルを使わなくなります。紐付けを忘れたサブネットはメインルートテーブルが使われるので、メインRTの中身を変えると意図しないサブネットに影響が出ます。

Main Route Table(VPC作成時に自動生成)
Destination
Target
10.0.0.0/16
local
→ local のみ。カスタムRTを紐付けていないサブネット全てに暗黙適用される
Custom Route Table(自分で作成 → Public Subnet に明示的に紐付け)
Destination
Target
10.0.0.0/16
local
0.0.0.0/0
igw-0abc123
→ IGW 行きルートを追加して明示的にサブネットに紐付け = パブリックサブネット
ベストプラクティス: メインルートテーブルは local のみのまま触らず、パブリック用・プライベート用にカスタムルートテーブルを作って明示的に紐付けるのが安全です。メインRTを変更すると「紐付けを忘れたサブネット」全てに影響するため、事故の元になります。

⚠️
ルートテーブル設定ミスによるトラブルシューティング

「EC2からインターネットに繋がらない」という障害の原因で最も多いのがルートテーブルの設定ミスです。ここでは実際によくある3つのケースを、ルートテーブルの中身を見ながら確認します。

ケース1: NAT Gateway を設定し忘れた

プライベートサブネットの EC2 で apt update が失敗する。原因: デフォルトルートがない。

Destination
Target
Status
10.0.0.0/16
local
Active
→ 0.0.0.0/0 の行がない = VPC外への通信は全て破棄される
修正: NAT GW を作成し 0.0.0.0/0 → nat-xxx を追加する
ケース2: NAT Gateway が削除されて blackhole になった

昨日まで動いていたのに突然 Connection timed out。コスト削減で NAT GW を削除したが、ルートは残ったままだった。

Destination
Target
Status
10.0.0.0/16
local
Active
0.0.0.0/0
nat-0abc123
blackhole
→ ルートは存在するがターゲットが削除済み。パケットはサイレントに消える
→ ケース1と違い「ルートがある」ので見落としやすい。Status 列の確認が重要
修正: NAT GW を再作成し replace-route で新しい NAT に向ける
ケース3: メインルートテーブルに IGW を追加してしまった

「パブリックサブネットを作ろう」と思い、カスタムRTではなくメインRTに 0.0.0.0/0 → IGW を追加。結果、明示的にRTを紐付けていない全サブネットがパブリック化してしまった。

Main Route Table(全サブネットに暗黙適用)
Destination
Target
10.0.0.0/16
local
0.0.0.0/0
igw-0abc123 ← 追加してしまった
→ DB用サブネットもインターネットからアクセス可能に。セキュリティ事故のリスク
修正: メインRTからIGWルートを削除し、パブリック専用のカスタムRTを作成する
診断手順(インターネットに繋がらないとき)
1. EC2のサブネットIDを確認する
2. そのサブネットに紐付いたルートテーブルを特定する
3. 0.0.0.0/0 の行があるか確認 → なければケース1
4. 0.0.0.0/0 の Status が blackhole でないか確認 → blackhole ならケース2
5. ターゲット(IGW/NAT)のリソースが正常に存在するか確認
# サブネットのルートテーブルを確認
$ aws ec2 describe-route-tables \
--filters "Name=association.subnet-id,Values=subnet-xxx"
# Status: blackhole が見つかったら → ターゲットを確認
$ aws ec2 describe-nat-gateways --nat-gateway-ids nat-0abc123

📝
AWS 認定試験(SAA)レベルの問題

Q1.プライベートサブネットのEC2インスタンスがインターネットに接続できません。ルートテーブルには「10.0.0.0/16 → local」のみ設定されています。最も適切な対処はどれですか?
A.EC2 にパブリック IP を付与する
B.プライベートサブネットに IGW を直接アタッチする
C.NAT Gateway を作成し、ルートテーブルに 0.0.0.0/0 → NAT のルートを追加する
D.セキュリティグループのアウトバウンドルールに 0.0.0.0/0 を追加する
Q2.ルートテーブルに「10.0.0.0/16 → local」「10.0.1.0/24 → pcx-xxx」「0.0.0.0/0 → igw-xxx」のルートがあります。10.0.1.50 宛のパケットはどこに転送されますか?
A.local(VPC内ルーティング)
B.pcx-xxx(VPCピアリング接続)
C.igw-xxx(Internet Gateway)
D.3つのルート全てにマッチするためエラーになる
Q3.VPC のルートテーブルにおける local ルートについて正しい記述はどれですか?
A.local ルートは管理者が手動で追加する必要がある
B.local ルートはルートテーブルから削除できる
C.local ルートは VPC の CIDR ブロック宛の通信を VPC 内でルーティングする
D.local ルートは 0.0.0.0/0 と同じプレフィックス長を持つ

関連コンテンツ