home
SAA-C03

[security] 보안 그룹 & NACL 심화

stateful이 실제로 뭘 뜻하는지, 3-티어에선 어떻게 쓰는지. 보안 그룹과 NACL을 실무 감각으로 깊게 팝니다.

이 노트는 이론 심화 + AWS 실제 활용 사례 중심이다. 시험 직전 빠른 비교/트리거는 network/security-group-vs-nacl.md를 함께 본다.

One-Line Summary

Security Group(SG)Network ACL(NACL)은 VPC 안에서 트래픽을 막는 두 개의 방화벽 계층이다. SG는 ENI(인스턴스) 단위·stateful·allow-only, NACL은 서브넷 단위·stateless·allow+deny다. 실무에서는 SG를 주력 접근 제어로 쓰고(계층 간에는 IP가 아니라 SG를 서로 참조), NACL은 서브넷 경계의 보조 방어선(특정 IP/대역 차단, 규정용 격리)으로 쓴다. 이 역할 분담과 "왜 그렇게 쓰는가"를 이해하는 게 핵심이다.

Why It Exists — 심층 방어(Defense in Depth) 안에서의 위치

AWS 네트워크 보안은 하나의 장치가 아니라 여러 겹으로 이루어진다. SG/NACL은 그중 VPC 계층의 두 겹이다.

사용자 요청
  │
  ▼
[Route 53 / CloudFront / WAF / Shield]   ← 엣지: L7 필터·DDoS 완화(별도 노트)
  │
  ▼
[Internet Gateway] → [Route Table]        ← 경로가 있어야 도달 (라우팅은 방화벽 아님)
  │
  ▼
[Network ACL]     ← 서브넷 경계, stateless, allow/deny   ◀── 이 노트
  │
  ▼
[Security Group]  ← ENI(인스턴스) 앞, stateful, allow만   ◀── 이 노트
  │
  ▼
[호스트 OS 방화벽 / IAM / 앱 인증]          ← 인스턴스 내부·권한 계층

핵심 사고방식:

라우트 테이블은 "길을 열고", SG/NACL은 "문을 지킨다". 통신이 안 되면 라우팅→NACL→SG를 순서대로 의심한다. 어느 한 겹이라도 막으면 통신은 실패한다(= 심층 방어).

이 두 겹을 나눈 이유:

  • SG (인스턴스 관점): "이 서버에 누가/무엇이 접근할 수 있나"를 리소스별로 정밀 제어.
  • NACL (서브넷 관점): "이 네트워크 구획 전체에 무엇을 들이고 내보낼까"를 광역으로 제어 — 개별 SG가 잘못 설정돼도 막아주는 안전망.

Abbreviations

약어풀네임의미
SGSecurity GroupENI 단위 stateful 방화벽
NACLNetwork Access Control List서브넷 단위 stateless 방화벽
ENIElastic Network Interface인스턴스·Lambda·엔드포인트에 붙는 가상 NIC (SG가 여기 적용)
StatefulStateful허용된 요청의 응답을 연결 추적으로 자동 허용
StatelessStateless요청·응답을 각각 규칙으로 명시해야 함
Ephemeral PortEphemeral Port클라이언트가 응답 수신용으로 임시로 여는 높은 번호 포트
5-tuple5-tuple(출발지 IP·포트, 목적지 IP·포트, 프로토콜) — 연결을 식별하는 5요소

Part 1. 이론 심화

1-1. 패킷은 실제로 어떻게 검사되나

인바운드 패킷 하나가 EC2에 도달하기까지, 그리고 응답이 나가기까지의 검사 지점:

인바운드:  외부 ─▶ [NACL 인바운드 규칙] ─▶ [SG 인바운드 규칙] ─▶ ENI ─▶ EC2
아웃바운드(응답): EC2 ─▶ [SG] ─▶ [NACL 아웃바운드 규칙] ─▶ 외부
  • NACL이 먼저(서브넷 경계) → 그다음 SG(ENI).
  • SG는 stateful이라 응답에 대해 규칙을 안 봐도 되지만, NACL은 stateless라 응답이 나가는 아웃바운드도 규칙을 통과해야 한다.
  • 같은 서브넷 내부 인스턴스끼리 통신하면 NACL은 개입하지 않는다(서브넷 경계를 넘지 않으므로). 이때는 SG만 적용된다 → "같은 서브넷인데 왜 안 되지?"는 대개 SG 문제.

1-2. Stateful의 실체 — 연결 추적(Connection Tracking)

