- ネットワーク
VPCとは?AWSのサブネット・IGW・NATの関係を手元で再現
結論
Amazon VPC は、AWS の中に作る自分専用の仮想ネットワークです。サブネットに付けたルートテーブルに「0.0.0.0/0 → インターネットゲートウェイ」の行があればパブリックサブネット、無ければプライベートサブネットになります。
この記事でわかること
- VPC・サブネット・ルートテーブル・IGW・NAT の関係と、パブリック/プライベートの決まり方
- moto と AWS CLI で作った VPC の出力と、ip netns で「外へ出られる/出られない」を再現した ping・tcpdump
- CIDR の決め方の計算、セキュリティグループと NACL の違い、料金の考え方の判断表
VPC は「AWS の中に借りた、自分だけの区画」です。区画の中をサブネットで部屋に分け、部屋ごとのルートテーブル(道案内の表)で「外へ出る扉」を決めます。最初に全体の形を図で示します。
flowchart TB
NET((インターネット))
IGW[インターネット<br>ゲートウェイ]
subgraph VPC[VPC 10.0.0.0/16]
subgraph PUB[パブリック 10.0.1.0/24]
WEB[Web<br>公開IPあり]
NAT[NAT<br>ゲートウェイ]
end
subgraph PRI[プライベート 10.0.11.0/24]
DB[DB・アプリ]
end
end
NET <--> IGW
IGW <--> WEB
DB -->|外向きだけ| NAT
NAT --> IGW
よく調べられることの答えを先にまとめます。
| 知りたいこと | 答え | 詳しい節 |
|---|---|---|
| VPCとは | AWS の中に作る、論理的に切り離された自分専用の仮想ネットワーク | VPCとは |
| VPC サブネットとは | VPC の IP アドレスの範囲を小分けしたもの。1つのアベイラビリティーゾーン(AZ)の中に置く | サブネットとルートテーブル |
| パブリックとプライベートの違い | ルートテーブルに IGW への経路があるかどうか。名前の設定ではない | サブネットとルートテーブル |
| IGW と NAT ゲートウェイの違い | IGW は外と双方向、NAT は中から外への片道だけ | IGWとNATゲートウェイの違い |
| CIDR はどう決める | /16 を取り、AZ ごと・役割ごとに /20〜/24 に分ける。他と重ねない | CIDRとサブネットの決め方 |
| セキュリティグループと NACL の違い | SG はインスタンス単位で戻りを自動で許可、NACL はサブネット単位で戻りも書く | SGとネットワークACLの違い |
| VPC の料金 | VPC 自体は追加料金なし。NAT ゲートウェイ・パブリック IPv4 などが有料 | VPCの料金の考え方 |
| 作り方の手順(AWS CLI) | VPC→サブネット→IGW→ルートテーブル→関連付けの順 | AWS CLIで作った出力 |
確認環境:Ubuntu 24.04.5 LTS(カーネル 6.18.44)の上で、本物の AWS には接続せず、AWS のモック(まねをする偽物のサーバー)である moto 5.1.22 をサーバーモードで 127.0.0.1 に起動し、AWS CLI 1.44.87(botocore 1.42.97・Python 3.9.25 の venv)から VPC・サブネット・IGW・ルートテーブル・NAT ゲートウェイ・セキュリティグループを作成・削除しました。認証情報は作業用のダミーの値だけを使っています。パブリック/プライベートの違いは、Linux の ip netns(ネットワークを分けた小部屋)を7つ作り、iproute2 6.1.0・iptables 1.8.10(nf_tables)で「VPC ルーター」「IGW」「NAT」「インターネット」を再現して、ping(iputils 20240117)・curl 8.5.0・tcpdump 4.99.4 で確かめました。CIDR の計算は Python 3.13.18 の ipaddress モジュールです。AWS 側の仕様(サブネットの大きさ・予約アドレス・デフォルト VPC・クォータ・NACL のエフェメラルポート・料金)は AWS の公式ドキュメントと料金ページで確かめ、moto の動きが公式と違う点は本文に書いています。図は mermaid 11.16.0 で描画を確かめました(確認日 2026年10月29日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「VPCとは?AWSのサブネット・IGW・NATの関係を手元で再現」
VPCとは(Amazon VPCの意味と全体像)
この節では、VPC が何の略で、何をするための仕組みなのかが分かります。
VPC は Virtual Private Cloud の略で、AWS の中に「論理的に切り離された、自分で定義する仮想ネットワーク」を作るサービスです。 AWS の公式ドキュメントは、自社のデータセンターで運用する従来のネットワークによく似たもので、そこに AWS のリソース(EC2・RDS・ロードバランサーなど)を置ける、と説明しています。
家にたとえると、VPC は「敷地」、サブネットは「部屋」、ルートテーブルは「部屋ごとの道案内の表」、インターネットゲートウェイ(IGW)は「表通りへの玄関」、NAT ゲートウェイは「中からは出られるが、外からは入れない勝手口」です。セキュリティグループは「各部屋の住人が持つ合鍵の規則」、ネットワーク ACL は「部屋の入口の門番」にあたります。
VPC で決められること
- IP アドレスの範囲:VPC 全体の範囲(例:10.0.0.0/16)と、サブネットごとの範囲を自分で決める。
- 経路:サブネットからの通信をどこへ送るかを、ルートテーブルで決める。
- 外との出入り口:インターネット(IGW)、外向きだけ(NAT)、社内ネットワーク(VPN・Direct Connect)、他の VPC(ピアリング・Transit Gateway)、AWS のサービス(VPC エンドポイント)を必要な分だけ付ける。
- 通してよい通信:セキュリティグループとネットワーク ACL で、ポートと送信元を絞る。
VPC は「リージョン」単位で作り、サブネットは「AZ(アベイラビリティーゾーン。リージョンの中の独立したデータセンター群)」単位で作ります。 1つの VPC は東京リージョンの中の複数の AZ にまたがれますが、1つのサブネットは1つの AZ からはみ出せません。
Google Cloud の「VPC」との関係
「VPC」という言葉は AWS だけのものではなく、Google Cloud にも VPC があります。この記事は AWS の Amazon VPC について書いています。Google Cloud の公式ドキュメントは、VPC ネットワークをリージョンのサブネットで構成される「グローバル リソース」と説明しており、AWS(VPC はリージョン、サブネットは AZ)とは単位が異なります。
VPCを構成する要素の一覧
この節では、VPC の中に出てくる部品の名前と役割が一覧で分かります。
最初に覚えるのは、サブネット・ルートテーブル・IGW・NAT ゲートウェイ・セキュリティグループの5つです。 残りは、必要になったときに足す部品です。
サブネット
VPC の IP 範囲を小分けした「部屋」。1つの AZ に属する。サーバーはここに置く。
大きさは /16〜/28
ルートテーブル
「この宛先はこの出口へ」の表。サブネットごとに1つ関連付く。
パブリックかどうかを決める
インターネットゲートウェイ
VPC とインターネットをつなぐ玄関。外と双方向に通信できる。
VPC に1つアタッチ
NAT ゲートウェイ
プライベートサブネットから外へ「出るだけ」の勝手口。外からは入れない。
時間とデータ量で課金
セキュリティグループ
インスタンス(正確にはネットワークインターフェイス)ごとの許可リスト。
戻りの通信は自動で許可
ネットワーク ACL
サブネットの入口の許可・拒否リスト。番号の小さい順に判定。
戻りの通信も書く
| 部品 | 役割 | いつ使う |
|---|---|---|
| Elastic IP | 固定のパブリック IPv4 アドレス | NAT ゲートウェイ(パブリック型・ゾーン型)や、IP を変えたくないサーバー |
| VPC エンドポイント | インターネットを通らずに S3 などの AWS サービスへ行く | プライベートサブネットから S3・DynamoDB・各種 API を使うとき |
| VPC ピアリング | 2つの VPC を1対1でつなぐ | つなぐ VPC が少ないとき |
| Transit Gateway | 多数の VPC・VPN・Direct Connect をつなぐ中継の拠点(ハブ) | VPC が多い、社内網ともつなぐとき |
| Site-to-Site VPN | 社内ネットワークと VPC を暗号化してつなぐ | オンプレミスと AWS を併用するとき |
| VPC フローログ | ネットワークインターフェイスを出入りした通信の記録 | 「届いているか」「どこで拒否されたか」を調べるとき |
サブネットとルートテーブル(パブリックとプライベートの違い)
この節では、VPC のサブネットとは何か、パブリックサブネットとプライベートサブネットが何で決まるのかが分かります。
サブネットは「VPC の IP アドレスの範囲を小分けしたもの」で、必ず1つの AZ の中に収まります。 AWS の公式ドキュメントは「各サブネットは1つの AZ の中に完全に収まり、AZ をまたげない」と書いています。複数の AZ に分けて同じ役割のサブネットを作るのは、AZ が1つ止まっても動き続けるためです。
パブリック/プライベートは「ルートテーブル」で決まる
公式ドキュメントは、サブネットの種類をルーティングの設定で決まるものとして4つに分けています。
| 種類 | ルートテーブルの中身 | できること |
|---|---|---|
| パブリックサブネット | IGW への直接の経路がある(0.0.0.0/0 → igw-…) | インターネットと通信できる(パブリック IP が要る) |
| プライベートサブネット | IGW への直接の経路が無い | 外へ出るには NAT が要る |
| VPN 専用サブネット | 仮想プライベートゲートウェイ経由の VPN への経路だけ | 社内ネットワークとだけ通信 |
| 分離されたサブネット | VPC の外への経路が無い | 同じ VPC の中とだけ通信 |
「パブリックサブネット」というチェックボックスはありません。 サブネットの名前に public と付けても、ルートテーブルに IGW への行が無ければプライベートとして振る舞います。逆に、名前が private でも IGW への行があればパブリックです。
ルートテーブルの読み方
ルートテーブルは「宛先(Destination)」と「ターゲット(Target。次に渡す先)」の2列の表です。VPC を作ると、VPC の範囲あての local の行が必ず入り、VPC の中どうしはこの行で届きます。宛先が重なるときは、いちばん細かい(プレフィックスの長い)行が選ばれます。
| 宛先 | ターゲット | 意味 |
|---|---|---|
| 10.0.0.0/16 | local | VPC の中あては VPC の中で届ける(消せない) |
| 0.0.0.0/0 | igw-… | それ以外は全部インターネットへ(パブリック) |
| 0.0.0.0/0 | nat-… | それ以外は NAT ゲートウェイへ(プライベートの外向き) |
| pl-…(S3 のプレフィックスリスト) | vpce-… | S3 あてはゲートウェイエンドポイントへ |
サブネットに明示的に関連付けたルートテーブルが無いときは、VPC のメインルートテーブルが使われます。メインルートテーブルに IGW への行を足すと、関連付けを忘れたサブネットまでパブリックになるため、メインは local だけにしておき、パブリック用・プライベート用を別に作って明示的に関連付けるのが安全です。
インターネットゲートウェイとNATゲートウェイの違い
この節では、IGW と NAT ゲートウェイがそれぞれ何をして、なぜ両方が要るのかが分かります。
IGW は「外と双方向」、NAT ゲートウェイは「中から外への片道だけ」です。 NAT ゲートウェイについて、公式ドキュメントは「プライベートサブネットのインスタンスは VPC の外のサービスに接続できるが、外のサービスはそのインスタンスへの接続を始められない」と説明しています。
同じ「外へ出る」でも、外から入れるかが違う
見分ける問い:「インターネットから接続を始められてよいか」
IGW は「パブリック IP」と組で働く
IGW をアタッチしてルートテーブルに経路を書いても、サーバー自身にパブリック IPv4 アドレス(または Elastic IP)が無いと、インターネットとは通信できません。 IGW は、プライベート IP とパブリック IP を1対1で付け替える役もしているためです。この点は、後の ip netns の再現で、同じパブリックサブネットにいるのにパブリック IP の無いサーバーだけ外へ出られない様子として確かめます。
NAT ゲートウェイの置き場所と種類
- パブリック型(既定):パブリックサブネットに作り、作成時に Elastic IP を付ける。プライベートサブネットのルートテーブルに「0.0.0.0/0 → nat-…」を書く。
- プライベート型:Elastic IP を付けられない。他の VPC や社内ネットワークへの通信で、送信元アドレスをそろえたいときに使う。
- リージョン型(Regional NAT gateway):公式ドキュメントでは、従来の NAT ゲートウェイを「ゾーン型(zonal)」と呼び分け、リージョン型は AZ をまたいで自動で広がり、パブリックサブネットを要しない独立したリソースと説明しています(プライベート型には対応していません)。
ゾーン型の NAT ゲートウェイは1つの AZ の中で動くため、AZ ごとに NAT を置かないと、その AZ が止まったときに他の AZ のプライベートサブネットも外へ出られなくなります。可用性と料金の釣り合いで、「本番は AZ ごと(またはリージョン型)、開発は1つ」と分けることがよくあります。
VPCをAWS CLIで作った出力(motoで再現)
この節では、VPC からセキュリティグループまでを AWS CLI で作ったときに、実際に何が返るのかが分かります。
本物の AWS には接続せず、moto のサーバーを 127.0.0.1 に起動して、AWS CLI の接続先をそこへ向けました。 鍵はダミーで、設定ファイルも作業場所に置いています。1行ずつの詳しい手順やスクリプト化は、関連記事「AWS CLIでVPCを作成する手順|サブネットからIGWまで一式」で扱っています。この記事では、全体の関係が見える出力にしぼります。
$ moto_server -H 127.0.0.1 -p 51340
* Running on http://127.0.0.1:51340
# 接続先とダミーの鍵(作業場所の設定ファイル)
$ export AWS_ENDPOINT_URL=http://127.0.0.1:51340
$ export AWS_CONFIG_FILE=./aws/config AWS_SHARED_CREDENTIALS_FILE=./aws/credentials
VPC を作る
範囲(CIDR)を決めて作る。メインルートテーブル・デフォルトのセキュリティグループ・ネットワーク ACL が一緒にできる。
サブネットを作る
AZ と範囲を指定する。この時点ではパブリックもプライベートも無い。
IGW を作って VPC にアタッチ
作っただけでは使われない。ルートテーブルに書いて初めて通る。
ルートテーブルを作り、経路を書き、関連付ける
パブリック用に 0.0.0.0/0 → IGW。サブネットに関連付けた時点でパブリックになる。
NAT とプライベート用のルートテーブル
Elastic IP を取り、パブリックサブネットに NAT を作り、プライベート用の表に 0.0.0.0/0 → NAT。
セキュリティグループ
Web 用に 443 を許可、DB 用に「Web のセキュリティグループから 3306」を許可。
VPC の作成
$ aws ec2 create-vpc --cidr-block 10.0.0.0/16 \
--tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=demo-vpc}]'
{
"Vpc": {
"OwnerId": "123456789012",
"InstanceTenancy": "default",
"CidrBlockAssociationSet": [
{
"AssociationId": "vpc-cidr-assoc-dadd6847c734013f5",
"CidrBlock": "10.0.0.0/16",
"CidrBlockState": {
"State": "associated"
}
}
],
"IsDefault": false,
"Tags": [ { "Key": "Name", "Value": "demo-vpc" } ],
"VpcId": "vpc-70b60b71d6b775b56",
"State": "available",
"CidrBlock": "10.0.0.0/16",
"DhcpOptionsId": "default"
}
}
サブネット2つ(同じ AZ にパブリック用とプライベート用)
$ aws ec2 create-subnet --vpc-id $VPC --cidr-block 10.0.1.0/24 \
--availability-zone ap-northeast-1a \
--query 'Subnet.[SubnetId,CidrBlock,AvailabilityZone,AvailableIpAddressCount,MapPublicIpOnLaunch]' --output text
subnet-9efc0c2ac79308a8e 10.0.1.0/24 ap-northeast-1a 251 False
$ aws ec2 create-subnet --vpc-id $VPC --cidr-block 10.0.11.0/24 --availability-zone ap-northeast-1a ...
subnet-e0da279a35999737b 10.0.11.0/24 ap-northeast-1a 251 False
/24 は256個のアドレスですが、使える数(AvailableIpAddressCount)は251でした。 AWS が各サブネットの先頭4つと最後の1つを予約するためで、この計算は後の CIDR の節で確かめます。
IGW・ルートテーブル・NAT を足したあとの表
$ aws ec2 create-internet-gateway --query InternetGateway.InternetGatewayId --output text
igw-58938b2ad0ae7fdee
$ aws ec2 attach-internet-gateway --internet-gateway-id $IGW --vpc-id $VPC
$ aws ec2 create-route --route-table-id $RT_PUB --destination-cidr-block 0.0.0.0/0 --gateway-id $IGW
{
"Return": true
}
$ aws ec2 associate-route-table --route-table-id $RT_PUB --subnet-id $SUBNET_PUB
{
"AssociationId": "rtbassoc-a6e55555485c2e263"
}
$ aws ec2 create-nat-gateway --subnet-id $SUBNET_PUB --allocation-id $EIPALLOC ...
nat-639e5cae6c42d344f subnet-9efc0c2ac79308a8e available 127.175.24.85 10.69.186.135
$ aws ec2 describe-route-tables --filters Name=vpc-id,Values=$VPC --query '...' --output table
+-----------------------+----------------------------+--------------------------------------------------------+
| rtb-755f2f9b2f12549fa| | 10.0.0.0/16->local |
| rtb-08ce56f5959264a2e| subnet-9efc0c2ac79308a8e | 10.0.0.0/16->local| 0.0.0.0/0->igw-58938b2ad0ae7fdee |
| rtb-24311316a2d53d4e6| subnet-e0da279a35999737b | 10.0.0.0/16->local| 0.0.0.0/0->nat-639e5cae6c42d344f |
+-----------------------+----------------------------+--------------------------------------------------------+
1行目が VPC と一緒にできたメインルートテーブル(local だけ)、2行目がパブリック用、3行目がプライベート用です。違いは 0.0.0.0/0 のターゲットが igw- か nat- かの1点だけで、これがパブリックとプライベートの差のすべてです。NAT ゲートウェイの行に出ている 127.175.24.85・10.69.186.135 は moto が作ったダミーの値で、本物の AWS ではサブネットの範囲内のプライベート IP と、割り当てた Elastic IP が入ります。
サブネットがパブリックかどうかを判定するスクリプト
コンソールでサブネットを1つずつ開かなくても、ルートテーブルを読めば判定できます。関連付けの無いサブネットはメインルートテーブルで判定する点が大事です。
import json, subprocess, sys
def aws(*a):
return json.loads(subprocess.check_output(["aws", "ec2", *a, "--output", "json"]))
vpc = sys.argv[1]
rts = aws("describe-route-tables", "--filters", f"Name=vpc-id,Values={vpc}")["RouteTables"]
main = next(r for r in rts if any(x.get("Main") for x in r["Associations"]))
def kind(rt):
for r in rt["Routes"]:
if r.get("DestinationCidrBlock") == "0.0.0.0/0":
if (r.get("GatewayId") or "").startswith("igw-"):
return "パブリック(0.0.0.0/0 -> " + r["GatewayId"] + ")"
if r.get("NatGatewayId"):
return "プライベート(外向きのみ NAT " + r["NatGatewayId"] + ")"
return "プライベート(外へ出る経路なし)"
for s in aws("describe-subnets", "--filters", f"Name=vpc-id,Values={vpc}")["Subnets"]:
rt = next((r for r in rts if any(x.get("SubnetId") == s["SubnetId"] for x in r["Associations"])), main)
print(s["SubnetId"], s["CidrBlock"], s["AvailabilityZone"], rt["RouteTableId"], kind(rt))
subnet-9efc0c2ac79308a8e 10.0.1.0/24 ap-northeast-1a rtb-08ce56f5959264a2e パブリック(0.0.0.0/0 -> igw-58938b2ad0ae7fdee)
subnet-e0da279a35999737b 10.0.11.0/24 ap-northeast-1a rtb-24311316a2d53d4e6 プライベート(外向きのみ NAT nat-639e5cae6c42d344f)
subnet-66ec7b61d1dc09386 10.0.12.0/24 ap-northeast-1c rtb-755f2f9b2f12549fa プライベート(外へ出る経路なし)
3行目は、関連付けをせずに足したサブネットです。メインルートテーブル(local だけ)が使われ、「分離されたサブネット」として判定されました。
セキュリティグループ(Web から DB だけを許可)
$ aws ec2 authorize-security-group-ingress --group-id $SG_WEB --protocol tcp --port 443 --cidr 0.0.0.0/0 \
--query 'SecurityGroupRules[].[IsEgress,IpProtocol,FromPort,ToPort,CidrIpv4]' --output text
False tcp 443 443 0.0.0.0/0
$ aws ec2 authorize-security-group-ingress --group-id $SG_DB --protocol tcp --port 3306 --source-group $SG_WEB ...
False tcp 3306 3306 sg-3403c37a6a9f100dc
$ aws ec2 describe-security-groups --group-ids $SG_DB --query 'SecurityGroups[0].IpPermissionsEgress'
[ { "IpProtocol": "-1", "IpRanges": [ { "CidrIp": "0.0.0.0/0" } ], ... } ]
DB 側は送信元を IP アドレスではなく「Web のセキュリティグループ」で指定しています。Web サーバーが増えても減っても、DB のルールを書き換えずに済みます。新しいセキュリティグループには、外向き(アウトバウンド)を全部許可するルールが最初から入っていました。セキュリティグループの操作の詳細は、関連記事「AWS CLIでセキュリティグループ設定|ルール追加・削除・確認」で扱っています。
moto と本物の AWS の違い(手元で気づいた点)
- moto は /29 のサブネットを作成できた(使える数3)。公式ドキュメントでは、サブネットの大きさは /28〜/16 で、/29 は作れない。
- moto のデフォルト VPC には IGW への経路が無かった。本物のデフォルト VPC は、メインルートテーブルに 0.0.0.0/0 → IGW が入る(公式ドキュメント)。
- 削除の依存関係の一部(他のセキュリティグループから参照されているグループの削除など)を moto は止めなかった。依存関係の順番は公式ドキュメントに合わせて書いている。
パブリックとプライベートの違いをip netnsで再現(ping・ip route)
この節では、パブリックサブネットのサーバーは外へ出られ、プライベートサブネットのサーバーは出られない理由を、実際のパケットで確かめられます。
moto は API の応答だけを返すので、通信そのものは起きません。 そこで Linux の ip netns で7つの小部屋を作り、VPC と同じ形のネットワークを手元に組みました。インターネット側のアドレスには、文書用に予約された 203.0.113.0/24・198.51.100.0/24 を使っています。
| netns の名前 | VPC での役 | アドレス |
|---|---|---|
| t134-pub | パブリックサブネットの Web(パブリック IP あり) | 10.0.1.10(外からは 198.51.100.10) |
| t134-pub2 | パブリックサブネットだがパブリック IP なし | 10.0.1.30 |
| t134-nat | NAT ゲートウェイ(Elastic IP あり) | 10.0.1.20(外からは 198.51.100.20) |
| t134-pri | プライベートサブネットのサーバー | 10.0.11.10 |
| t134-vrt | VPC ルーター(サブネットごとのルートテーブル) | 10.0.1.1・10.0.11.1 |
| t134-igw | IGW(パブリック IP ⇔ プライベート IP の1対1変換) | — |
| t134-inet | インターネット上のサーバー | 203.0.113.10 |
「サブネットごとのルートテーブル」は、Linux の ip rule(どの表を引くかの規則)で、入ってきたインターフェイスごとに別の表を引くようにして再現しました。表 101 がパブリック用、表 111 がプライベート用です。
$ ip netns exec t134-vrt ip rule
0: from all lookup local
1000: from all iif br-pub lookup 101
1100: from all iif sub-pri lookup 111
32766: from all lookup main
32767: from all lookup default
$ ip netns exec t134-vrt ip route show table 101 # パブリック用
default via 169.254.0.2 dev to-igw
10.0.1.0/24 dev br-pub scope link
10.0.11.0/24 dev sub-pri scope link
$ ip netns exec t134-vrt ip route show table 111 # プライベート用(最初は外への経路なし)
10.0.1.0/24 dev br-pub scope link
10.0.11.0/24 dev sub-pri scope link
サーバー自身の ip route は、パブリックでもプライベートでも「既定の出口はサブネットの .1(VPC ルーター)」で同じです。AWS でも、インスタンスの OS から見た経路はサブネットの種類で変わりません。違いは VPC ルーター側の表にあります。
$ ip netns exec t134-pub ip route
default via 10.0.1.1 dev eth0
10.0.1.0/24 dev eth0 proto kernel scope link src 10.0.1.10
$ ip netns exec t134-pri ip route
default via 10.0.11.1 dev eth0
10.0.11.0/24 dev eth0 proto kernel scope link src 10.0.11.10
結果1:パブリックは外へ出られる、プライベートは出られない
$ ip netns exec t134-pub ping -c 3 -W 1 203.0.113.10
64 bytes from 203.0.113.10: icmp_seq=1 ttl=62 time=0.428 ms
64 bytes from 203.0.113.10: icmp_seq=2 ttl=62 time=0.076 ms
64 bytes from 203.0.113.10: icmp_seq=3 ttl=62 time=0.060 ms
3 packets transmitted, 3 received, 0% packet loss, time 2051ms
$ ip netns exec t134-pri ping -c 3 -W 1 203.0.113.10
From 10.0.11.1 icmp_seq=1 Destination Net Unreachable
From 10.0.11.1 icmp_seq=2 Destination Net Unreachable
From 10.0.11.1 icmp_seq=3 Destination Net Unreachable
3 packets transmitted, 0 received, +3 errors, 100% packet loss, time 2030ms
$ ip netns exec t134-pri ping -c 2 -W 1 10.0.1.10 # VPC の中どうしは届く(local の経路)
64 bytes from 10.0.1.10: icmp_seq=1 ttl=63 time=0.032 ms
2 packets transmitted, 2 received, 0% packet loss, time 1020ms
プライベート側は、VPC ルーター(10.0.11.1)が「その宛先への経路が無い」と返しました。VPC の中(10.0.1.10)には届くので、「VPC の中は local で届く、外へは表に行が無いと出られない」がそのまま見えます。AWS の VPC ルーターが同じ ICMP を返すかは公式ドキュメントに書かれていないため、ここでは「どこで止まったか」を見る目的で、Linux の既定の動きのまま示しています。
結果2:外からはパブリック IP にだけ届く
$ ip netns exec t134-inet ping -c 2 -W 1 198.51.100.10 # Web のパブリック IP
64 bytes from 198.51.100.10: icmp_seq=1 ttl=62 time=0.103 ms
2 packets transmitted, 2 received, 0% packet loss, time 1008ms
$ ip netns exec t134-inet ping -c 2 -W 1 10.0.11.10 # プライベート IP あて
ping: connect: Network is unreachable
インターネット側から見ると、10.0.11.10 のようなプライベート IP には経路そのものがありません。プライベートサブネットが外から守られているのは、設定で隠しているからではなく、外から指す宛先が存在しないからです。
結果3:パブリックサブネットでもパブリック IP が無いと出られない
$ ip netns exec t134-pub2 ping -c 2 -W 1 203.0.113.10
2 packets transmitted, 0 received, 100% packet loss, time 1009ms
# VPC ルーター → IGW の間では見える
$ ip netns exec t134-vrt tcpdump -n -i to-igw icmp
IP 10.0.1.30 > 203.0.113.10: ICMP echo request, id 21380, seq 1, length 64
IP 10.0.1.30 > 203.0.113.10: ICMP echo request, id 21380, seq 2, length 64
# インターネット側には1つも届かない
$ ip netns exec t134-inet tcpdump -n -i eth0 icmp
0 packets captured
10.0.1.30 は同じパブリックサブネットにいて、同じルートテーブルで IGW まで行きます。それでも、付け替える先のパブリック IP が無いので、IGW の先へは出られません。 EC2 を「パブリックサブネットに置いたのにインターネットにつながらない」ときは、パブリック IP の自動割り当て(サブネットの MapPublicIpOnLaunch、起動時の設定)を見ます。
結果4:NAT への経路を足すと、プライベートから外へ出られる
プライベート用の表 111 に「0.0.0.0/0 → NAT(10.0.1.20)」を1行足しました。AWS で create-route --nat-gateway-id をするのと同じ操作です。
$ ip netns exec t134-vrt ip route add default via 10.0.1.20 table 111
$ ip netns exec t134-vrt ip route get 203.0.113.10 from 10.0.11.10 iif sub-pri
203.0.113.10 from 10.0.11.10 via 10.0.1.20 dev br-pub table 111
$ ip netns exec t134-pri ping -c 2 -W 1 203.0.113.10
64 bytes from 203.0.113.10: icmp_seq=1 ttl=60 time=0.095 ms
64 bytes from 203.0.113.10: icmp_seq=2 ttl=60 time=0.073 ms
2 packets transmitted, 2 received, 0% packet loss, time 1010ms
同じ1回の ping を、3か所で同時に tcpdump しました。送信元のアドレスが2回付け替わる様子が分かります。
# (1) プライベートのサーバーの中
IP 10.0.11.10 > 203.0.113.10: ICMP echo request, id 21363, seq 1, length 64
IP 203.0.113.10 > 10.0.11.10: ICMP echo reply, id 21363, seq 1, length 64
# (2) VPC ルーター → IGW の間(NAT が自分のプライベート IP に付け替えた)
IP 10.0.1.20 > 203.0.113.10: ICMP echo request, id 21363, seq 1, length 64
IP 203.0.113.10 > 10.0.1.20: ICMP echo reply, id 21363, seq 1, length 64
# (3) インターネット側(IGW が NAT の Elastic IP に付け替えた)
IP 198.51.100.20 > 203.0.113.10: ICMP echo request, id 21363, seq 1, length 64
IP 203.0.113.10 > 198.51.100.20: ICMP echo reply, id 21363, seq 1, length 64
1差はルートテーブルの1行
サーバー側の設定は同じまま、VPC ルーターの表に IGW か NAT の行があるかで、出られる・出られないが変わった。
2パブリック IP が無いと IGW を越えない
同じパブリックサブネットでも、パブリック IP の無い 10.0.1.30 は IGW の手前で止まった。
3外から見えるのは Elastic IP だけ
プライベートのサーバーの通信は、外では NAT の 198.51.100.20 として見える。外部 API に許可 IP を登録するときはこの値。
VPCのCIDRとサブネットの決め方(Python ipaddressで計算)
この節では、VPC とサブネットの IP アドレスの範囲(CIDR)をどう決めればよいかが、計算つきで分かります。
CIDR(サイダー)は「10.0.0.0/16」のように、先頭からのビット数でネットワークの大きさを表す書き方です。 /16 なら先頭16ビットが固定で、残り16ビット分=65,536個のアドレスを持ちます。数字が1増えると大きさは半分になります。
決まり(公式ドキュメント)
- VPC の IPv4 CIDR は /16(65,536個)〜/28(16個)。RFC 1918 のプライベートアドレス(10.0.0.0/8・172.16.0.0/12・192.168.0.0/16)から取るのが推奨。
- サブネットも /16〜/28。VPC の範囲の中で、サブネットどうしは重ねられない。
- 各サブネットの先頭4つと最後の1つは AWS の予約で使えない。
- 既にある CIDR の大きさは変えられない。足りなくなったら、セカンダリ CIDR を追加する(最初の CIDR は外せない)。
import ipaddress as ip
for p in (16, 18, 20, 22, 24, 26, 27, 28):
n = ip.ip_network(f"10.0.0.0/{p}")
print(f"/{p}: 全体 {n.num_addresses:>6} 使える {n.num_addresses-5:>6} マスク {n.netmask}")
/16: 全体 65536 使える 65531 マスク 255.255.0.0
/18: 全体 16384 使える 16379 マスク 255.255.192.0
/20: 全体 4096 使える 4091 マスク 255.255.240.0
/22: 全体 1024 使える 1019 マスク 255.255.252.0
/24: 全体 256 使える 251 マスク 255.255.255.0
/26: 全体 64 使える 59 マスク 255.255.255.192
/27: 全体 32 使える 27 マスク 255.255.255.224
/28: 全体 16 使える 11 マスク 255.255.255.240
/24 の「使える 251」は、moto の AvailableIpAddressCount(251)とも一致しました。予約される5つは次のとおりです(公式ドキュメントの 10.0.0.0/24 の例を 10.0.1.0/24 に当てはめたもの)。
10.0.1.0 ネットワークアドレス
10.0.1.1 VPC ルーター
10.0.1.2 DNS(VPC の範囲の先頭+2。各サブネットの+2も予約)
10.0.1.3 将来の予約
10.0.1.255 ブロードキャスト(VPC はブロードキャスト非対応のため予約)
3つの AZ × パブリック/プライベートに分ける例
vpc = ip.ip_network("10.0.0.0/16")
subs = list(vpc.subnets(new_prefix=20))
plan = {"public-a": subs[0], "public-c": subs[1], "public-d": subs[2],
"private-a": subs[4], "private-c": subs[5], "private-d": subs[6]}
16 個: 10.0.0.0/20, 10.0.16.0/20, 10.0.32.0/20, 10.0.48.0/20, 10.0.64.0/20, 10.0.80.0/20 ...
public-a 10.0.0.0/20 使える 4091
public-c 10.0.16.0/20 使える 4091
public-d 10.0.32.0/20 使える 4091
private-a 10.0.64.0/20 使える 4091
private-c 10.0.80.0/20 使える 4091
private-d 10.0.96.0/20 使える 4091
残り: 10 個の /20
パブリックとプライベートの間(10.0.48.0/20)を1つ空けておくと、あとで4つ目の AZ を足しても番号の並びがそろいます。EKS(Kubernetes)や Lambda を VPC で動かすと、Pod や関数の数だけ IP を使うことがあるため、プライベート側は大きめに取ります。
重なりの確認
CIDR でいちばん困るのは「あとでつなぐ相手と重なる」ことです。 VPC ピアリングは重なる CIDR どうしでは作れず、社内ネットワークと VPN でつなぐときも経路が決められなくなります。作る前に、社内・他の VPC・開発 PC の Docker などの範囲と重ならないかを確かめます。
for a, b in [("10.0.0.0/16", "10.0.128.0/17"), ("10.0.0.0/16", "10.1.0.0/16"),
("10.0.0.0/16", "10.0.0.0/8"), ("172.31.0.0/16", "172.16.0.0/12"),
("172.17.0.0/16", "172.31.0.0/16")]:
print(a, "と", b, "重なる" if ip.ip_network(a).overlaps(ip.ip_network(b)) else "重ならない")
10.0.0.0/16 と 10.0.128.0/17 重なる
10.0.0.0/16 と 10.1.0.0/16 重ならない
10.0.0.0/16 と 10.0.0.0/8 重なる
172.31.0.0/16 と 172.16.0.0/12 重なる
172.17.0.0/16 と 172.31.0.0/16 重ならない
どの VPC も 10.0.0.0/16 で作ると、あとでつなげなくなります。「VPC ごとに 10.1.0.0/16・10.2.0.0/16…と番号を割り振る表」をチームで1つ持つのが確実です。AWS には、この割り振りを管理する VPC IP Address Manager(IPAM)もあります。なお、Python の is_private は RFC 1918 以外(文書用の 203.0.113.0/24 など)にも True を返したため、RFC 1918 かどうかの判定には使えませんでした。CIDR とサブネットマスクの計算をさらに詳しく知りたいときは、関連記事「CIDR計算・サブネット早見表|/0〜/32一覧とPython計算コード」で扱っています。
セキュリティグループとネットワークACLの違い
この節では、2つのファイアウォールの違いと、ステートフル・ステートレスの差が通信にどう出るのかが、実測で分かります。
公式ドキュメントの比較表を日本語にまとめると次のとおりです。
| 項目 | セキュリティグループ | ネットワーク ACL |
|---|---|---|
| 効く場所 | インスタンス(ネットワークインターフェイス) | サブネット |
| ルールの種類 | 許可だけ | 許可と拒否 |
| 判定の仕方 | すべてのルールを見て決める | 番号の小さい順に、最初に合ったもので決める |
| 戻りの通信 | 自動で許可(ステートフル) | 明示的に許可が要る(ステートレス) |
| 既定のクォータ | 1インターフェイスに5つ、1グループに入・出それぞれ60ルール | 入・出それぞれ20ルール(最大40) |
セキュリティグループで絞るもの
サーバーの役割ごとの許可(Web は 443、DB は Web からだけ)
送信元にセキュリティグループを指定できる
ふだんの制御はこちらが中心
ネットワーク ACL で絞るもの
サブネット全体で特定の IP やポートを拒否
拒否のルールが書ける唯一の場所
戻りの通信(エフェメラルポート)も書く
実測:ステートフル(SG)は戻りを書かなくても通る
ip netns の Web サーバー(t134-pub)で 8080 番の HTTP サーバーを起動し、セキュリティグループの代わりに「受信は既定で拒否、8080 と接続済みの戻りだけ許可」のルールを入れました。
ルールなし 8080 → code=200 time=0.003392
ルールなし 22 → curl: (7) Failed to connect to 198.51.100.10 port 22 after 0 ms: Couldn't connect to server
SG 相当あり 8080 → code=200 time=0.002363
SG 相当あり 22 → curl: (28) Connection timed out after 3001 milliseconds
許可していない 22 番は、「接続を拒否された(すぐ返る)」から「時間切れ(3秒待って失敗)」に変わりました。 AWS のセキュリティグループも、許可していない通信には何も返さず捨てるため、接続できないときに「タイムアウトする」のは、セキュリティグループかネットワーク ACL で止まっている合図です。「Connection refused」がすぐ返るなら、通信はサーバーまで届いていて、そのポートでプログラムが待ち受けていません。
実測:ステートレス(NACL)は戻りのポートを書かないと通らない
次に、パブリックサブネットの入口(VPC ルーター)に NACL 相当のルールを入れました。受信は「8080 を許可」、送信は「443 を許可、それ以外は拒否」です。一見、Web サーバーへの 8080 は通りそうです。
NACL 送信が 443 だけ → curl: (28) Connection timed out after 3002 milliseconds
4 240 DROP /* * deny */ ← 応答のパケットが捨てられた
送信に 1024-65535 を足した → code=200 time=0.002515
6 527 ACCEPT tcp dpts:1024:65535 /* 110 allow tcp 1024-65535 */
Web サーバーからの応答は、宛先がクライアント側の一時的なポート(エフェメラルポート)になります。手元のクライアントの範囲は net.ipv4.ip_local_port_range = 32768 60999 でした。NACL は戻りを覚えていないので、この範囲を送信側で許可しないと、応答が捨てられて時間切れになります。 公式ドキュメントは、クライアントの OS によって範囲が違う(多くの Linux は 32768-61000、Windows Server 2008 以降は 49152-65535、NAT ゲートウェイと ELB は 1024-65535)ことから、1024-65535 を開け、拒否したいポートはそれより前の番号で拒否する方法を示しています。
同じ NACL を付けたまま、プライベートのサーバーから NAT 経由で外へ HTTP を送ると、これも時間切れになりました。NAT はパブリックサブネットにいるので、プライベートのサーバーの通信もパブリックサブネットの NACL を通ります。 送信側に宛先 8080、受信側に 1024-65535 を足すと、応答が戻ってくるようになりました。
デフォルトVPCとは(そのまま使ってよいか)
この節では、アカウントに最初からある VPC が何で、どう扱えばよいかが分かります。
AWS アカウントには、リージョンごとにデフォルト VPC が1つ用意されていて、作ってすぐ EC2 を起動して接続できるように設定されています。 公式ドキュメントが挙げる中身は次のとおりです。
- 172.31.0.0/16 の VPC(最大65,536個のプライベート IPv4 アドレス)
- AZ ごとに /20 のデフォルトサブネット(1つあたり4,096個、うち数個は予約)
- インターネットゲートウェイをアタッチ
- メインルートテーブルに 0.0.0.0/0 → IGW の経路
- デフォルトのセキュリティグループ、デフォルトのネットワーク ACL、デフォルトの DHCP オプションセット
moto のデフォルト VPC も、AZ ごとに /20 のサブネットが3つ並び、それぞれ使える数は 4,091、MapPublicIpOnLaunch は True でした。
| ap-northeast-1a | 172.31.0.0/20 | True | 4091 |
| ap-northeast-1c | 172.31.16.0/20 | True | 4091 |
| ap-northeast-1d | 172.31.32.0/20 | True | 4091 |
デフォルト VPC は、すべてのサブネットがパブリックです。 学習や短い検証には便利ですが、DB や社内向けのサーバーを置く本番の環境には、プライベートサブネットを持つ VPC を別に作るのが一般的です。また、デフォルト VPC の範囲は 172.31.0.0/16 なので、他の VPC や社内網とつなぐ予定があるなら重なりに注意します。デフォルト VPC は削除できますが、ロードバランサーや RDS の作成時にデフォルト VPC を前提にする画面もあるため、消す前にチームで使い道を決めておきます。
VPCエンドポイント・ピアリング・Transit Gatewayの概要
この節では、VPC を「AWS のサービス」「他の VPC」「社内網」とつなぐ部品の違いが分かります。
VPC エンドポイント(AWS のサービスへ、インターネットを通らずに)
- ゲートウェイエンドポイント:S3 と DynamoDB 用。ルートテーブルに「S3 のプレフィックスリスト → vpce-…」の行が入る。追加料金なし(公式ドキュメント)。
- インターフェイスエンドポイント(PrivateLink):多くの AWS サービス用。サブネットにネットワークインターフェイスが作られ、時間とデータ量で課金される。
プライベートサブネットから S3 へ大量のデータを送るとき、NAT ゲートウェイ経由だとデータ処理の料金がかかります。ゲートウェイエンドポイントを付ければ、S3 あての通信は NAT を通らなくなります。
VPC ピアリングと Transit Gateway
| 項目 | VPC ピアリング | Transit Gateway |
|---|---|---|
| つなぎ方 | 2つの VPC を1対1 | 中央のハブに各 VPC・VPN・Direct Connect をつなぐ |
| 推移的なルーティング | 不可(A-B・A-C があっても B から C へは行けない) | ハブ経由で行ける(ルートテーブルで制御) |
| CIDR の重なり | 重なる VPC どうしは作れない | 重なると経路を決められない |
| 料金の形 | 接続の時間料金なし。AZ をまたぐデータ転送に料金 | アタッチメントの時間料金+データ処理料金 |
| 向いている規模 | VPC が数個 | VPC が多い、社内網ともつなぐ |
ピアリングの公式ドキュメントには、相手の VPC の IGW・NAT・VPN・Direct Connect・ゲートウェイエンドポイントを経由して外へ出ることもできない(edge to edge routing の不可)と書かれています。「VPC A の NAT を VPC B からも使って節約する」構成は、ピアリングではできません。
VPCの料金の考え方(2026年10月29日時点)
この節では、VPC で何にお金がかかり、何が無料なのかが分かります。
公式ドキュメントは「VPC の利用に追加料金はかからない。ただし NAT ゲートウェイ・IPAM・トラフィックミラーリング・Reachability Analyzer・Network Access Analyzer などの部品には料金がかかる」と書いています。 VPC・サブネット・ルートテーブル・IGW・セキュリティグループ・ネットワーク ACL を作るだけなら料金はかかりません。
| 部品 | 料金の形 | 公式ページの値(2026年10月29日時点) |
|---|---|---|
| NAT ゲートウェイ | 時間+処理したデータ量 | 料金ページの例(米国東部・オハイオ):1時間 0.045 USD、1GB 0.045 USD。リージョン型は AZ ごとに時間料金 |
| パブリック IPv4 アドレス | 1つあたりの時間 | 使用中・アイドルとも 1時間 0.005 USD(商用リージョン共通) |
| ゲートウェイエンドポイント | なし | 追加料金なし(S3・DynamoDB) |
| インターフェイスエンドポイント | AZ ごとの時間+データ量 | データ処理は最初の 1PB まで 1GB 0.01 USD(リージョン内の合計) |
| VPC ピアリング | データ転送 | 同じリージョンで AZ をまたぐと、送受信それぞれ 1GB 0.01 USD |
| Transit Gateway | アタッチメントの時間+データ処理 | 料金ページの例(米国東部・オハイオ):VPC アタッチメント 1時間 0.05 USD、1GB 0.02 USD |
料金はリージョンで違い、NAT ゲートウェイ・インターフェイスエンドポイント・Transit Gateway の東京リージョン(ap-northeast-1)の値は、料金ページでリージョンを選んだときに表示されます。この表の米国東部の値は、料金ページに載っている計算例の値です。見積もりは、料金ページでリージョンを「アジアパシフィック(東京)」に切り替えるか、AWS Pricing Calculator で行います。
費用が大きくなりやすいところ
- NAT ゲートウェイは、使っていなくても時間料金がかかる。 AZ ごとに置くと、その数だけかかる。夜間に止められる開発環境では、NAT を置かない構成や VPC エンドポイントの利用を検討する。
- NAT を通るデータ量にも料金がかかる。 S3 への大量転送はゲートウェイエンドポイント(無料)に逃がす。
- パブリック IPv4 アドレスは、使用中でも有料。 公式ドキュメントによれば、RFC 1918 のプライベート IPv4 には料金がかからない。EC2 の無料利用枠では、パブリック IPv4 の750時間分が無料。
よくあるエラーとつまずき(原文つき)
この節では、VPC を作るとき・使うときに出るエラーの原文と、原因・直し方が分かります。
| 出た文言・症状 | 原因 | 直し方 |
|---|---|---|
| InvalidSubnet.Conflict:The CIDR '10.0.1.128/25' conflicts with another subnet | 既にあるサブネットと範囲が重なる | 重ならない範囲を選ぶ(計算は Python の overlaps で確かめる) |
| InvalidSubnet.Range:The CIDR '10.1.0.0/24' is invalid. | サブネットが VPC の範囲の外 | VPC の CIDR の内側で切る。足りなければセカンダリ CIDR を追加 |
| InvalidVpc.Range:The CIDR '10.0.0.0/15' is invalid. | VPC の大きさが /16〜/28 の外(/15・/29 で出た) | /16〜/28 にする |
| DependencyViolation:The vpc '…' has dependencies and cannot be deleted. | 中にサブネット・IGW・NAT などが残っている | 作った順の逆に消す(次の手順) |
| DependencyViolation:igw-… is being utilized by vpc-… | VPC にアタッチしたまま IGW を消そうとした | detach-internet-gateway してから削除 |
| InvalidPermission.Duplicate:The specified rule already exists | 同じルールをもう一度足した | describe-security-groups で今のルールを見てから足す |
| InvalidInternetGatewayID.NotFound | 経路のターゲットに存在しない IGW の ID | ID の写し間違い・別リージョンを確かめる |
| ping・curl が時間切れになる | SG・NACL で捨てられている、またはパブリック IP・経路が無い | 経路→パブリック IP→SG→NACL の順に見る |
エラーの文言は moto 5.1.22 が返したものです。本物の AWS も同じエラーコード(InvalidSubnet.Conflict など)を返しますが、メッセージの細かい文面は違うことがあります。
削除の順番(依存関係の逆)
1 NAT ゲートウェイを削除 delete-nat-gateway
2 Elastic IP を解放 release-address
3 IGW をデタッチして削除 detach-internet-gateway → delete-internet-gateway
4 サブネットを削除 delete-subnet
5 ルートテーブルの関連付けを外して削除 disassociate-route-table → delete-route-table
6 セキュリティグループを削除(参照している側から) delete-security-group
7 VPC を削除 delete-vpc
手元ではこの順で消し、最後の delete-vpc が成功して、残ったのはデフォルト VPC だけになりました。消し忘れると料金が続くのは NAT ゲートウェイと Elastic IP(パブリック IPv4)です。
つながらないときのチェック
- 1サブネットのルートテーブルを見る関連付けが無ければメインルートテーブルが使われる。0.0.0.0/0 のターゲットが igw- か nat- か
- 2パブリック IP が付いているかパブリックサブネットでもパブリック IP が無いと IGW を越えない(手元の再現でも止まった)
- 3セキュリティグループの受信ルール時間切れなら SG か NACL を疑う。Connection refused がすぐ返るなら届いている
- 4NACL の戻りのポート送信側・受信側に 1024-65535 が無いと応答が捨てられる。NAT のいるサブネットの NACL も通る
- 5NAT ゲートウェイの置き場所ゾーン型はパブリックサブネットに置く。プライベートサブネットに置くと外へ出られない
- 6OS の中のファイアウォールAWS 側が正しくても、OS の firewalld・ufw・Windows ファイアウォールで止まることがある
原因の切り分けの考え方は、関連記事「穴だらけにしない!AWSネットワークセキュリティの定石!」も参考になります。
VPC構成の判断表
この節では、作りたいものに対して、どのサブネットと部品を選べばよいかが分かります。
- 1インターネットから直接アクセスされる → パブリックサブネットロードバランサー・NAT ゲートウェイ(ゾーン型)・踏み台。パブリック IP が要る
- 2外へは出るが、外からは入られたくない → プライベート+NATアプリサーバー・バッチ。OS の更新や外部 API の呼び出し
- 3AWS のサービスとだけ話す → プライベート+VPC エンドポイントS3・DynamoDB はゲートウェイ型(無料)。NAT の費用を減らせる
- 4VPC の中とだけ話す → 分離されたサブネットDB(RDS)など。外への経路を持たない
- 5社内ネットワークとつなぐ → VPN または Direct ConnectCIDR を社内と重ねないことが前提
- 6他の VPC とつなぐ → 数個ならピアリング、多いなら Transit Gatewayピアリングは推移的なルーティング不可
| 場面 | おすすめの形 | 理由 |
|---|---|---|
| AWS の学習・短い検証 | デフォルト VPC か、パブリックサブネット1つ | NAT が要らず、料金がかかる部品が少ない |
| 小さな Web サービス | 2AZ × パブリック/プライベート、NAT は1つ | 可用性と費用の釣り合い。NAT の AZ が止まると外へ出られない点は受け入れる |
| 止められない本番 | 3AZ × パブリック/プライベート、NAT は AZ ごと(またはリージョン型) | 1つの AZ の障害で外向きの通信が止まらない |
| S3 を大量に読み書きする | ゲートウェイエンドポイントを追加 | NAT のデータ処理料金がかからない |
| サーバーに SSH したい | 踏み台より Session Manager | 受信ポートを開けずに済み、プライベートのまま接続できる |
| VPC が今後も増える | CIDR の割り振り表を先に作る(または IPAM) | あとから CIDR は変えられず、重なるとつなげない |
プライベートサブネットのサーバーへ、受信ポートを開けずに入る方法は、関連記事「Session ManagerでEC2に接続する方法|SSH鍵なしの手順」で扱っています。グローバル IP とプライベート IP、NAT の基本は、関連記事「グローバルIPの確認方法|コマンド・プライベートIPとの違いとNATを実演」で扱っています。
よくある質問
Q. VPCとは何ですか? A. AWS の中に作る、論理的に切り離された自分専用の仮想ネットワークです。IP アドレスの範囲・サブネット・経路・出入り口・通してよい通信を自分で決め、その中に EC2 や RDS などを置きます。
Q. VPC とサブネットの違いは何ですか? A. VPC は全体の敷地(例:10.0.0.0/16)、サブネットはそれを小分けした部屋(例:10.0.1.0/24)です。VPC はリージョン単位、サブネットは AZ 単位で、サーバーはサブネットに置きます。
Q. パブリックサブネットとプライベートサブネットはどう作り分けますか? A. 作るときの設定は同じです。作ったあと、関連付けるルートテーブルに「0.0.0.0/0 → インターネットゲートウェイ」があればパブリック、無ければプライベートになります。
Q. NAT ゲートウェイは必ず要りますか? A. プライベートサブネットのサーバーがインターネットへ出る必要があるときだけ要ります。AWS のサービスとだけ話すなら VPC エンドポイントで代わりになることがあり、外へ一切出ないなら要りません。
Q. VPC の料金はいくらですか? A. VPC 自体の利用に追加料金はありません。NAT ゲートウェイ(時間+データ量)、パブリック IPv4 アドレス(1時間 0.005 USD)、インターフェイスエンドポイント、Transit Gateway などの部品に料金がかかります(2026年10月29日時点の公式ページ)。
Q. VPC の CIDR はどれくらいの大きさにすればよいですか? A. 迷ったら /16 を取り、AZ と役割ごとに /20〜/24 に分けます。既にある CIDR の大きさは変えられないため、小さく作って困るより大きめが安全です。他の VPC や社内網と重ならない範囲を選びます。
Q. サブネットで使える IP アドレスが5つ少ないのはなぜですか? A. AWS が各サブネットの先頭4つ(ネットワークアドレス・VPC ルーター・DNS・将来用)と最後の1つ(ブロードキャスト)を予約しているためです。/24 なら 256−5=251 個です。
Q. セキュリティグループとネットワーク ACL はどちらを使えばよいですか? A. ふだんの制御はセキュリティグループで行います。ネットワーク ACL は、サブネット全体で特定の IP やポートを拒否したいときに足します。NACL は戻りの通信も書く必要があり、エフェメラルポート(1024-65535)を忘れると通信が時間切れになります。
Q. デフォルト VPC は削除してもよいですか? A. 削除できますが、デフォルト VPC を前提にしたサービスの画面や、使っている人がいないかを先に確かめます。削除したあとでも、新しいデフォルト VPC を作り直す操作が用意されています。
Q. EC2 をパブリックサブネットに置いたのにインターネットにつながりません。 A. パブリック IP(または Elastic IP)が付いているか、サブネットのルートテーブルに IGW への経路があるか、セキュリティグループと NACL を順に見ます。手元の再現でも、パブリック IP の無いサーバーだけは IGW の先へ出られませんでした。
Q. VPC ピアリングで3つの VPC を順につなげば、端から端まで通信できますか? A. できません。ピアリングは推移的なルーティングに対応しておらず、A-B と A-C があっても B から C へは行けません。B-C にもピアリングを作るか、Transit Gateway を使います。
Q. VPC を作る練習を、料金をかけずにできますか? A. VPC・サブネット・ルートテーブル・IGW・セキュリティグループは作るだけなら料金がかかりません。NAT ゲートウェイと Elastic IP は時間で課金されるため、練習のあとは削除します。この記事のように、moto を 127.0.0.1 で動かせば AWS に接続せずに AWS CLI の操作を試せます。
まとめ
- Amazon VPC は、AWS の中に作る自分専用の仮想ネットワーク。VPC はリージョン単位、サブネットは AZ 単位。
- パブリックとプライベートは、サブネットのルートテーブルに「0.0.0.0/0 → IGW」があるかで決まる。手元の再現でも、差はルーターの表の1行だった。
- IGW は双方向で、パブリック IP と組で働く。NAT ゲートウェイは中から外への片道で、外からは入られない。tcpdump では送信元が 10.0.11.10 → 10.0.1.20 → 198.51.100.20 と2回付け替わった。
- CIDR は /16〜/28。各サブネットの5つは予約。大きさはあとから変えられず、他の VPC・社内網と重ねない。
- セキュリティグループはステートフル、NACL はステートレス。NACL はエフェメラルポートを書かないと応答が捨てられ、時間切れになる。料金は VPC 自体は無料で、NAT ゲートウェイとパブリック IPv4 が主な費用。
参考・出典
確認日はいずれも 2026年10月29日です。
- AWS「What is Amazon VPC?」:https://docs.aws.amazon.com/vpc/latest/userguide/what-is-amazon-vpc.html
- AWS「VPC CIDR blocks」:https://docs.aws.amazon.com/vpc/latest/userguide/vpc-cidr-blocks.html
- AWS「Subnet CIDR blocks」:https://docs.aws.amazon.com/vpc/latest/userguide/subnet-sizing.html
- AWS「Subnets for your VPC」(Subnet types):https://docs.aws.amazon.com/vpc/latest/userguide/configure-subnets.html
- AWS「Default VPC components」:https://docs.aws.amazon.com/vpc/latest/userguide/default-vpc-components.html
- AWS「NAT gateways」:https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html
- AWS「Regional NAT gateways」:https://docs.aws.amazon.com/vpc/latest/userguide/nat-gateways-regional.html
- AWS「Infrastructure security in Amazon VPC」(セキュリティグループとネットワーク ACL の比較):https://docs.aws.amazon.com/vpc/latest/userguide/infrastructure-security.html
- AWS「Custom network ACLs」(Ephemeral ports):https://docs.aws.amazon.com/vpc/latest/userguide/custom-network-acl.html
- AWS「Amazon VPC quotas」:https://docs.aws.amazon.com/vpc/latest/userguide/amazon-vpc-limits.html
- AWS「Gateway endpoints」:https://docs.aws.amazon.com/vpc/latest/privatelink/gateway-endpoints.html
- AWS「VPC peering basics」:https://docs.aws.amazon.com/vpc/latest/peering/vpc-peering-basics.html
- AWS「Amazon VPC pricing」:https://aws.amazon.com/vpc/pricing/
- AWS「AWS PrivateLink pricing」:https://aws.amazon.com/privatelink/pricing/
- AWS「AWS Transit Gateway pricing」:https://aws.amazon.com/transit-gateway/pricing/
- moto「Non-Python SDK’s / Server Mode」:https://docs.getmoto.org/en/latest/docs/server_mode.html
- Google Cloud「VPC ネットワークの概要」:https://docs.cloud.google.com/vpc/docs/overview?hl=ja
- Python「ipaddress — IPv4/IPv6 manipulation library」:https://docs.python.org/3/library/ipaddress.html
- IETF「RFC 1918 Address Allocation for Private Internets」:https://www.rfc-editor.org/rfc/rfc1918
- IETF「RFC 5737 IPv4 Address Blocks Reserved for Documentation」:https://www.rfc-editor.org/rfc/rfc5737
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「VPCとは?AWSのサブネット・IGW・NATの関係を手元で再現」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。