アウトバウンドを開けたのになぜ通らないのか
一言でいうと
セキュリティグループは状態を記憶し(stateful)、NACLは記憶しません(stateless)。この1つの違いから、残りのすべての違いが出てきます。
なぜ必要なのか
セキュリティグループでインバウンド80だけを開けておけば、応答は勝手に出ていきます。リクエストが入ってきたことを記憶していて、その応答を自動的に許可するからです。
NACLは違います。入ってきたものを記憶しないので、応答が出ていくことも別に許可する必要があります。そして、応答はエフェメラルポート(1024–65535)へ出ていくので、その範囲をアウトバウンドで開ける必要があります。
これを知らないと、「インバウンドは開けたのに、応答が来ない」という現象を、何時間も見ることになります。
並べて見る
| セキュリティグループ | ネットワークACL | |
|---|---|---|
| 適用対象 | インスタンス(ENI) | サブネット全体 |
| 状態 | 保存。応答を自動許可 | 非保存。双方向がそれぞれ必要 |
| ルール | 許可のみ | 許可 + 拒否 |
| 評価 | すべてのルールを見て、許可が1つあれば通過 | 番号順に、最初に合ったルールを適用 |
| 既定値 | インバウンドはすべて遮断、アウトバウンドはすべて許可 | 既定はすべて許可 |
| 個数 | インスタンスあたり複数適用可能 | サブネットあたり1つ |
NACLの順序ルールが作る落とし穴
번호 타입 동작
100 전체 ALLOW
200 TCP 22 DENY ← 절대 적용되지 않는다
ルール100ですでに許可されて終わっているので、ルール200は見られることがありません。セキュリティグループのように「拒否が優先」ではありません。番号が小さいものから、最初に合ったルールで終わりです。
そのため、NACLのルール番号は、100、200、300のように間を空けて付けます。あとで間に差し込む場所を残すためです。
セキュリティグループの強力な機能: グループ参照
セキュリティグループのルールの送信元に、別のセキュリティグループを指定できます。
DB 보안그룹 인바운드:
5432 ← sg-app (앱 서버 보안그룹)
IPを使っていないという点が重要です。アプリサーバーが何台でも、オートスケーリングで増えても減っても、IPが変わっても、ルールを直す必要がありません。役割でルールを書くことなので、クラウドで最も実用的なパターンです。
どう使い分けるか
実務では、たいてい次のように整理されます。
- セキュリティグループを主力として使います。きめ細かく、グループ参照ができ、ミスが少ないです。
- NACLは、サブネット全体にかける広いガードレールとしてだけ使います。例: 特定の悪意あるIP範囲の遮断、データサブネットからインターネットへ出ること自体の封鎖。
NACLできめ細かい制御をしようとすると、エフェメラルポートと順序ルールのため、すぐに絡まります。
よくあるミス5つ
0.0.0.0/0にポート22(SSH)を開放してしまいます。スキャナーが数分で見つけます。- アウトバウンドをすべて開けておきます。侵害後のデータ持ち出し経路になります。
- NACLでエフェメラルポートのアウトバウンドを開けず、応答が塞がれます。
- NACLのルール番号を1、2、3と付けてしまい、あとから差し込む場所がありません。
- セキュリティグループの説明(description)を書かず、6か月後に誰も理由を知りません。
5つ目が意外とつらいです。消してよいかわからないので、ルールが溜まり続けます。
現場での姿
- インバウンドは通るのに応答が来ない → NACLのアウトバウンドのエフェメラルポートです。
- オートスケーリングのあとにDB接続が失敗 → IPでルールを書いていました。グループ参照に変える必要があります。
- セキュリティグループが40個まで増えた → 整理の基準がありませんでした。説明を必須にします。
ルールが増えるのを防ぐ方法
前に、セキュリティグループが40個まで増えた事例を挙げました。これは怠慢の問題ではなく、消す根拠を作らなかった構造の問題です。いくつかのルールを最初に決めておけば、この状態には至りません。
名前と説明を形式として強制します。どのサービスのどの役割かが名前から読め、ルールごとに、なぜ開けたのか、いつまで必要かが説明に書かれていれば、6か月後に消すかどうかを判断できます。説明が空のものは、作れないように検査で防ぐほうがよいです。
役割で書き、アドレスでは書きません。グループ参照を使えば、ルールの数がリソースの数と無関係になります。逆に、IPで書き始めると、サーバーが増えるたびにルールが増え、サーバーがなくなってもルールは残ります。ある日そのアドレスを別の人が使うようになると、意図しないアクセスが開くことも、IPルールの危険です。
一時的に開けたものに、期限を書いておきます。調査のために少しの間だけ開けることは、常にあります。そのとき、説明に日付を書くルールがあるだけでも、あとで期限が過ぎたルールを機械的に抜き出せます。
定期的に、実際に使われているかを見ます。フローログを有効にしておけば、どのルールで実際のトラフィックが通ったかがわかります。数か月間、1度も使われなかった許可は、削除の候補です。
そして、ルールを手で直さないことが、このすべての前提です。コンソールで急いで開けたルールは、コードにないので、次のデプロイで消えるか、逆にコードと実際がずれたまま残ります。どちらにしても、あとで「このルールはなぜここにあるのか」に誰も答えられない状態につながります。
次に見ること
プライベートリソースが外へ出る3つの道と、それぞれの値段。