SG가 "응답을 자동 허용"하는 건 마법이 아니라 연결 추적 테이블 덕분이다. AWS는 각 연결을 5-tuple로 기록해 두고, 그 연결에 속한 응답 패킷을 인식해 통과시킨다.

클라이언트 1.2.3.4:53820  ──TCP 80──▶  웹서버 10.0.1.10:80
  → SG가 이 흐름을 연결 추적 테이블에 등록
  → 응답 10.0.1.10:80 ─▶ 1.2.3.4:53820 은 "알고 있는 연결의 응답"이라 자동 통과
     (아웃바운드 규칙을 보지 않음)

실무 참고: SG 규칙을 삭제·변경해도 이미 추적 중인 기존 연결은 바로 끊기지 않고 타임아웃될 때까지 유지될 수 있다. "규칙을 지웠는데 왜 아직 붙어 있지?"의 원인.

1-3. Stateless와 Ephemeral 포트 — NACL 최대 함정

NACL은 연결 추적이 없다. 요청과 응답을 각각 허용해야 한다. 문제는 응답이 돌아가는 포트가 80이 아니라 클라이언트가 임시로 연 높은 번호 포트라는 것이다.

클라이언트 :53820  ──▶  서버 :80        (요청: NACL 인바운드 80 허용 필요)
서버 :80          ──▶  클라이언트 :53820 (응답: NACL 아웃바운드 1024-65535 허용 필요)
                                          ▲ 이 ephemeral 대역을 빠뜨리면 통신 절단

ephemeral 포트 범위는 클라이언트 종류마다 다르다 — 그래서 실무/시험 모두 넉넉히 1024–65535를 연다:

클라이언트대표 ephemeral 범위
Linux 커널32768–60999
Windows (최신)49152–65535
NAT Gateway1024–65535
ELB (ALB/NLB)1024–65535

그래서 커스텀 NACL에서는 아웃바운드(또는 응답 방향)에 TCP 1024–65535 allow를 관례적으로 넣는다.

1-4. 규칙 평가 방식의 차이

Security GroupNetwork ACL
평가모든 규칙을 종합(OR), 하나라도 맞으면 허용번호 오름차순, 처음 매칭된 규칙을 즉시 적용(뒤는 무시)
deny없음(암묵적 거부만)명시적 deny 가능
특정 IP 차단불가(allow-list라서)가능(그 IP만 deny 규칙)
NACL 예 (번호 낮은 게 우선):
  90  DENY  1.2.3.4/32      ← 먼저 평가 → 이 IP는 여기서 차단
  100 ALLOW 0.0.0.0/0 :443  ← 나머지는 통과

SG는 "허용 목록만 관리". 악성 IP 하나를 차단하는 건 SG로 원천적으로 불가능 → NACL deny의 존재 이유.


Part 2. AWS 실제 활용 사례 (핵심)

사례 1. 3-티어 웹 애플리케이션 — SG 체이닝(SG가 SG를 참조)

가장 정석적이고 시험·실무 모두 단골인 패턴. IP를 쓰지 않고 SG를 서로 참조해 계층 간 접근을 논리적으로 연결한다.

[인터넷] ─443─▶ [ALB]  (sg-alb)
                  │
                  ▼ (ALB가 연결 종료 후 백엔드로 새 연결)
             [Web/App EC2]  (sg-app)   ← Auto Scaling으로 IP 계속 바뀜
                  │
                  ▼
             [RDS]  (sg-db)

각 SG의 인바운드 규칙(소스가 IP가 아니라 다른 SG인 점이 핵심):

SG인바운드 규칙의미
sg-albTCP 443 from 0.0.0.0/0인터넷에서 HTTPS
sg-appTCP 80 from sg-albALB SG를 가진 것만 앱에 접근
sg-dbTCP 3306 from sg-app앱 SG를 가진 것만 DB 3306 접근

왜 이렇게 하나 (실무 이유):

  • Auto Scaling으로 앱 인스턴스 IP가 수시로 바뀌어도 규칙을 고칠 필요가 없다 — "sg-app을 가진 것"이라는 논리적 조건이라서.
  • 최소 권한: DB는 인터넷은 물론 ALB에서도 직접 못 오고, 오직 앱 계층에서만.
  • ALB는 연결을 종료하고 백엔드로 자기 이름으로 새 연결을 맺으므로 백엔드 SG는 ALB의 SG를 소스로 참조하면 된다.

시험 트리거: "allow only the application tier to access the database", "instances scale and IPs change" → SG가 SG를 참조.

