오늘날 많은 인프라 조직들이 클라우드 환경을 효율적으로 관리하기 위해 Terraform과 같은 IaC(Infrastructure as Code) 도구를 도입하여 프로비저닝 과정을 자동화하고 생산성을 높이고 있습니다. 하지만 아무리 코드로 인프라를 깔끔하게 배포한다고 해도, 네트워크 통신의 기본 원리를 간과한 채 단순히 포트만 열어두는 보안 설계는 치명적인 운영 리스크를 안고 있습니다. 실제 네트워크 통신은 TCP, UDP, ICMP 등 각 프로토콜의 고유한 동작 방식과 연결 상태(State)에 따라 전혀 다르게 처리됩니다. 따라서 진정으로 안전한 클라우드 환경을 구축하려면 단순히 통로를 여닫는 수준을 넘어, 데이터가 오가는 전체적인 흐름을 정확히 이해하고 제어해야 합니다. 이 트래픽 흐름을 조절하는 핵심은 바로 보안 그룹(SG)과 NACL(Network Access Control List) 입니다. Stateful과 Stateless라는 상이한 동작 방식을 이해하고 인바운드와 아웃바운드 트래픽을 정교하게 제어하여 안전한 네트워크 환경을 구성하는 방법에 대해 알아보겠습니다.
목차
1. SG와 NACL이란? (Stateful vs Stateless)
2. Terraform으로 구성하는 SG 인바운드/아웃바운드
3. Terraform으로 구성하는 NACL 인바운드/아웃바운드
4. 아키텍처 다이어그램
5. 결론
#1 SG와 NACL이란?

먼저 SG와 NACL에 대해 알아보겠습니다.
SG(Security Group)란 AWS의 리소스들에게 오고가는 트래픽을 프로토콜과 포트 별로 허용 혹은 차단하는 리스트를 의미하고, NACL(Network Access Control List)이란 AWS의 서브넷들에게 오고가는 트래픽을 프로토콜과 포트 별로 허용 혹은 차단하는 리스트를 의미합니다. 두 기능 모두 동작하는 방식은 동일하나, 이 기능이 적용되는 주체가 리소스인지 서브넷인지에 따라 다르며 구성하는 방법 또한 달라집니다. 하지만 클라우드 네트워크 아키텍처를 설계할 때 이 둘을 구분 짓는 가장 결정적인 차이점은 적용 대상이 아니라, 바로 트래픽의 연결 상태(State)를 기억하는 방식에 있습니다.
Stateful vs Stateless
Stateful(상태 저장) 은 한 번 통과한 트래픽의 연결 세션을 기억하는 방식이며, Stateless(상태 비저장) 는 과거 통과한 트래픽의 연결 세션을 기억하지 않고 매번 오가는 패킷을 독립적으로 검사하는 방식입니다. 리소스로 향하는 패킷을 검사하는 보안 그룹(SG) 은 Stateful하게 동작하여, 인바운드 요청이 허용되면 그에 대한 아웃바운드 응답도 자동으로 통과됩니다. 반면 서브넷으로 향하는 패킷을 검사하는 네트워크 ACL(NACL) 은 Stateless하게 동작하므로 앞서 들어온 트래픽을 전혀 기억하지 못합니다. 따라서 AWS의 보안 아키텍처 설계 시 SG는 단방향 규칙만 신경 써도 되지만, NACL은 반드시 인바운드와 아웃바운드 양방향 허용 규칙을 꼼꼼하게 구성해야 합니다.
위 <그림 1>을 보며 상황을 가정해보겠습니다. Internet Gateway를 통해 들어온 포트 80번 HTTP 외부 인터넷 트래픽은 라우터를 거쳐 퍼블릭 서브넷 내의 로드밸런서와 같은 리소스로 이동하게 됩니다. 이때, 라우터에서 서브넷으로 이동하는 HTTP 패킷은 서브넷에 진입하기 전에 NACL 검사를 받습니다. 우리가 NACL에 0.0.0.0/0 으로 들어오는 80번 HTTP 요청을 허용하겠다! 라고 설계를 했다면 서브넷에 해당 패킷이 정상적으로 통과하고 로드밸런서까지 이동을 하게 됩니다. 여기서, 로드밸런서까지 이동한 패킷은 SG 검사를 한 번 더 받습니다. 우리가 보안 그룹에 0.0.0.0/0 소스로 부터 오는 80번 TCP(HTTP) 요청을 허용하겠다! 라고 설계를 했다면 이번 패킷도 정상적으로 로드밸런서에 이동하게 되고, 프라이빗 서브넷에 있는 서버까지 잘 전달됩니다.
위 내용처럼 인바운드 전달에서는 SG와 NACL에 규칙을 추가를 해야 내부까지 패킷이 전달됩니다. 그러나 아웃바운드 같은 경우에는 상태 저장의 차이가 존재하여 구성 방식이 달라집니다. 로드밸런서로부터 오는 패킷을 받은 서버는 다시 외부로 응답 패킷을 보내게 되는데, 이때 로드밸런서와 SG는 Stateful한 리소스이기 때문에, 추가 구성 없이 서브넷의 출입구인 NACL까지 잘 이동하게 됩니다. 즉, SG의 아웃바운드 허용 규칙을 0개로 하여도, 로드밸런서와 SG는 인바운드 되었던 패킷의 정보를 기억하여 역방향으로 응답을 돌려보낼 수 있다는 특징이 있습니다.
하지만 Stateless 방식인 NACL은 들어왔던 패킷의 내용을 전혀 기억하지 않기 때문에, 아웃바운드 규칙을 구성하지 않으면 응답 패킷이 인터넷 외부로 빠져나갈 수 없습니다. 이 NACL 검사를 통과하기 위해서는 응답 패킷만을 허용하는 Ephemeral Port(임시 포트)를 추가해야 합니다. 이 내용은 #3에서 자세히 알아보겠습니다.
#2 Terraform으로 구성하는 SG 인바운드/아웃바운드

