BFT名古屋 TECH BLOG

日々の業務で得た知識を所属するエンジニアたちがアウトプットしていきます。

【AWS】セキュリティグループとネットワークACLはどう違う?

こんにちは! BFT名古屋支店の、佐野です。

今回はAWS内の仮想ネットワーク環境であるVPCにおいて、
トラフィック制御を担う「セキュリティグループ」と「ネットワークアクセスコントロールリスト(ネットワークACL)」のふたつの仕組みの違いや使い分けについて紹介させて頂きます。


はじめに

この記事を書こうと思ったきっかけとして何より「自分がごりごりに引っかかった所だから」というのがあります。
セキュリティグループとネットワークACLは双方ともトラフィック制御を行なうものではありますが、違うところも多く、混同してしまうと思わぬところで意図しない疎通・不通が起こったりします。 その解決のための無為な時間の消費の減らすためのお手伝いとして、この記事が役立てれば幸いです。
(自身の備忘録としての意味も大いにあります)


セキュリティグループとネットワークACLの違い

早速本題となりますが、まずセキュリティグループとネットワークACLそれぞれの特徴は以下の通りになります。

  • セキュリティグループ

    • インスタンス仮想マシン)ごとにかけられるものです。
      EC2でもRDSでも、インスタンスを作成する場合は必ずひとつ以上のセキュリティグループが関連付けなければいけません。
      (作成時に指定しなかった場合はVPCのデフォルトのセキュリティグループが自動的に関連付けられます)
    • ひとつのインスタンスに対して、複数関連付けることができます。
      セキュリティグループAとセキュリティグループBの両方にインスタンスAは属している、という形にもできます。
    • 通信を許可するルールのみを設定でき、その設定で許可されていない通信はデフォルトで拒否します。
    • ステートフルの性質を持ちます。
      例えばアウトバウンドルールのみ許可した通信先にトラフィックを送った場合、先に送ったトラフィックに対応する戻りのトラフィックは、インバウンドルールで通信先を許可していなくても拒否されず受け取ることができます。
      同じく許可しているインバウンドトラフィックに対する応答のアウトバウンドトラフィックは、アウトバウンドルールで通信先を設定しなくとも送信することができます。
    • ルールを設定する際、送信元・送信先を指定する方法として以下の3つを使用できます。
      • IPv4/IPv6
        (単一のアドレス、CIDR ブロックのどちらでも指定可)
      • セキュリティグループID
        (セキュリティグループごとに自動的に割り振られるID。
        セキュリティグループ単位のトラフィック許可を行なう場合はこちらが便利)
      • プレフィックスリストID
        IPアドレス範囲を表すプレフィックスリストのID。
        S3等のAWSサービスへの通信を許可する際には、サービス毎に設定されているプレフィックスリストのIDが必要となる)
  • ネットワークACL

    • サブネットごとにかけられるものです。
      サブネットを作成する際、必ずひとつのネットワークACLに関連付けなければいけません。
      (作成時に指定しなかった場合はVPCのデフォルトのネットワークACLが自動的に関連付けられます)
    • ひとつのサブネットに対して関連付けられるネットワークACLはひとつのみです。
    • 通信に対する許可と拒否のルールを両方設定します。
      またルールごとに番号を設定し、設定されているルール同士で矛盾する場合は番号が低いルールが優先されます。
      またデフォルトで設定されており、なおかつ変更不可でルール番号がない(一番優先度が低い)設定として
      「すべてのトラフィック」「送信元(先):0.0.0.0/0」「DENY」が存在します。
    • ステートレスの性質を持ちます。
      セキュリティグループと違って戻りの通信もネットワークACLの影響を受けるため、戻りの通信を考慮したルール設定を行なわないと、送信のみを許可している通信先からの応答の通信や、受信のみを許可している通信元への応答となる通信が不通となってしまいます。
      もちろんこれを利用し、一方向の送信や受信のみを許可し、戻りの通信を拒否するといった設定を行なうこともできます。
    • ルールを設定する際、送信元・送信先を指定する方法はIPv4/IPv6(単一のアドレス、CIDR ブロックのどちらでも指定可)のみとなります。