사례 2. 관리 접근 — Bastion에서 SSM Session Manager로 (현대적 실무)

과거 방식 (Bastion Host):

운영자 ─22─▶ [Bastion EC2] (sg-bastion: 22 from 회사 IP만) ─22─▶ 프라이빗 EC2 (sg-app: 22 from sg-bastion)
  • 퍼블릭 서브넷에 점프박스를 두고, SSH는 회사 고정 IP에서만, 내부 인스턴스는 bastion SG에서만 22 허용.
  • 절대 하면 안 되는 것: 22 from 0.0.0.0/0 (전 세계에 SSH 개방 — 가장 흔한 사고).

현대 권장 방식 (SSM Session Manager):

운영자 ─▶ AWS Systems Manager ─▶ (SSM Agent) 프라이빗 EC2
  인바운드 22 규칙: 없음. 퍼블릭 IP: 없음. Bastion: 없음.
  • 인바운드 SSH 포트를 아예 열지 않고, 아웃바운드로 SSM에 연결해 셸을 얻는다.
  • SG 관점의 이점: 인바운드 공격 표면 = 0. 접근 통제는 IAM으로, 감사는 CloudTrail/세션 로그로.

시험/실무 감각: "SSH 포트를 열지 않고 EC2에 안전하게 접근" → SSM Session Manager(SG 인바운드 불필요).

사례 3. 공격 중 특정 IP/대역 차단 — NACL deny (SG로는 불가)

DDoS나 스캐닝의 출처 IP를 즉시 막아야 할 때. SG는 allow-list라 차단 규칙 자체가 없다. 서브넷 경계의 NACL에서 deny한다.

공격 대역 203.0.113.0/24 유입
  → 해당 서브넷 NACL:
      80  DENY  203.0.113.0/24   (낮은 번호로 먼저 평가)
      100 ALLOW 0.0.0.0/0 :443
  • 서브넷 전체 리소스에 일괄 적용된다는 점이 광역 차단에 유리.
  • 단, L7(HTTP 페이로드·SQLi 등) 기반 차단은 NACL로 못 함 → AWS WAF, 대규모 볼류메트릭 DDoS는 Shield/Network Firewall로 올라간다(다른 노트).

시험 트리거: "block a specific malicious IP range" → NACL deny.

사례 4. 서브넷 경계를 규정 준수 격리선으로 사용 — NACL 안전망

프라이빗 DB 서브넷은 애초에 인터넷과 통신할 이유가 없다. 개별 DB SG가 실수로 넓게 열려도, 서브넷 NACL이 인터넷 대역을 막아두면 사고를 예방한다.

DB 서브넷 NACL:
  인바운드  ALLOW  10.0.0.0/16(VPC 내부) 만
  아웃바운드 ALLOW 10.0.0.0/16 + ephemeral
  → 인터넷(0.0.0.0/0)과의 통신은 원천 차단 (SG 실수와 무관하게)
  • 이것이 "SG가 주력, NACL은 안전망"이라는 실무 분담의 전형. NACL은 광역·거친 규칙으로 두고, 세밀 제어는 SG에 맡긴다.

사례 5. ALB vs NLB 뒤 백엔드의 SG (자주 틀리는 실무 포인트)

로드밸런서 종류에 따라 백엔드 인스턴스 SG가 무엇을 허용해야 하는지가 달라진다.

LB 종류백엔드에서 보이는 출발지백엔드 SG 인바운드
ALBALB (연결을 종료·재생성)from sg-alb (LB의 SG 참조)
NLB (기본)클라이언트 원본 IP 보존클라이언트 CIDR를 허용해야 함(LB가 아니라!)
NLB + SG 기능(SG를 붙이면) NLB SG 참조 가능from sg-nlb
  • 함정: NLB 뒤 인스턴스 SG에 "NLB만 허용"이라고 넣으면 안 통한다. NLB는 기본적으로 클라이언트 IP를 그대로 전달하므로 백엔드 SG는 클라이언트 IP 대역을 허용해야 한다. (NLB에 SG를 붙이는 기능을 쓰면 SG 참조도 가능.)

사례 6. Self-referencing SG — 클러스터 내부 통신

같은 역할의 노드들이 서로 통신해야 할 때(예: EKS 노드, ElastiCache/DB 클러스터, 분산 앱), SG가 자기 자신을 소스로 참조한다.