이제부터 HCL Terraform 언어를 활용하여 보안 그룹을 설계해보겠습니다. <그림 2>는 퍼블릭 서브넷에 생성한 Application Load Balancer의 보안 그룹을 생성하는 코드이며, 보안 그룹의 이름, VPC ID를 설정하여 AWS 리소스들을 담을 그룹을 준비합니다.

<그림 3>은 HTTP 인바운드 규칙을 생성하는 코드입니다. 각 전달되는 파라미터는 다음과 같습니다.
- type : ingress 혹은 egress를 전달하여 인바운드 혹은 아웃바운드를 결정합니다.
- from_port, to_port : 허용할 포트 번호의 범위를 선택합니다.
- protocol : 허용 혹은 차단할 프로토콜을 결정합니다. (TCP, UDP, ...)
- cidr_blocks : 어떤 소스 IP에 위의 보안 규칙을 적용할지 결정합니다. (0.0.0.0/0 -> 모든 트래픽)
- security_group_id : 이 보안 규칙을 적용할 보안 그룹을 결정합니다.
위 처럼 설정을 하게 되면 80번 TCP로 오는 모든 HTTP 요청을 허용하는 규칙이 만들어집니다.

AWS 콘솔을 확인해보면 인바운드 규칙이 잘 추가된 것을 확인할 수 있습니다. 위의 그림은 443 포트의 HTTPS를 동일한 방식으로 추가한 결과물입니다.
같은 방식으로 ALB 말고도 ENI를 생성하는 모든 리소스들(EC2, Lambda, RDS, ...)에 보안 그룹을 생성하면 안전한 아키텍처를 설계가 가능합니다.
보안 그룹 구성 시에 고려할 점
- 보안 그룹은 NACL과는 다르게 규칙을 허용만 가능합니다.
- 모든 트래픽이 아닌 특정 서브넷에서 오는 트래픽만 허용하는 프라이빗 통신을 원할 경우, cidr_blocks를 해당 서브넷의 네트워크 주소 (ex. 10.0.1.0/16)를 작성해야 합니다.
- Stateful의 특성 덕분에 응답 규칙을 따로 추가할 필요가 없으며, 불필요한 아웃바운드 규칙은 최소화해야 합니다.
#3 Terraform으로 구성하는 NACL 인바운드/아웃바운드

이번에는 NACL을 구성하는 방법에 대해 알아보겠습니다. <그림 5>는 NACL 그룹을 생성하는 코드이며, 최소로 필요한 파라미터는 VPC ID입니다.

위 그림은 만든 NACL 그룹을 서브넷에 연결하는 작업입니다. 위 시나리오는 가용 영역 a, b 2개를 한 NACL로 적용시키는 상황입니다. subnet_id에는 서브넷 주소의 아이디를, network_acl_id에는 방금 만들었던 NACL의 로컬이름.아이디를 작성합니다.

