はじめに
アプリケーションを書いてきたエンジニアが、あるとき突然インフラを見ることになる。ありがちな話です。そして最初にぶつかるのが、たいてい 「繋がらない」 という壁でした。
- ローカルでは動いたのに、サーバーにデプロイしたらブラウザから見えない
- SSH でログインしようとしたら、コマンドが無反応のまま固まる
- アプリから DB に接続できない。エラーログには「タイムアウト」とだけ書いてある
こういうとき、闇雲に設定を触ると余計に沼にはまります。必要なのは、通信がどこを通ってどこで止まるのか を頭の中に描けることでした。
この記事では、AWS のネットワークを構成する要素を、アプリケーションエンジニアが「トラブルを切り分けられる」レベルまで整理します。登場人物の整理 → 個々の役割 → 切り分けの手順 までを1本にまとめました。手順書ではなく、考え方の地図として読んでいただければと思います。
このシリーズでは「可用性設計の基本」「マネージドサービスの考え方」も解説しています。あわせて読むと全体像がつかめます。
この記事で分かること
- VPC・サブネット・ルートテーブル・セキュリティグループの役割分担が分かる
- CIDR 表記(
/16や/24)を見て、使えるアドレス数が計算できる - 「パブリックサブネット」「プライベートサブネット」が何で決まるのかを説明できる
- プライベートに置いたサーバーが
installコマンドで固まる理由が分かる - エラーメッセージの種類から、原因のレイヤーを切り分けられるようになる
第1章:4つの登場人物
AWS のネットワークは、ざっくり次の4つを押さえれば読み解けます。
| 要素 | ひとことで言うと | アプリで例えるなら |
|---|---|---|
| VPC | 自分専用のネットワーク空間 | プロジェクトのルートディレクトリ |
| サブネット | VPC を区切った区画 | その下のサブディレクトリ |
| ルートテーブル | 通信の行き先を決める道順表 | ルーティング定義 |
| セキュリティグループ | サーバーの手前に立つ門番 | ミドルウェアの認可チェック |
この4つの関係を図にすると、こうなります。
ここで大事なのは 担当範囲の違い です。ルートテーブルは「どこへ向かうか」をサブネット単位で決め、セキュリティグループは「通していいか」をサーバー単位で決めます。繋がらないとき、この2つのどちらの問題かを切り分けるのが第一歩になります。
第2章:VPC ― 自分専用のネットワーク空間
VPC は、クラウド上に確保する 自分だけのネットワーク です。他人のサーバーと同じ物理基盤の上で動いていても、ネットワーク的には隔離されています。
VPC を作るときに決めるのが、どれくらいの広さの IP アドレス空間を使うか です。これを CIDR 表記で書きます。
CIDR 表記の読み方
10.0.0.0/16 のような書き方です。末尾の数字は「先頭から何ビットを固定するか」を表し、残りが自由に使える範囲 になります。
| 表記 | 使えるアドレス数(計算上) | イメージ |
|---|---|---|
/32 |
1個 | 特定の1台を指定するとき |
/24 |
256個 | 一般的なサブネット1つ分 |
/16 |
65,536個 | VPC 全体の器として |
実際に使える数は、AWS がサブネットごとに 5個を予約 しているぶん減ります。/24 なら 256 − 5 = 251個 です。「あれ、計算が合わない」と思ったらこれが原因です。
広さはどう決めるか
原則は「将来を見て、少し余裕を持って広めに」です。狭すぎるとサーバーを増やせなくなります。とくに、リクエストに応じて自動でスケールするサービス(ロードバランサーなど)は、1リソース=1IP とは限らず、内部的に複数の IP を消費します。器が狭いとスケールしきれず、エラーの原因になります。
一方で、無闇に広くするのも考えものです。将来、別の VPC と接続する必要が出たとき、IP アドレス帯が重複していると繋げられません。プロダクトの規模に見合った範囲にしておくのが無難です。
第3章:サブネットとルートテーブル ― パブリックとプライベートの正体
VPC をさらに区切ったものがサブネットです。ここで最初の重要な概念が出てきます。
パブリックサブネット と プライベートサブネット という言葉をよく聞きますが、これは サブネットに付ける設定項目ではありません。「パブリック」という名前を付けても、パブリックになるわけではないのです。
では何で決まるのか。ルートテーブルの中身 です。
ルートテーブルは通信の道順表
ルートテーブルは、サブネットに紐づくルーティング定義です。そのサブネットにいるサーバーが通信を始めるとき、宛先に応じてどこへ送るかを、この表を見て決めます。
0.0.0.0/0 は「上記のどれにも当てはまらないすべて」を意味するデフォルトルートです。この行き先として インターネットゲートウェイ(IGW) が設定されていれば、そのサブネットのサーバーはインターネットと直接やり取りできます。
そして、冒頭の問いの答えがこれです。
サブネットに紐づくルートテーブルに、IGW への経路があればパブリックサブネット。なければプライベートサブネット。 ただそれだけです。「このサブネットはパブリックですか?」と聞かれたら、名前ではなく ルートテーブルを見に行く のが正解です。
第4章:プライベートサブネットの「片道通行」問題
DB サーバーなど、外部から直接アクセスさせたくないものはプライベートサブネットに置きます。ここで、アプリエンジニアが必ず一度は踏む地雷があります。
プライベートサブネットのサーバーは、外から入れないだけでなく、自分から外へも出られません。
つまり dnf install、npm install、外部 API の呼び出し――これらが すべて無反応のまま固まります。ルートテーブルに「外に出る経路」がないからです。エラーすら返ってこないので、原因に気づきにくいのが厄介なところでした。
これを解決するのが NAT ゲートウェイ です。パブリックサブネットに NAT ゲートウェイを置き、プライベートサブネットのルートテーブルで 0.0.0.0/0 の行き先をそこに向けます。すると、外向きの通信だけが通り、外から入ってくる接続は依然として遮断される という、望ましい状態になります。
NAT ゲートウェイは 無料枠がなく、置いてあるだけで時間課金 されます。検証で作ったまま忘れると、地味に効いてきます。使い終わったら削除するか、そもそも必要かを検討してください。AWS のサービスにだけ繋ぎたいなら、VPC エンドポイントという安価な選択肢もあります。
プライベートなサーバーにどうやって入るのか
SSH でログインしたい場合は、パブリックサブネットのサーバーを 踏み台(bastion) にして二段階で入る方法が古典的です。ただ、この方式は踏み台サーバー自体の管理コストがかかりますし、秘密鍵を踏み台に置くのはセキュリティ的にも望ましくありません。
現在は Session Manager(AWS Systems Manager の機能)を使うのが主流です。エージェントと適切な権限があれば、SSH のポートを開けず、鍵も踏み台も不要で プライベートサブネットのサーバーに接続できます。「踏み台を立てなきゃ」と思ったら、まずこちらを検討してください。
第5章:セキュリティグループ ― サーバーの前に立つ門番
ルートテーブルが「どこへ向かうか」なら、セキュリティグループは「通していいか」を決めます。サーバーの周りを包む、薄い膜のようなものです。
指定するのは、おおむね次の3つです。
- プロトコル/ポート(例:TCP 22、TCP 80)
- ソース(どこからの通信か)
- 許可するかどうか
ここで押さえるべき挙動が一つあります。
セキュリティグループは 「許可ルールに一致しない通信は、すべて拒否」 です。明示的に「拒否」を書くのではなく、許可を書き足していく ホワイトリスト方式です。何も書かなければ、何も通りません。
だから「SSH できない」ときは、22番ポートの許可ルールがあるか、そのソースに自分の IP が含まれているかを見ます。「ブラウザから見えない」なら、80番(または 443番)の許可があるかを見ます。
ソースに「セキュリティグループ」を指定する
ここが、知っていると設計の質が変わるポイントでした。ソースには IP アドレス(0.0.0.0/0 や 203.0.113.10/32)だけでなく、別のセキュリティグループを指定できます。
たとえば DB サーバーのセキュリティグループに、こう書けます。
「web-sg が付いているサーバーからの MySQL 通信(3306)のみ許可する」
IP アドレスを直書きしないので、サーバーが増減して IP が変わってもルールが壊れません。「役割で許可する」という発想です。アプリで言えば、ユーザー ID を直書きするのではなくロールで認可する、というのに近い考え方だと捉えると腑に落ちます。
第6章:繋がらないときに見る順番
トラブルシュートで一番大事なのは、エラーメッセージが何を意味するか を知ることでした。
| 症状 | 疑うべき場所 |
|---|---|
| 接続がタイムアウトする/無反応で固まる | セキュリティグループ(ポートが開いていない)、次に ルートテーブル(経路がない) |
| すぐに「接続拒否(Connection refused)」が返る | ネットワークは届いている。サーバー上のプロセスが起動していない |
名前解決に失敗する(Name or service not known) |
接続先のホスト名が存在しない。DNS やエンドポイント名の綴りを確認 |
認証エラー(Access denied) |
通信は成立している。ユーザー名・パスワード・権限 の問題 |
この表が意味するところは、「エラーの種類が、原因のレイヤーを教えてくれる」 ということです。
タイムアウトなら、パケットがどこかで捨てられています。ネットワーク層(セキュリティグループ、ルートテーブル)を疑います。逆に「認証エラー」が返ってきたなら、通信自体は成立しているので、ネットワーク設定をいじっても無駄です。アプリケーション層の問題です。
この切り分けができるだけで、無駄な作業時間が劇的に減りました。
まとめ:AWSネットワーク チェックリスト
-
VPC は自分専用のネットワーク空間。広さは CIDR(
/16など)で決める -
/24の使えるアドレスは 256 − 5(予約分)= 251個 - サブネットのパブリック/プライベートは、ルートテーブルの中身 で決まる(名前ではない)
-
IGW への
0.0.0.0/0経路があればパブリック、なければプライベート - プライベートのサーバーは 外からも入れず、外へも出られない。外向き通信には NAT ゲートウェイ
- NAT ゲートウェイは 置いてあるだけで課金。消し忘れに注意
- プライベートへの接続は、踏み台よりも Session Manager を検討する
- セキュリティグループ は「許可を書き足すホワイトリスト」。書かなければ通らない
- ソースに 別のセキュリティグループ を指定できる。IP 直書きより壊れにくい
- 切り分けは エラーの種類 から。タイムアウト=ネットワーク、認証エラー=アプリ層