sg-cluster 인바운드:
  All traffic  from  sg-cluster   ← "같은 SG를 가진 멤버끼리는 서로 허용"
  • 노드가 늘거나 IP가 바뀌어도 규칙 변경 불필요. VPC 기본 SG도 이 방식(자기 참조)으로 내부 통신을 허용한다.

사례 7. SG는 EC2만의 것이 아니다

SG는 ENI를 갖는 모든 리소스에 적용된다 — 실무에서 자주 잊는 지점.

리소스SG 적용 방식
RDS/AuroraDB에 SG 지정(앱 SG만 3306/5432 허용)
Lambda (VPC 연결)함수가 ENI를 얻고 SG 적용 → 프라이빗 RDS 접근
Interface VPC Endpoint엔드포인트 ENI의 SG로 어떤 SG가 이 엔드포인트를 쓸지 통제
ELB (ALB, NLB 옵션)LB 자체에 SG
ElastiCache노드에 SG

Part 3. 실무 운영·거버넌스

3-1. 흔한 실수(Anti-patterns)와 교정

안티패턴왜 위험한가올바른 방식
SSH 22 / RDP 3389 from 0.0.0.0/0전 세계에 관리 포트 개방회사 IP만, 또는 SSM Session Manager
계층 간 접근에 IP 하드코딩오토스케일로 IP 변동 시 깨짐SG 참조
모든 걸 NACL로 세밀 제어하려 함stateless·번호관리로 복잡·실수↑세밀제어는 SG, NACL은 광역 안전망
커스텀 NACL 만들고 규칙 미기입커스텀 NACL 기본은 전체 거부 → 전면 장애명시 allow(+ephemeral) 규칙 추가
통신 장애를 SG만 확인라우팅·NACL·SG 다층세 겹을 함께 점검
규칙을 너무 넓게(all traffic)연결 추적이 untracked화, 감사 어려움필요한 포트/소스만 좁게

3-2. 가시성·감사

목적도구
실제 허용/거부된 트래픽 관찰VPC Flow Logs (ACCEPT/REJECT 기록)
"0.0.0.0/0 SSH 열린 SG 탐지" 자동화AWS Config 규칙(restricted-ssh 등)
계정 전반 보안 상태 종합Security Hub

Flow Logs에서 REJECT가 보이면 SG 또는 NACL이 막은 것 → 어느 계층인지 좁혀 진단.


Common Wrong Directions

오답 방향왜 부족한가
SG로 특정 악성 IP 차단SG는 allow-only → 차단은 NACL deny
NACL이 응답을 자동 허용할 거라 가정NACL은 stateless → ephemeral 아웃바운드를 직접 열어야
NLB 뒤 SG에 "NLB만 허용"NLB는 클라이언트 IP 보존 → 클라이언트 CIDR 허용 필요
관리 접근을 위해 SSH를 0.0.0.0/0 개방공격 표면 폭증 → 회사 IP 한정 또는 SSM Session Manager
계층 접근에 IP 하드코딩오토스케일 IP 변동 → SG 참조
DB 보호를 SG만 신뢰서브넷 NACL 안전망으로 심층 방어
같은 서브넷 통신 실패를 NACL 탓서브넷 내부는 NACL 미개입 → SG 확인

Exam Triggers

문제에서 이런 표현이 나오면떠올릴 것
"allow only app tier to reach DB / IPs change with scaling"SG가 SG 참조
"block a specific IP/CIDR"NACL deny
"return/response traffic blocked"NACL ephemeral 포트 allow
"access EC2 without opening inbound SSH / no bastion"SSM Session Manager
"instances behind NLB can't be reached; SG references NLB"백엔드 SG가 클라이언트 CIDR 허용
"subnet-wide policy / compliance isolation"NACL
"instance-level, stateful firewall"SG
"detect security groups open to the world"AWS Config 규칙
"see which traffic was accepted/rejected"VPC Flow Logs

Memory Sentence

SG는 ENI 단위·stateful(연결 추적)·allow-only라 응답이 자동 허용되고 특정 IP는 못 막는다. NACL은 서브넷 단위·stateless·allow+deny라 악성 IP를 막을 수 있지만 ephemeral 포트를 직접 열어야 한다. 실무는 SG를 주력(계층 간 SG 참조)으로, NACL을 서브넷 안전망(광역 차단·규정 격리)으로 쓴다. 관리 접근은 SSH 개방 대신 SSM, NLB 뒤 SG는 클라이언트 IP를 허용, 가시성은 Flow Logs·감사는 Config.

References

댓글

아직 댓글이 없습니다.