背景
先日、後輩からAWSについてのヘルプを求められました。あるIPアドレスからの通信を許可したいが、うまく設定できていないのか、リクエストに対してレスポンスを確認できない、とのこと。イメージは以下の通り(相談時と内容を少し改変しています)。
どうも、ネットワークACLを用いて送信元を制限しようとしていたらしいが、うまくいかないらしい。レスポンスの通信でポートを443にすると上手くいかず、全ポート許可するとレスポンスが返せているとのこと。ただ、それではセキュリティ上良くないのでは?とのことで相談を受けた。とりあえず動くけど、良くないのでは?と考える姿が素晴らしい。
セキュリティグループとネットワークACLの違い
本題に入っていく前に、セキュリティグループとネットワークACLの違いについておさらい。後輩にはこのあたりの違いを改めて説明しました。細かい違いもありますが、ざっくり記載します。
セキュリティグループ | ネットワークACL |
---|---|
ステートフルであり、リクエストに対するレスポンスは自動で許可される | ステートレスであり、リクエストだけではなくレスポンスに対しても明示的な許可が必要 |
AWSリソースに対して関連付けをする | サブネットに対して関連付けをする |
通信の許可のみ可能 | 通信の許可及び拒否が可能 |
セキュリティグループで特定のセキュリティグループを許可できるというのも特徴ですね。
解決編
さて、私のこれまでの知識&経験上、ネットワークACLを使うケースはほぼありませんでした。セキュリティグループで満たせない要件がある場合はネットワークACLを使っていくという感じです。
そのため、まずは「セキュリティグループを使って制御したら?」と回答しました。後輩曰く、「社内のものなので、可能な限りセキュリティは厳しめの方が良いのではと思った」とのこと。
それ対して、「セキュリティグループでもIPとPortで制限掛けられるから問題ない」と返しました。その後、セキュリティグループを使うように修正したところ、上手くいったと連絡を受けました。
めでたしめでたし…なんですが、ちょっと回答として不十分だったなと後から思い、少し追加で調査&補足しました。
なぜセキュリティグループではないといけなかったのか
そもそも、ネットワークACLでポートを全許可したら上手くいく、というところが一つのポイントでした。リクエストのプロトコルはHTTPで、443を許可すれば良いというのは当然の感覚ですが、レスポンスのポートは443なのでしょうか?
HTTPでは、レスポンス時のポートはエフェメラルポートから割り当てされます。つまり、レスポンス時のポートは事前には分からないということになります。そのため、ネットワークACLでポート全許可をすればレスポンス可能だが、あるポートだけ許可してもレスポンスはできなかった(許可されたポートではなかったため)ということになります。
セキュリティグループではステートフルであり、レスポンスの通信は自動で許可されるため、レスポンスのポート番号を意識しなくても良いという点で、今回のケースではセキュリティグループを採用した方が良かったということです。
セキュリティグループとネットワークACLの使い分け
じゃあ基本セキュリティグループでいいじゃん!ネットワークACLはどこで使うの?という話になります。あくまで個人の感覚になりますが、ネットワークACLの方はデフォルトの全許可にし、セキュリティグループで制御することを第一に考えればOKだと思います。ネットワークACLはリクエストとレスポンス両方で設定が必要になるため、管理が煩雑になることが懸念されます。
また、ネットワークACLでは「拒否」ルールが設定できるので、特定サーバへの通信または特定サーバからの通信を制限したい場合に利用するのが良いかなと思います。例えば、VPC内部からウイルス感染の恐れがあるサーバへのアクセスを拒否したい場合であったり、外部から不正アクセスの恐れがある送信元を拒否したい場合などでしょうか。
まとめ
- 特定の通信を「許可」したい場合はセキュリティグループで対応(基本はこちらで十分)
- 特定の通信を「拒否」したい or 厳しいセキュリティ要件がある場合はネットワークACLで対応
最後まで記事をご覧いただきありがとうございました!もし私はこういう使い分けしているよ、みたいな話があれば教えていただきたいです!