設定方法など様々な違いがありますが、特に大きな点はトラフィック制御をかける場所・範囲が異なるという点です。
そして設定の単純さで言えばネットワークACLの方が簡潔であり、セキュリティグループはさらに細かい制御を行なうことができる仕組みと言えるでしょう。


セキュリティグループとネットワークACLの設定の注意点

ネットワークACLの注意点

ネットワークACLについては、先に挙げた通り「ステートレスであり、戻りの通信を意識した設定を行なう必要があること」が最も注意すべき点になります。
これを意識していないと、しっかり設定したはずなのに通信が疎通しない……といった一見難しく見える問題に直面してしまうことになります。
また戻りの通信はおおよその場合エフェメラルポートが利用されることもあって、ポートの特定が困難です。
ネットワークACLおよびセキュリティグループでは通信に使用するポートを範囲指定することも可能ですので、戻りの通信を意識する際には使用されるエフェメラルポートの範囲を覚えておくとよいでしょう。
(もっとも、セキュリティグループのみ使う場合はステートフルの仕様上この問題は起きないのですが)

またネットワークACLはあくまでサブネット単位でのトラフィック制御を行なうものですので、同じサブネットに属するインスタンス同士のトラフィック制御を行なうことはできません。
同サブネット内のインスタンス同士のトラフィック制御が必要な場合はセキュリティグループを使用しましょう。

加えて、送信元・送信先を指定する方法がIPv4/IPv6が限定されている都合上、AWSサービスへの通信を細かに制御することができません。
正しくは不可能ではないものの、AWSサービスにCIDRブロックを設定しなければならない為、あまり現実的ではありません。
ついてはこの場合、ネットワークACLではAWSサービスとの通信に使用するプロトコル(S3の場合はHTTPS:443になります)をアウトバウンドルールにおいて0.0.0.0/0で許可し、
インバウンドルールでエフェメラルポートからの戻り通信を許可した上で、細かい制御はセキュリティグループで行なうとよいかと思います。

セキュリティグループの注意点

セキュリティグループに関して最も勘違いしやすく、注意すべきと言える(と筆者が思った)注意点は、
同じセキュリティグループに属しているインスタンス同士は、自動的に相互の通信が許可される、ということはない
という点です。

あくまでセキュリティグループは「関連付けたインスタンスへのトラフィック制御のルールを定めたもの」であり、
同じセキュリティグループに属するインスタンス同士で疎通を可能とするグループを生成するものではありません。
そのため、特に何も設定せずにセキュリティグループAに属するインスタンスAから、同じくセキュリティグループAに属するインスタンスBに通信を行なおうとしても、不通になってしまいます。
(ネットワークACLがサブネット単位という広い範囲でくくるものであり、かつセキュリティグループという名前故、ここを勘違いする方も多いと思います。筆者は勘違いしました)

その為、同じセキュリティグループに属するインスタンス同士での通信を可能としたい場合は、インバウンドルールおよびアウトバウンドルールの両方で、 「このセキュリティグループに属しているインスタンスへの送信(受信)を許可する」という設定を追加する必要があります。
その際、設定するセキュリティグループのセキュリティグループIDを送信元・送信先に指定することになります。

また先述の通り、S3などのIPを持たず、特定のセキュリティグループに属させる設定もできないAWSサービスを送信先とする許可設定については、
対象となるAWSサービスのプレフィックスリストIDを取得し、これをもって送信先として指定する必要があります。
例えば東京リージョンでのS3のプレフィックスリストIDは「pl-61a54008」となります。(2020/11/26現在)

プレフィックスリストIDの確認は、AWS-CLIで以下コマンドを実行することによって可能です。
ただし実行には「aws configure」コマンドでAWSアカウントの関連付けを行なう必要があります。

コマンド:

aws ec2 describe-prefix-lists

終わりに

以上がセキュリティグループとネットワークACLの違い、および注意点の解説となります。
「セキュリティグループとネットワークACLは同じものなんじゃないの? どう違うの?」という疑問を持つ方や
「セキュリティグループorネットワークACLの設定中につまづいた!」という悩みを抱えている方などに、この記事が少しでも助けになれば幸いです。