위 그림은 HTTP 패킷을 허용하는 인바운드 규칙을 생성하는 코드입니다. 각 파라미터의 의미는 아래와 같습니다.
- network_acl_id : 만들었던 NACL의 로컬이름.id를 작성하여 어떤 NACL 그룹에 규칙을 적용할지 결정합니다.
- rule_number : 규칙에 임의의 번호를 부여합니다.
- egress : 아웃바운드 여부를 결정합니다.
- protocol : 허용 혹은 차단할 프로토콜을 결정합니다. (TCP, UDP, ...)
- rule_action : 해당 프로토콜, 포트, 소스에서 오는 패킷을 허용할지, 차단할지 결정합니다.
- cidr_block : 어떤 소스 IP에 위의 보안 규칙을 적용할지 결정합니다. (0.0.0.0/0 -> 모든 트래픽)
- from_port, to_port : 허용할 포트 번호의 범위를 선택합니다.

위 그림은 아웃바운드 규칙을 설정하는 코드입니다. NACL은 Stateless 방식으로 동작하므로, 트래픽이 서브넷을 빠져나가기 위해서는 아웃바운드 규칙을 필수적으로 명시해 주어야 합니다. 특히, 인터넷 외부로부터 들어온 요청에 대해 서버가 다시 응답 트래픽을 되돌려 보낼 때, 이 응답이 향하는 목적지 포트는 80번이나 443번이 아니라 클라이언트가 통신을 위해 임시로 열어둔 임시 포트(Ephemeral Port)가 됩니다. 클라이언트의 운영체제에 따라 보통 1024에서 65535 사이의 무작위 포트 번호가 할당됩니다. 따라서 NACL 아웃바운드 규칙을 구성할 때는 특정 포트로 고정하는 것이 아니라, 1024-65535와 같이 광범위한 임시 포트 대역을 모두 허용해 주어야만 통신이 도중에 끊기지 않고 정상적으로 반환될 수 있습니다.
NACL 구성 시에 고려할 점
- NACL은 보안 그룹과는 다르게 규칙에 허용 뿐만 아니라 명시적인 차단도 가능하므로, 특정 악성 IP를 원천 차단(Blacklist)하는 용도로 활용이 가능합니다.
- 규칙을 평가할 때 번호(Rule Number)가 낮을수록 우선순위가 높으며, 조건이 일치하는 규칙을 찾는 순간 검사를 종료합니다. 따라서 좁은 범위의 차단 규칙을 낮은 번호에 할당하고, 넓은 범위의 허용 규칙을 높은 번호에 배치하도록 번호를 신중하게 설계해야 합니다.
- Terraform으로 직접 생성하는 커스텀 NACL은 모든 트래픽을 차단하는 상태로 시작한다는 점을 주의해야 합니다.
- 임시포트를 아웃바운드 뿐만 아니라, 인바운드 규칙에도 생성해야 외부의 응답 트래픽을 수신할 수 있습니다.
#4 아키텍처 다이어그램

위 그림은 외부 클라이언트의 요청이 서브넷 내부의 EC2 인스턴스에 도달한 뒤, 다시 외부로 응답이 반환되는 네트워크 트래픽의 왕복 흐름을 시각화한 다이어그램입니다. 방어벽의 위치(서브넷 vs 인스턴스)와 특성(Stateless vs Stateful)에 따라 트래픽 검사 방식이 달라지게 됩니다.
결론
클라우드 네트워크 보안을 완벽하게 구현하기 위해서는, 방어벽의 위치뿐만 아니라 트래픽을 다루는 상태(State)의 차이를 명확히 이해해야 합니다. 가장 핵심적인 차이는 트래픽을 기억하는 Stateful한 보안 그룹과, 매번 독립적인 검사를 수행하는 Stateless한 NACL라는 동작 차이에 있습니다. 이로 인해 인바운드 요청에 대한 응답을 처리할 때, 보안 그룹은 아웃바운드 규칙 없이도 통신을 유연하게 허용하지만, NACL은 클라이언트를 위한 임시 포트(Ephemeral Port) 대역을 명시적으로 열어주어야만 원활한 통신이 가능합니다. 이 두 방어벽의 서로 다른 차이점을 이해하고 양방향 트래픽 흐름을 꼼꼼하게 설계한다면, 어떤 외부 보안 위협에도 안전한 인프라 환경을 구축할 수 있을 것입니다.
'Computer Science' 카테고리의 다른 글
| ISMS-P 인증 받는 클라우드 아키텍처 핵심 7가지 (0) | 2026.05.01 |
|---|---|
| ECS on EC2와 ECS on Fargate를 비용과 운영 관점에서 비교하기 (0) | 2026.04.15 |
| Route53 가중치 라우팅으로 안전하게 카나리아 배포하기 (0) | 2026.01.19 |
| MSA 환경에서 SNS + SQS, Apache Kafka를 활용하여 시스템 결합도 낮추기 (0) | 2025.12.28 |
| AWS VPC Endpoint를 활용한 보안 및 비용 최적화 (0) | 2025.12.26 |