はじめる前に
- 必須AWS アカウントを持っていること
- 必須マネジメントコンソールにサインインできること
- 必須VPC・サブネット・セキュリティグループを使って EC2 に SSH 接続した経験
- あると良いパブリック/プライベートサブネットの違いについての理解
※ このハンズオンは すべてコンソールだけで完結します。ローカル端末からの SSH 接続確認のみ行います。
参照する公式ドキュメント
手順に迷ったときや、用語の意味を確かめたいときに開きましょう。
※ リンク切れの場合は、ページタイトルで検索してください。
背景・シナリオ
VPC の通信制御は、サーバー単位の「セキュリティグループ」だけで決まると思われがちです。しかし VPC には、サブネット単位で通信を制御する「ネットワークACL」というもう1つの壁があります。最初から使っている「デフォルトのネットワークACL」はすべての通信を許可しているため、多くの人はその存在を意識せずに過ごしています。
ところが、自分でカスタムのネットワークACLを作ってサブネットに関連付けると、様子が変わります。新しく作ったカスタムネットワークACLは、ルールを何も追加していない時点では、すべての通信を暗黙的に拒否するという初期状態を持っています。そのため、セキュリティグループでは許可されているはずのSSH通信が、ネットワークACLの側で止まってしまう、ということが起こります。今回はこの「2段階の壁」を実際に作り、片方が許可していても、もう片方が拒否していれば通信できない、という様子を体験します。
セキュリティグループとネットワークACL、両方設定する必要があるの?
多くの場合はセキュリティグループだけで十分です。ネットワークACLは、サブネット単位でまとめて通信を制限したい場合や、特定のIPアドレスを明示的に拒否したい場合などに使います。両方を設定すると、両方の条件を満たした通信だけが許可される、二重の壁になります。
セキュリティグループは「ステートフル」、ネットワークACLは「ステートレス」と言われるのはどういうこと?
セキュリティグループは、リクエストを許可すると、その応答の通信は自動的に許可されます(ステートフル)。一方ネットワークACLは、リクエストを許可しても、応答の通信は別のルールとして許可しないと通信が成立しません(ステートレス)。今回、インバウンドの許可ルールだけでは接続が戻らない、という体験もします。
サブネットに関連付けるネットワークACLを「デフォルト(すべて許可)」から「自作したカスタムACL(最初は何も許可していない)」に切り替えると、セキュリティグループでは許可されているSSH通信が拒否されることを確認し、インバウンド・アウトバウンドそれぞれに正しいルールを追加して、再びSSH接続できる状態に戻す。
つくる構成
同じセキュリティグループ・同じEC2のまま、サブネットに関連付けるネットワークACLだけを切り替えて、SSH接続できるかどうかを比較します。
すべての通信を許可
暗黙的にすべてを拒否
※ セキュリティグループの設定は変更していません。サブネットに関連づくネットワークACLだけを切り替えています。
要件
以下の要件を満たし、「つながる」→「つながらない」→「ルールを直してつながる」という変化を確認してください。
| No | 要件 |
|---|---|
| 1 | リージョンは「東京(ap-northeast-1)」を使用する。 |
| 2 | VPC内のサブネットに、SSH(22番、マイIPから)を許可したセキュリティグループを持つ EC2 を1台用意する(例:t3.micro、Amazon Linux 2023)。まず SSH 接続できることを確認する。 |
| 3 | カスタムのネットワークACLを1つ作成し、EC2のあるサブネットに関連付ける。関連付け直後、ルールを何も追加していない状態でSSH接続が失敗することを確認する。 |
| 4 | インバウンドルールにSSH(22番、自分のIPから)の許可を1つ追加する。この時点でもまだ接続できないことを確認する。 |
| 5 | アウトバウンドルールに、エフェメラルポート(例:1024〜65535)の許可を追加し、SSH接続が再び成功することを確認する。 |
構築の進め方
「土台を作る」→「ブロックを体験する」→「正しいルールを追加して戻す」という順番で進めます。
- フェーズ1 — 土台を作る
-
マネジメントコンソールにサインインし、リージョンを合わせる
ブラウザで AWS マネジメントコンソールにサインインし、画面右上のリージョンが「アジアパシフィック(東京)ap-northeast-1」になっていることを確認します。
-
SSH接続できるEC2を1台用意する
EC2コンソールで、名前を自由に決め(例:
nacl-demo)、AMIにAmazon Linux 2023、セキュリティグループでSSH(22番)をマイIPから許可して起動します。キーペアも作成しておきます。 -
SSH接続できることを確認する
ローカルのターミナル(PowerShellなど)から、作成したキーペアを使ってSSH接続できることを確認します。これが「ケース1」の状態です。
ssh -i nacl-demo-key.pem ec2-user@<パブリックIP>
- フェーズ2 — ブロックを体験する
-
カスタムのネットワークACLを作成する
VPCコンソールの「ネットワークACL」から、「ネットワークACLを作成」を選び、EC2と同じVPCを指定して作成します(名前は自由、例:
nacl-demo-custom)。作っただけでは「何も許可していない」カスタムのネットワークACLは、作成した時点ではインバウンド・アウトバウンドともにルールが1つもなく、暗黙的にすべての通信を拒否する状態になっています。これは初期状態としてそうなる仕様で、設定ミスではありません。
-
EC2のあるサブネットに関連付ける
作成したネットワークACLの「サブネットの関連付け」タブから「編集」を選び、EC2が属しているサブネットを選んで関連付けます。
-
SSH接続が失敗することを確認する
もう一度同じSSHコマンドを実行します。先ほどまで成功していた接続が、今度は応答がないまま固まる、またはタイムアウトすることを確認します。これが「ケース2」の状態です。
セキュリティグループは何も変えていないセキュリティグループの設定は最初のままです。それでも接続できなくなるのは、サブネットに関連付くネットワークACLの側が、すべての通信を暗黙的に拒否しているためです。
- フェーズ3 — ルールを直して戻す
-
インバウンドにSSHの許可ルールを追加する
作成したネットワークACLの「インバウンドルール」タブから、SSH(22番)を自分のIPアドレスから許可するルールを1つ追加します(ルール番号は例:
100)。ルール番号 タイプ ポート 送信元 許可/拒否 100 SSH 22 自分のIP/32 ALLOW * すべて すべて 0.0.0.0/0 DENY(変更不可) -
この時点でもまだ接続できないことを確認する
もう一度SSHコマンドを実行しますが、まだ失敗するはずです。インバウンドだけ許可しても、応答(戻り)の通信がまだ許可されていないためです。
-
アウトバウンドにエフェメラルポートの許可ルールを追加する
「アウトバウンドルール」タブから、TCPのポート範囲1024〜65535(エフェメラルポート、例)を、送信先
0.0.0.0/0で許可するルールを追加します(ルール番号は例:100)。ルール番号 タイプ ポート 送信先 許可/拒否 100 カスタムTCP 1024-65535 0.0.0.0/0 ALLOW * すべて すべて 0.0.0.0/0 DENY(変更不可) これがゴールもう一度SSHコマンドを実行し、接続が成功すれば、このハンズオンの目的は達成です。インバウンドの許可だけでは戻らず、アウトバウンドの許可も追加してはじめて戻る、という体験がポイントです。
つまずきポイント
初学者がよく引っかかる箇所を先回りでまとめました。答えそのものは載せていませんが、「どこを見直すか」の手がかりとして使ってください。
「インバウンドもアウトバウンドも追加したのに失敗する」
追加したルールのポート番号・プロトコル(TCP)・送信元/送信先のCIDRを見直しましょう。また、セキュリティグループ側のSSH許可ルールが、自分のIPアドレスの変化(再起動などでIPが変わるケース)によって合わなくなっていないかも確認しましょう。
「番号は何のために設定するのか」
ネットワークACLのルールは、番号が小さいものから順に評価され、最初に一致したルールが適用されます。複数のルールを追加する場合は、後から間に挿入できるよう、10や100刻みで番号を空けておくと管理しやすくなります。
完了チェック
要件の再確認ではなく、画面のどこを見れば達成を確認できるかをまとめました。次を順に確かめましょう。
- デフォルトのネットワークACLの時点で、SSH接続が成功していたことを確認済みである。
- カスタムネットワークACLを関連付けた直後(ルール追加前)は、SSH接続が失敗する。
- インバウンドのSSH許可ルールだけを追加した時点でも、SSH接続はまだ失敗する。
- アウトバウンドのエフェメラルポート許可ルールを追加した後、SSH接続が成功する。
- VPCコンソールのサブネット詳細で、関連付けられているネットワークACLが、自分で作成したものになっている。
考えてみよう
手を動かすことに加えて、次の問いに自分の言葉で答えられるようにしておくと、理解がより深まります。
- インバウンドのSSH許可ルールだけでは接続が戻らず、アウトバウンドのルールも必要だったのはなぜでしょうか。
ヒント
ネットワークACLは「ステートレス」、つまり一度許可したリクエストの応答を自動では許可しません。SSHのリクエストとその応答(戻りの通信)が、それぞれ別のルールとして扱われている、という点がヒントです。 - セキュリティグループとネットワークACL、本番運用ではどのように使い分けるとよさそうでしょうか。
ヒント
セキュリティグループは「サーバーごとの細かい制御」に向いています。ネットワークACLは「サブネット単位でまとめて制限したい場合」や「特定のIPアドレスを明示的に拒否したい場合」に向いています。それぞれの得意な場面を考えてみましょう。 - ネットワークACLのルール番号を「10刻み」や「100刻み」で作ることが推奨されているのはなぜでしょうか。
ヒント
ルールは番号の小さい順に評価されます。後から新しいルールを「既存のルールの間」に挿入したくなった場合、番号が詰まっていると挿入できる余地がありません。運用中に変更が発生することを考えてみましょう。
後片づけ
作成したリソースを順番に削除します。
- サブネットの関連付けを戻す:サブネットの「ネットワークACL」をデフォルトのネットワークACLに戻すか、削除前にいったん別のネットワークACLへ関連付け直します。
- カスタムネットワークACLを削除する:サブネットの関連付けを外した後、作成したネットワークACLを削除します。
- EC2インスタンスを終了する:EC2コンソールで
nacl-demoを選び、終了します。
削除するのは、自分で作成したカスタムネットワークACLだけ
ネットワークACLの一覧には、VPC作成時に自動的に用意される「デフォルトのネットワークACL」も表示されます。これは削除できません(削除しようとしてもエラーになります)が、誤って他のサブネットの関連付けを変更しないよう、対象を名前でよく確認しましょう。
コストに関する注意: ネットワークACLの利用そのものに料金はかかりません。VPC・サブネット・ルートテーブル・セキュリティグループ・ネットワークACL自体も同様に無料です。一方、EC2インスタンスは起動中の時間に応じて課金されます(t3.microなどは無料利用枠の対象になる場合があります)。アタッチされるEBSボリュームにも保存容量に応じた料金がかかります。検証が終わったら、上の「後片づけ」に沿って忘れずに削除しましょう。最新の料金は AWS の公式料金ページで確認してください。