[Daily morning study] AWS 보안 그룹(Security Group)과 네트워크 ACL(NACL) 차이
#daily morning study
AWS 네트워크 보안의 두 가지 축
AWS에서 VPC 안에 리소스를 배치할 때 네트워크 수준의 접근 제어를 담당하는 레이어가 두 개 있다. 보안 그룹(Security Group)과 네트워크 ACL(Network Access Control List, NACL)이다. 둘 다 트래픽을 허용하거나 차단하는 역할인데, 적용 범위와 동작 방식이 다르다.
보안 그룹 (Security Group)
보안 그룹은 인스턴스(ENI) 수준에서 동작하는 가상 방화벽이다. EC2, RDS, Lambda 등 리소스에 직접 붙는다.
핵심 특징
Stateful (상태 추적)
- 인바운드 요청을 허용하면 해당 연결의 아웃바운드 응답은 별도 규칙 없이 자동으로 허용된다.
- TCP 3-way handshake 등 세션 상태를 기억한다.
허용(Allow) 규칙만 존재
- 명시적으로 허용되지 않은 트래픽은 묵시적으로 거부(Deny)된다.
- Deny 규칙을 추가할 수 없다.
규칙 평가 방식
- 모든 규칙을 검토한 뒤 하나라도 허용이면 통과된다. 순서가 없다.
인바운드/아웃바운드 규칙 예시
| 방향 | 프로토콜 | 포트 | 소스/대상 | 설명 |
|---|---|---|---|---|
| 인바운드 | TCP | 80 | 0.0.0.0/0 | 전체 HTTP 허용 |
| 인바운드 | TCP | 22 | 10.0.0.0/8 | 내부 SSH 허용 |
| 아웃바운드 | 전체 | 전체 | 0.0.0.0/0 | 기본 전체 허용 |
Stateful이기 때문에 아웃바운드에 0.0.0.0/0이 있으면 인바운드로 들어온 요청의 응답이 자동으로 나간다.
네트워크 ACL (NACL)
NACL은 서브넷 수준에서 동작한다. 서브넷 경계에 설치된 게이트키퍼 같은 역할이다. 서브넷에 들어오거나 나가는 모든 트래픽에 적용된다.
핵심 특징
Stateless (상태 비추적)
- 인바운드 허용과 아웃바운드 허용을 완전히 독립적으로 설정해야 한다.
- HTTP 요청을 허용했다면 응답 트래픽을 위한 아웃바운드 규칙도 별도로 추가해야 한다. 응답은 보통 임시 포트(Ephemeral Port, 1024~65535)를 사용한다.
허용(Allow)과 거부(Deny) 규칙 모두 존재
- 특정 IP를 명시적으로 차단하는 Deny 규칙을 추가할 수 있다.
규칙 번호 순서대로 평가
- 낮은 번호부터 순서대로 평가하고, 첫 번째로 매칭되는 규칙이 적용된다.
- 번호는 보통 100, 200, … 단위로 간격을 두고 설정한다.
NACL 규칙 예시 (인바운드)
| 규칙 번호 | 프로토콜 | 포트 | 소스 | 액션 |
|---|---|---|---|---|
| 100 | TCP | 80 | 0.0.0.0/0 | 허용 |
| 110 | TCP | 443 | 0.0.0.0/0 | 허용 |
| 120 | TCP | 22 | 10.0.0.0/8 | 허용 |
| 200 | TCP | 22 | 0.0.0.0/0 | 거부 |
| * | 전체 | 전체 | 0.0.0.0/0 | 거부 (기본) |
규칙 120에서 내부 IP 대역의 SSH를 먼저 허용하고, 규칙 200에서 나머지 모든 SSH를 차단한다. 순서가 중요한 이유다.
보안 그룹 vs NACL 한눈에 비교
| 항목 | 보안 그룹 | 네트워크 ACL |
|---|---|---|
| 적용 범위 | 인스턴스(ENI) | 서브넷 |
| 상태 추적 | Stateful | Stateless |
| 허용/거부 | 허용만 가능 | 허용 + 거부 가능 |
| 규칙 평가 | 모든 규칙 검토 (순서 없음) | 번호 순서대로 첫 매칭 |
| 기본 동작 | 묵시적 전체 거부 | 묵시적 전체 거부 |
| 응답 트래픽 | 자동 허용 | 별도 규칙 필요 |
| 리소스 연결 | 여러 인스턴스에 동일 SG 적용 | 서브넷 전체에 일괄 적용 |
계층 방어 (Defense in Depth)
두 레이어를 함께 쓰는 이유는 방어 심층화(Defense in Depth) 때문이다.
인터넷
│
▼
[NACL] ← 서브넷 경계에서 1차 필터 (악성 IP 블록, 포트 제한)
│
▼
[보안 그룹] ← 인스턴스에서 2차 필터 (역할별 세밀한 규칙)
│
▼
EC2 인스턴스
NACL에서 광범위한 차단을 먼저 처리하고, 보안 그룹에서 리소스 별로 세밀하게 제어한다.
Stateless를 잊으면 생기는 문제
NACL을 처음 설정할 때 가장 흔한 실수는 Stateless라는 걸 잊는 것이다.
# 잘못된 NACL 설정 예
인바운드: TCP 443 허용
# 아웃바운드 규칙 없음
# 결과: HTTPS 요청은 들어오지만 응답이 나가지 못한다.
# 클라이언트 입장에서는 요청 타임아웃처럼 보인다.
# 올바른 NACL 설정 예
인바운드: TCP 443 허용 (0.0.0.0/0)
아웃바운드: TCP 1024-65535 허용 (0.0.0.0/0)
# 응답은 임시 포트(Ephemeral Port) 범위로 나간다.
임시 포트 범위는 OS마다 다르다. Linux는 보통 32768~60999, Windows는 49152~65535인데, 안전하게 1024~65535를 열어두는 경우가 많다.
언제 어떤 걸 쓸까
보안 그룹만으로 충분한 경우
- 대부분의 일반적인 애플리케이션 배포
- 세밀한 역할 기반 접근 제어가 필요한 경우 (웹 서버 SG, DB 서버 SG 분리)
NACL을 추가로 활용하는 경우
- 특정 IP 대역을 서브넷 전체에서 차단해야 할 때 (DDoS 대응, 공격 IP 블록)
- 규정 준수(Compliance) 요건으로 서브넷 수준 방화벽이 필요한 경우
- 내부 서브넷 간 트래픽도 통제해야 하는 경우
보안 그룹은 세밀하고 유연한 제어에 유리하고, NACL은 서브넷 전체에 빠르게 적용해야 하는 굵직한 정책에 유리하다. 실제 운영 환경에서는 두 가지를 함께 쓰는 것이 기본이다.
정리
- 보안 그룹: 인스턴스 레벨, Stateful, Allow만 지원, 순서 없음
- NACL: 서브넷 레벨, Stateless, Allow/Deny 모두 지원, 번호 순서 중요
- Stateless인 NACL은 아웃바운드 임시 포트 규칙을 반드시 추가해야 한다
- 두 레이어를 함께 사용해서 계층적 방어를 구성하는 것이 모범 사례다