はじめに
前回、NAT Gatewayについて調べた際の記事( https://qiita.com/y-kojima-next/items/fa37c47a0f62aa02dc1a )で、「NAT Gatewayにはセキュリティグループを設定できないので、制御したい場合はネットワークACLか通信元のEC2のセキュリティグループで行う」と書きました。
どちらもVPCの通信を制御する仕組みですが、性質がかなり違います。SAAでもこの違いを前提にした問題が出るようなので、内容をまとめます。
外部からの通信は2つのフィルタリングポイントを通る
まず前提として、VPC外からVPC内のEC2に通信が届くまでには、ネットワークACLと宛先EC2のセキュリティグループの2つのフィルタリングポイントを通ります。
インターネット
|
v
IGW(VPCの出入口)
|
v
=== サブネット =========================
|
v
(1) ネットワークACL(サブネットレベル)
|
v
(2) セキュリティグループ(ENIレベル)
|
v
EC2
=======================================
- ネットワークACL:サブネットの入口で通信をチェックする
- セキュリティグループ:EC2などのリソースの直前で通信をチェックする
なお、(2)で評価されるのは正確には宛先EC2のENI(ネットワークインターフェイス)に関連付けられたセキュリティグループのインバウンドルールです。セキュリティグループは通信の途中にあるのではなく、あくまでリソースごとに付いているものです。
両方を通過しないと通信は成立しません。片方で許可していても、もう片方で止まっていれば通信できません。設定したのになぜか繋がらないという場合の原因になることが多いようです。
なぜ2段階あるのかというと、役割が違うからです。ネットワークACLはサブネット全体に一律のルールを適用し、セキュリティグループは関連付けられたENIの通信を制御します。
同一サブネット内の通信ではセキュリティグループのみ通る
上の図は、サブネットの外から来る通信を想定したものです。ポイントとしては、ネットワークACLはサブネットの境界を越える通信しか評価しないという点です。
つまり、同じサブネットに置いたEC2同士の通信には、ネットワークACLは一切適用されません。サブネットの入口を通らないので、チェックされる機会がないためです。
一方セキュリティグループは、リソースの直前で通信を見るので、相手が隣のEC2であっても関係なく評価されます。
このとき評価されるのは1箇所ではなく、送信側と受信側の2箇所です。EC2-Aから出ていく通信はEC2-Aに付いたセキュリティグループのアウトバウンドで、EC2-Bに入る通信はEC2-Bに付いたセキュリティグループのインバウンドで、それぞれ独立して評価されます。
【同じサブネット内】
EC2-A
|
v
SG-A のアウトバウンドルール
|
v
SG-B のインバウンドルール
|
v
EC2-B
※ネットワークACLは通らない
そのため、サブネット内のサーバー同士の通信を制限したいという場合、ネットワークACLでは実現できず、セキュリティグループで行うことになります。
セキュリティグループとは
ENI(ネットワークインターフェイス)単位で通信を制御する仮想的なファイアウォールです。EC2、RDS、ALBなどに割り当てると、そのリソースが持つENIに関連付けられます。
特徴は次のとおりです。
許可ルールしか書けない
これを通すというルールだけを書きます。書かれていないものは自動的に拒否されます。特定のIPアドレスだけ拒否するといった書き方はできません。
すべてのルールが評価される
複数のルールがある場合、そのすべてを見て、どれか1つでも一致すれば許可されます。ルールの順番は関係ありません。
複数を割り当てられる
1つのENIに複数のセキュリティグループを付けられます(デフォルトでは最大5つ。緩和申請により最大16まで引き上げ可能)。その場合、すべてのルールを合わせたものが適用されます。
1台のEC2に複数のENIをアタッチした場合は、ENIごとに別のセキュリティグループを割り当てられます。そのため、インスタンス全体として関わるセキュリティグループの数は5つを超えることがあります。
送信元に別のセキュリティグループを指定できる
IPアドレス指定ではなく、たとえば「ALBに割り当てたセキュリティグループからの通信だけを許可する」といった書き方ができます。
オートスケーリングでEC2が増減してIPアドレスが変わる構成では、IPアドレスで書くと管理できなくなります。グループ同士で指定しておけば、台数が変わっても設定を変える必要がありません。
なお、送信元にはIPアドレス(CIDR)とセキュリティグループのほかに、マネージドプレフィックスリスト(複数のCIDRをまとめて名前で扱えるもの)も指定できます。
デフォルトの状態
VPC作成時に自動で作られるものと自分で新規作成したものとで状態が違います。
| 種類 | インバウンド | アウトバウンド |
|---|---|---|
| VPC作成時のデフォルトのもの | 同じセキュリティグループからの通信のみ許可 | すべて許可 |
| 自分で新規作成したもの | ルールなし=すべて拒否 | すべて許可 |
新規作成した場合は、作っただけでは外からは一切入れず、中からは自由に出られる状態です。必要なものだけをインバウンドに追加していく形になります。
一方、デフォルトのセキュリティグループには、最初から「送信元=自分自身」というインバウンドルールが入っています。つまり、同じデフォルトSGを付けたリソース同士は最初から通信できるということです。前述の「送信元に別のセキュリティグループを指定できる」の実例でもあります。
ネットワークACLとは
サブネット単位で通信を制御する仕組みです。ACLは Access Control List(アクセス制御リスト)の略です。
サブネットに必ず1つ紐づく
1つのサブネットに設定できるネットワークACLは1つだけです(逆に、1つのネットワークACLを複数のサブネットに紐づけることはできます)。明示的に指定しない場合は、VPCのデフォルトのネットワークACLが適用されます。
拒否ルールを書ける
セキュリティグループとの大きな違いです。「許可」に加えて「拒否」も書けるので、特定のIPアドレスからの通信をブロックするといった制御ができます。
ルール番号の小さい順に評価される
各ルールには番号を付けます。番号の小さいものから順に評価され、最初に一致したルールが適用されて、そこで評価は終了します。
そのため、順番を間違えると意図しない結果になります。
ルール100:0.0.0.0/0(すべて)からのHTTPを許可
ルール200:203.0.113.10 からのHTTPを拒否
この場合では203.0.113.10が先にルール100で一致してしまい、拒否されません。拒否したいルールを先(小さい番号)に書く必要があります。
なお、ユーザーが指定できるルール番号は1〜32766です。また、ルールの最後には常に*という「すべて拒否」が入っており、これは削除できません。どのルールにも一致しなかった通信は、最終的にここで拒否されます。
デフォルトの状態
こちらも、VPC作成時に自動で作られるものと新規作成したものとで初期状態が異なります。
| 種類 | デフォルト |
|---|---|
| VPC作成時に自動で作られるもの | インバウンド・アウトバウンドともすべて許可 |
| 自分で新規作成したもの | インバウンド・アウトバウンドともすべて拒否 |
最初から存在するものは全許可なので、何も設定していない状態では、実質的にセキュリティグループだけが効いていることになります。一方、自分で新しく作ると全拒否から始まるので、必要なルールを入れないと通信が止まります。
ステートフルとステートレス
両者の違いでSAAでも問われる部分です。
通信は往復するもの
前提として、通信は必ず往復します。
自分のPCからWebサーバーにアクセスする場面を考えます。
- 行き:PC → サーバーの80番ポート宛てにリクエストを送る
- 帰り:サーバー → PCにレスポンスを返す
このとき、帰りの通信の宛先は80番ポートではありません。PCが通信を始めるときに自動的に割り当てた、一時的なポート番号宛てに返ってきます。
この一時的なポートを エフェメラルポート(一時ポート) と呼びます。通信ごとに使い捨てで割り当てられるもので、番号は決まっていません。
行き: PC:54321 ---(80番宛て)---> サーバー:80
帰り: PC:54321 <--(54321番宛て)-- サーバー:80
つまり、行きと帰りではポート番号が違うということです。
セキュリティグループはステートフル
セキュリティグループは、行きの通信を許可すると、その戻りの通信は自動的に許可されます。
この通信は許可したものだという状態(ステート)を覚えているので、ステートフルと呼ばれます。
そのため、Webサーバーとしてリクエストを受ける場合は、インバウンドで80番を許可するだけでレスポンスは返せます(EC2が自分から通信を始める場合は、別途アウトバウンドの許可が必要です)。
ネットワークACLはステートレス
一方、ネットワークACLは状態を覚えていません。行きと帰りをまったく別の通信として、それぞれ独立して評価します。
この場合、Webサーバーへの通信を成立させるには、両方向の設定が必要になります。
| 方向 | 必要なルール | 意味 |
|---|---|---|
| インバウンド | ポート80を許可 | リクエストを受け取る |
| アウトバウンド | ポート1024-65535を許可 | レスポンスを返す |
アウトバウンドで指定しているのが、先ほどのエフェメラルポートの範囲です。
ネットワークACLから見れば、レスポンスもサブネットの外に出ていく通信の1つでしかないため、アウトバウンドの設定が必要となります。
エフェメラルポートの範囲
指定する範囲は、通信してくる相手のOSや仕組みによって異なります。
| 通信元 | 範囲 |
|---|---|
| 多くのLinuxカーネル(Amazon Linuxを含む) | 32768-60999 |
| Windows Server 2008以降 | 49152-65535 |
| ELB、NAT Gateway、Lambda | 1024-65535 |
インターネット向けのWebサーバーのように相手が特定できない場合は、すべてをカバーできる 1024-65535 を指定するのが一般的です。
このエフェメラルポートの許可漏れは、ネットワークACLで最もよくある設定ミスとされています。セキュリティグループの感覚のまま設定すると、引っかかりやすい部分です。
違いのまとめ
| 比較項目 | セキュリティグループ | ネットワークACL |
|---|---|---|
| 適用単位 | ENI(ネットワークインターフェイス)単位 | サブネット単位 |
| 状態の管理 | ステートフル(戻りは自動許可) | ステートレス(戻りも明示的に許可が必要) |
| ルールの種類 | 許可のみ | 許可と拒否 |
| 評価方法 | すべてのルールを評価 | 番号の小さい順、最初に一致した時点で確定 |
| 割り当て | 1つのENIに複数可 | 1つのサブネットに1つ |
| デフォルト(新規作成時) | イン:全拒否 / アウト:全許可 | イン・アウトとも全拒否 |
| 送信元の指定 | IPアドレス、セキュリティグループ、プレフィックスリスト | IPアドレス(CIDR)のみ |
| 同一サブネット内の通信 | 適用される | 適用されない |
どちらを使うのか
調べた限り、通信制御は基本的にセキュリティグループで行い、ネットワークACLはデフォルト(全許可)のまま使う構成が一般的なようです。
セキュリティグループの方が細かく制御でき、ステートフルなので設定ミスも起きにくいためです。
ネットワークACLを使うのは、次のような場面です。
- 特定のIPアドレスをブロックしたい……セキュリティグループでは拒否を書けないため、ネットワークACLで行う
- サブネット全体に一律の制限をかけたい……個別のセキュリティグループの設定漏れに備えた保険として使う
- サブネット間の通信を止めたい……たとえばプライベートサブネットへの通信を、特定のサブネットからだけに限定する
注意点やつまずきポイント
両方を通過しないと通信できない
セキュリティグループで許可していても、ネットワークACLで止まっていれば通信できません。繋がらないときは、両方を確認する必要があります。
インバウンドの通信はネットワークACL → セキュリティグループの順に、アウトバウンドの通信は逆の順にチェックされます。
ネットワークACLでは外に出ていく通信も往復で考える
前述の例はサーバーが受け取る側でしたが、EC2から外部のAPIを呼び出すような場合も同じです。
| 方向 | 必要なルール |
|---|---|
| アウトバウンド | ポート443を許可(リクエスト送信) |
| インバウンド | ポート1024-65535を許可(レスポンス受信) |
この場合はEC2側が一時ポートを使うので、インバウンドでエフェメラルポートを許可します。
ルール番号は間隔を空けておく
ネットワークACLのルール番号は、100、200、300のように間隔を空けて付けるのが定番です。後から間に挿入したくなったときに、番号を振り直さずに済みます。
拒否ルールは許可ルールより前に置く
前述のとおり、最初に一致したルールで確定します。「全許可」のルールを小さい番号に置いてしまうと、その後ろの拒否ルールは評価されません。
IPv6のルールは別に必要
ネットワークACLでは、IPv4とIPv6のルールは別々に管理されます。0.0.0.0/0を許可してもIPv6の通信は対象外なので、IPv6を使う場合は::/0のルールを別途書く必要があります。
一部のリソースにはセキュリティグループを設定できない
前回書いたNAT Gatewayがこれにあたります。この場合は、サブネットのネットワークACLか、通信元のEC2などのセキュリティグループで制御します。
まとめ
- VPCの通信は、ネットワークACL(サブネット) と セキュリティグループ(ENI) の2つのフィルタリングポイントを通り、両方を通過して初めて成立する
- ネットワークACLはサブネットの境界を越える通信にしか適用されない。同一サブネット内の通信を制御したい場合はセキュリティグループを使う
- セキュリティグループはステートフル。行きを許可すれば戻りは自動的に許可される
- ネットワークACLはステートレス。行きと帰りを別々に評価するので、戻り用のエフェメラルポート(1024-65535など)の許可が別途必要
- セキュリティグループは許可のみ、ネットワークACLは拒否も書ける
- ネットワークACLは番号順に評価し、最初に一致した時点で確定するため、拒否ルールを先に置く
- セキュリティグループは送信元に別のセキュリティグループを指定できるので、IPが変動する構成でも管理しやすい
- 基本はセキュリティグループで制御し、ネットワークACLは特定IPのブロックなど補助的に使う
セキュリティグループとネットワークACLを比べて調査したことで、その仕組みが理解できました。
SAAでは「通信ができない原因はどれか」「特定のIPをブロックするにはどうするか」といった形で問われるようなので、ステートフルとステートレスの違いを軸に押さえておきたいところです。
参考
- セキュリティグループを使用して AWS リソースへのトラフィックを制御する - Amazon VPC
- ネットワーク ACL を使用してサブネットへのトラフィックを制御する - Amazon VPC
- VPC のセキュリティのベストプラクティス - Amazon VPC
※本記事の内容は2026年8月時点のものです。最新の仕様は必ず公式ドキュメントでご確認ください。