Security Group vs Network ACL: 상태 저장 방식과 적용 계층의 차이
VPC 트래픽 제어를 처음 설계할 때 가장 흔히 겪는 혼란이 있다. Security Group과 Network ACL 둘 다 '방화벽'처럼 동작하는데, 왜 인바운드 규칙만 열었는데 어떤 건 통신이 되고 어떤 건 안 되는지 — 이 차이를 모르면 프로덕션에서 반드시 한 번은 삽질한다.
TL;DR — Security Group vs Network ACL 핵심 비교
| 항목 | Security Group | Network ACL (NACL) |
|---|---|---|
| 적용 계층 | 인스턴스(ENI) 레벨 | 서브넷 레벨 |
| 상태 저장 여부 | Stateful (응답 트래픽 자동 허용) | Stateless (인바운드·아웃바운드 별도 규칙 필요) |
| 규칙 평가 방식 | 모든 규칙을 평가 후 허용 여부 결정 | 번호 순서대로 평가, 첫 매칭 규칙 적용 |
| 기본 동작 | 모든 인바운드 거부, 모든 아웃바운드 허용 | 모든 인바운드·아웃바운드 허용 (기본 NACL 기준) |
| Allow/Deny 규칙 | Allow 규칙만 지원 | Allow 및 Deny 규칙 모두 지원 |
| 연결 대상 | ENI에 직접 연결 (인스턴스당 복수 적용 가능) | 서브넷에 연결 (서브넷당 하나의 NACL) |
Security Group과 Network ACL의 동작 원리
두 서비스 모두 VPC 내 트래픽을 필터링하지만, 동작하는 위치와 방식이 근본적으로 다르다. Security Group은 ENI(Elastic Network Interface)에 연결되어 인스턴스 단위로 동작하고, NACL은 서브넷 경계에서 동작하여 해당 서브넷을 드나드는 모든 트래픽에 적용된다.
트래픽이 실제로 처리되는 순서를 보면 이 차이가 명확해진다. 인터넷에서 EC2 인스턴스로 들어오는 패킷은 인터넷 게이트웨이 → 라우팅 테이블 → NACL(인바운드) → Security Group(인바운드) 순으로 통과한다. 응답 패킷은 반대 방향으로 Security Group(아웃바운드) → NACL(아웃바운드) → 인터넷 게이트웨이를 거친다.
- 인터넷에서 패킷이 인터넷 게이트웨이(IGW)로 진입한다.
- VPC 라우팅 테이블이 대상 서브넷으로 패킷을 전달한다.
- 서브넷 경계에서 NACL 인바운드 규칙이 번호 순서대로 평가된다. 첫 번째 매칭 규칙이 적용되고 평가가 종료된다.
- NACL을 통과한 패킷이 ENI에 도달하면 Security Group 인바운드 규칙이 평가된다. 모든 규칙을 검토한 뒤 하나라도 허용 규칙이 있으면 통과한다.
- 응답 트래픽은 반대 경로를 따른다. Security Group은 Stateful이므로 아웃바운드 규칙 없이도 응답을 자동 허용한다. NACL은 Stateless이므로 아웃바운드 규칙을 별도로 구성해야 한다.
Security Group — Stateful 동작의 실제 의미
Security Group이 'Stateful'이라는 말은, 연결 추적(connection tracking)을 수행한다는 뜻이다. 인바운드 요청이 허용되면, 그 연결에 대한 응답 트래픽은 아웃바운드 규칙과 무관하게 자동으로 허용된다. 반대로 아웃바운드 요청이 허용되면 그 응답 인바운드도 자동 허용된다.
Security Group의 Stateful 동작은 마치 회전문과 같다. 한 번 들어가는 것이 허용되면, 나오는 것은 별도 허가 없이 자동으로 열린다. NACL은 일반 문과 같아서 들어올 때와 나갈 때 각각 별도의 열쇠가 필요하다.
이 때문에 Security Group에서는 인바운드 규칙만 신경 써도 기본적인 서버 통신이 가능한 경우가 많다. 기본 아웃바운드 규칙이 모든 트래픽을 허용하도록 설정되어 있고, 응답 트래픽은 연결 추적으로 처리되기 때문이다.
Security Group 규칙 평가 방식도 중요하다. NACL과 달리 규칙에 번호 우선순위가 없다. 연결된 모든 Security Group의 모든 규칙을 평가하여, 하나라도 허용 규칙이 매칭되면 트래픽이 허용된다. Deny 규칙을 지원하지 않으므로, 특정 IP를 명시적으로 차단하려면 NACL을 사용해야 한다.
Security Group 설정 예시
# Security Group 생성
aws ec2 create-security-group \
--group-name web-server-sg \
--description "Web server security group" \
--vpc-id vpc-0abcd1234efgh5678
# HTTPS 인바운드 허용 (아웃바운드 응답은 Stateful로 자동 처리)
aws ec2 authorize-security-group-ingress \
--group-id sg-0123456789abcdef0 \
--protocol tcp \
--port 443 \
--cidr 0.0.0.0/0
# 현재 Security Group 규칙 확인
aws ec2 describe-security-groups \
--group-ids sg-0123456789abcdef0 \
--query 'SecurityGroups[*].{InboundRules:IpPermissions,OutboundRules:IpPermissionsEgress}'
Network ACL — Stateless 동작과 규칙 번호의 함정
NACL은 연결 상태를 추적하지 않는다. 각 패킷을 독립적으로 평가한다. 인바운드 HTTP 요청을 허용했더라도, 서버가 보내는 응답 패킷은 NACL 아웃바운드 규칙에서 별도로 허용되어야 한다.
여기서 실수가 자주 발생한다. TCP 응답 트래픽은 클라이언트의 임시 포트(ephemeral port)로 전송된다. AWS 공식 문서에 따르면 Linux 커널의 경우 일반적으로 32768–60999 범위를 사용하지만, 클라이언트 OS에 따라 다를 수 있다. NACL 아웃바운드 규칙에서 이 범위를 허용하지 않으면 응답이 차단된다.
- 클라이언트가 서버 포트 443으로 TCP SYN을 전송한다. 클라이언트 측 임시 포트(예: 54321)가 소스 포트로 사용된다.
- NACL 인바운드 규칙 100번이 포트 443 인바운드를 허용한다. 패킷이 EC2에 도달한다.
- EC2가 응답 패킷을 전송한다. 소스 포트는 443, 목적지 포트는 클라이언트 임시 포트 54321이다.
- NACL 아웃바운드 규칙에 임시 포트 범위 허용이 없으면 응답이 차단된다. Security Group은 이미 Stateful로 허용했지만 NACL이 막는다.
- 클라이언트는 응답을 받지 못하고 연결 타임아웃이 발생한다.
NACL 규칙은 번호 순서대로 평가되며 첫 번째 매칭 규칙이 적용된다. 규칙 번호 100에서 허용하고 규칙 번호 200에서 동일 트래픽을 거부하면, 규칙 100이 적용되어 허용된다. 규칙 번호 간격을 10 또는 100 단위로 설정하는 이유가 여기 있다 — 나중에 규칙을 삽입할 여지를 남기기 위해서다.
Network ACL 설정 예시
🔽 NACL 규칙 설정 CLI 전체 보기
# 현재 서브넷에 연결된 NACL 확인
aws ec2 describe-network-acls \
--filters Name=association.subnet-id,Values=subnet-0abcd1234efgh5678 \
--query 'NetworkAcls[*].{AclId:NetworkAclId,Entries:Entries}'
# NACL 인바운드 규칙 추가 — HTTPS 허용
aws ec2 create-network-acl-entry \
--network-acl-id acl-0123456789abcdef0 \
--rule-number 100 \
--protocol tcp \
--rule-action allow \
--ingress \
--cidr-block 0.0.0.0/0 \
--port-range From=443,To=443
# NACL 아웃바운드 규칙 추가 — 임시 포트 범위 허용 (응답 트래픽)
aws ec2 create-network-acl-entry \
--network-acl-id acl-0123456789abcdef0 \
--rule-number 100 \
--protocol tcp \
--rule-action allow \
--egress \
--cidr-block 0.0.0.0/0 \
--port-range From=1024,To=65535
# NACL 인바운드 규칙 추가 — 특정 IP 명시적 차단 (Security Group으로는 불가)
aws ec2 create-network-acl-entry \
--network-acl-id acl-0123456789abcdef0 \
--rule-number 50 \
--protocol -1 \
--rule-action deny \
--ingress \
--cidr-block 203.0.113.0/24
실제 장애 사례 — Security Group만 열었는데 왜 안 되지?
새로운 서브넷을 생성하고 웹 서버를 배포했다. Security Group에서 포트 80, 443을 열었고, EC2 내부에서 curl localhost는 정상 응답한다. 그런데 외부에서 접근하면 연결이 타임아웃된다.
처음엔 Security Group 규칙을 다시 확인한다. 규칙은 맞다. 라우팅 테이블도 확인한다. IGW도 연결되어 있다. 그런데 안 된다.
실제 원인은 NACL이었다. 커스텀 NACL을 새로 만들어 서브넷에 연결했는데, 기본 NACL과 달리 커스텀 NACL은 생성 시 모든 트래픽을 거부하는 상태로 시작한다. Security Group은 인스턴스 레벨에서 허용했지만, 서브넷 경계의 NACL이 패킷을 이미 차단하고 있었던 것이다.
NACL은 패킷을 조용히 버린다. TCP RST를 보내지 않는다. 그래서 클라이언트 입장에서는 연결 거부가 아니라 타임아웃으로 보인다. 이 증상이 NACL 차단의 특징적인 신호다.
# 서브넷에 연결된 NACL과 규칙 전체 확인
aws ec2 describe-network-acls \
--filters Name=association.subnet-id,Values=subnet-0abcd1234efgh5678 \
--query 'NetworkAcls[*].{AclId:NetworkAclId,IsDefault:IsDefault,Entries:Entries}'
커스텀 NACL을 사용할 때는 반드시 인바운드와 아웃바운드 규칙을 명시적으로 구성해야 한다. 기본 NACL(IsDefault: true)은 모든 트래픽을 허용하지만, 커스텀 NACL은 그렇지 않다.
Security Group과 Network ACL을 함께 설계하는 방법
두 계층을 함께 사용할 때 역할을 명확히 분리하면 관리가 쉬워진다. Security Group은 인스턴스 단위의 세밀한 접근 제어에 사용하고, NACL은 서브넷 단위의 광범위한 차단 — 특히 특정 IP 대역을 명시적으로 거부해야 할 때 — 에 활용한다.
- NACL은 서브넷 전체에 적용되므로 광범위한 IP 차단이나 서브넷 간 트래픽 제어에 적합하다.
- Security Group은 인스턴스별로 다른 규칙을 적용할 수 있어 마이크로서비스 환경에서 서비스 간 접근 제어에 유리하다.
- Security Group 참조(Source SG ID)를 활용하면 IP 대신 다른 Security Group을 소스로 지정할 수 있어, 동적 IP 환경에서도 안정적인 규칙 관리가 가능하다.
- NACL의 Stateless 특성으로 인해 임시 포트 범위를 아웃바운드 규칙에 반드시 포함해야 한다. 이를 누락하면 Security Group 설정이 올바르더라도 통신이 단절된다.
Security Group 간 참조 설정 예시
# 애플리케이션 서버 SG에서 데이터베이스 SG로의 접근만 허용
# (IP 대신 Security Group ID를 소스로 지정)
aws ec2 authorize-security-group-ingress \
--group-id sg-0db1234567890abcd \
--protocol tcp \
--port 5432 \
--source-group sg-0app123456789abcd
Security Group vs Network ACL — 언제 무엇을 써야 하는가
대부분의 접근 제어는 Security Group으로 충분하다. Stateful 동작 덕분에 규칙이 단순하고, 인스턴스 단위 제어가 가능하며, 다른 Security Group을 소스로 참조하는 기능이 강력하다.
NACL이 필요한 시나리오는 명확하다. 특정 IP 대역을 명시적으로 Deny해야 할 때, 서브넷 전체에 일괄 적용되는 규칙이 필요할 때, 또는 심층 방어(defense in depth) 전략의 일환으로 두 계층 모두 활용하고자 할 때다.
NACL의 Deny 규칙은 Security Group으로 대체할 수 없다. 이것이 NACL을 완전히 무시하면 안 되는 이유다.
마무리 및 다음 단계
Security Group과 Network ACL의 핵심 차이는 두 가지다. Security Group은 ENI 레벨에서 동작하는 Stateful 방화벽이고, NACL은 서브넷 레벨에서 동작하는 Stateless 필터다. 이 차이를 이해하면 트래픽이 왜 차단되는지, 어느 계층에서 문제가 발생했는지 빠르게 진단할 수 있다.
다음 단계로 VPC Flow Logs를 활성화하면 NACL과 Security Group 중 어느 계층에서 트래픽이 차단되었는지 로그로 확인할 수 있다. 공식 문서에서 VPC Flow Logs의 action 필드와 pkt-srcaddr 필드를 활용한 트래픽 분석 방법을 참고하길 권장한다.
핵심 용어 정리
| 용어 | 설명 |
|---|---|
| Stateful | 연결 상태를 추적하여 요청에 대한 응답 트래픽을 자동으로 허용하는 방식. Security Group이 이 방식으로 동작한다. |
| Stateless | 각 패킷을 독립적으로 평가하며 연결 상태를 추적하지 않는 방식. NACL이 이 방식으로 동작하며 인바운드·아웃바운드 규칙을 각각 구성해야 한다. |
| ENI (Elastic Network Interface) | EC2 인스턴스에 연결되는 가상 네트워크 인터페이스. Security Group은 ENI 단위로 연결된다. |
| 임시 포트 (Ephemeral Port) | 클라이언트가 서버에 연결할 때 OS가 자동으로 할당하는 단기 포트. TCP 응답 트래픽의 목적지 포트로 사용되며 NACL 아웃바운드 규칙에서 허용해야 한다. |
| 연결 추적 (Connection Tracking) | Security Group이 허용된 연결의 상태를 기록하여 응답 트래픽을 자동으로 허용하는 메커니즘. |
댓글
댓글 쓰기