목록으로 가기

AWS VPC 구성 — 서브넷, NAT Gateway, 보안그룹, NACL, 피어링

VPC를 처음부터 구성하는 방법. 퍼블릭/프라이빗 서브넷, 라우팅, NAT Gateway, 보안그룹 vs NACL, VPC 피어링까지 정리했습니다.

AWS VPC 구성 — 서브넷, NAT Gateway, 보안그룹, NACL, 피어링 ko posts aws VPC를 처음부터 구성하는 방법. 퍼블릭/프라이빗 서브넷, 라우팅, NAT Gateway, 보안그룹 vs NACL, VPC 피어링까지 정리했습니다.

개요

AWS에서 서버를 띄우려면 가장 먼저 VPC(네트워크)를 설계해야 합니다. VPC 없이는 EC2도, RDS도, EKS도 만들 수 없습니다.

이 글은 AWS 네트워크의 핵심인 VPC 구성 요소를 하나씩 정리합니다.

1. VPC란

상세 내용

VPC (Virtual Private Cloud) = AWS 안에 만드는 나만의 가상 네트워크

AWS 계정 안에 논리적으로 격리된 네트워크를 만드는 것입니다. 이 안에 서버, DB, 로드밸런서를 배치합니다.

AWS Cloud
└── VPC (10.0.0.0/16)
    ├── Public Subnet (10.0.1.0/24)  ← 인터넷 접근 가능
    ├── Private Subnet (10.0.2.0/24) ← 인터넷 직접 불가
    └── DB Subnet (10.0.3.0/24)      ← DB 전용

VPC 생성 시 결정할 것

항목 설명 예시
CIDR 블록 VPC 전체 IP 범위 10.0.0.0/16 (65,536개 IP)
리전 VPC가 위치할 AWS 리전 ap-northeast-2 (서울)

CIDR 선택 가이드

VPC의 IPv4 CIDR 블록 크기는 공식 문서 기준으로 /16(65,536개 주소)에서 /28(16개 주소) 사이만 가능합니다. 즉 /16보다 큰 범위는 하나의 CIDR로 지정할 수 없고, 필요하면 CIDR을 추가로 연결합니다.

CIDR 주소 수 용도
/16 65,536 허용되는 최대 크기
/20 4,096 중규모
/24 256 소규모/테스트
/28 16 허용되는 최소 크기

나중에 VPC 피어링이나 VPN 연결할 때 CIDR이 겹치면 안 되니까, 처음부터 여유 있게 /16으로 잡는 게 좋습니다.

# AWS CLI로 VPC 생성
aws ec2 create-vpc --cidr-block 10.0.0.0/16 --tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=main-vpc}]'

2. 서브넷

상세 내용

서브넷 = VPC를 작은 단위로 나눈 것

AZ(가용 영역)별로 서브넷을 나누고, 용도별(public/private)로 구분합니다.

일반적인 구성 (2 AZ 기준)

VPC: 10.0.0.0/16
├── ap-northeast-2a
│   ├── public-subnet-a:  10.0.1.0/24
│   ├── private-subnet-a: 10.0.2.0/24
│   └── db-subnet-a:      10.0.3.0/24
│
└── ap-northeast-2c
    ├── public-subnet-c:  10.0.11.0/24
    ├── private-subnet-c: 10.0.12.0/24
    └── db-subnet-c:      10.0.13.0/24

왜 2개 AZ에 나누냐

  • 하나의 AZ가 장애나도 다른 AZ에서 서비스 유지 (고가용성)
  • ALB, RDS Multi-AZ 사용하려면 최소 2개 AZ에 서브넷 필요

Public vs Private 서브넷

종류 인터넷 접근 용도
Public 직접 가능 (IGW 연결) ALB, Bastion, NAT Gateway
Private NAT 통해서만 앱 서버, 워커 노드
DB 불가 (완전 격리) RDS, ElastiCache

서브넷 크기와 실제 쓸 수 있는 IP

서브넷의 IPv4 CIDR 크기도 /28에서 /16 사이입니다. 그리고 공식 문서 기준으로 각 서브넷 CIDR의 처음 네 개 주소와 마지막 주소는 AWS가 예약해서 EC2 같은 리소스에 할당할 수 없습니다. 서브넷당 5개가 빠지는 셈입니다.

서브넷 CIDR 전체 주소 사용 가능
/24 256 251
/26 64 59
/28 16 11

ALB처럼 서브넷 IP를 여러 개 쓰는 리소스가 들어가면 이 5개 차이가 생각보다 빨리 체감됩니다. /28로 잘게 자르면 쓸 수 있는 주소가 11개뿐입니다.

# 서브넷 생성
aws ec2 create-subnet --vpc-id vpc-xxx --cidr-block 10.0.1.0/24 --availability-zone ap-northeast-2a

3. Internet Gateway와 NAT Gateway

상세 내용

Internet Gateway (IGW) = VPC가 인터넷과 통신하는 출입구

IGW를 VPC에 연결하고, Public 서브넷의 라우팅 테이블에 IGW를 추가하면 해당 서브넷에서 인터넷 접근이 가능합니다.

인터넷 ↔ IGW ↔ Public Subnet (ALB, Bastion)

NAT Gateway = Private 서브넷에서 인터넷으로 나가는 통로

Private 서브넷의 서버가 패키지 설치나 API 호출을 위해 인터넷에 접근해야 할 때 사용합니다. 외부에서 Private 서버로 직접 접근은 불가.

Private Subnet → NAT Gateway (Public에 위치) → IGW → 인터넷
                     (나가는 것만 가능, 들어오는 건 차단)

비용 주의

  • IGW: 인터넷 게이트웨이 자체에는 요금이 없습니다. 다만 이를 통해 나가는 트래픽에는 데이터 전송 요금이 붙습니다.
  • NAT Gateway: 프로비저닝된 시간당 요금 + 처리한 데이터 GB당 요금으로 과금됩니다. 단가는 리전마다 다르므로 금액은 VPC 요금 페이지에서 확인하는 게 맞습니다.
  • 가용성 관련 공식 권장: 여러 AZ의 리소스가 NAT Gateway 하나를 공유하면 그 AZ에 장애가 났을 때 다른 AZ 리소스도 인터넷 접근을 잃습니다. AZ에 독립적인 구성을 원하면 AZ마다 NAT Gateway를 만들고, 각 서브넷 라우팅을 같은 AZ의 NAT Gateway로 보냅니다.
  • 반대로 NAT Gateway를 하나만 두고 여러 AZ가 공유하면 시간당 요금은 줄지만, 위 장애 범위와 AZ 간 데이터 전송 요금을 감수하는 선택입니다.
# NAT Gateway 생성 (Elastic IP 필요)
aws ec2 allocate-address --domain vpc
aws ec2 create-nat-gateway --subnet-id subnet-public-a --allocation-id eipalloc-xxx

4. 라우팅 테이블

상세 내용

라우팅 테이블 = “이 목적지로 가려면 어디로 보내라"는 규칙

서브넷마다 라우팅 테이블을 연결합니다.

Public 서브넷 라우팅 테이블

Destination Target 의미
10.0.0.0/16 local VPC 내부 통신
0.0.0.0/0 igw-xxx 나머지는 인터넷으로

Private 서브넷 라우팅 테이블

Destination Target 의미
10.0.0.0/16 local VPC 내부 통신
0.0.0.0/0 nat-xxx 나머지는 NAT로 (인터넷 나감)

DB 서브넷 라우팅 테이블

Destination Target 의미
10.0.0.0/16 local VPC 내부만

DB 서브넷은 인터넷 경로 자체를 안 넣습니다. 완전 격리.

# 라우팅 테이블 생성 + 서브넷 연결
aws ec2 create-route-table --vpc-id vpc-xxx
aws ec2 create-route --route-table-id rtb-xxx --destination-cidr-block 0.0.0.0/0 --gateway-id igw-xxx
aws ec2 associate-route-table --route-table-id rtb-xxx --subnet-id subnet-xxx

5. 보안그룹 (Security Group)

상세 내용

보안그룹 = 인스턴스 단위의 방화벽

특징 설명
적용 단위 ENI (인스턴스/서비스)
상태 Stateful (응답 트래픽 자동 허용)
기본 동작 모든 인바운드 차단, 모든 아웃바운드 허용
규칙 허용만 가능 (거부 규칙 없음)

일반적인 구성

ALB 보안그룹:
  인바운드: 80, 443 ← 0.0.0.0/0 (모든 곳에서)
  
앱 서버 보안그룹:
  인바운드: 8080 ← ALB 보안그룹 (ALB에서만)
  
DB 보안그룹:
  인바운드: 3306 ← 앱 서버 보안그룹 (앱에서만)

보안그룹끼리 참조 = “이 보안그룹에 속한 것만 허용”

IP 대신 보안그룹 ID로 참조하면, 서버가 늘어나도 규칙 수정 안 해도 됩니다.

# 보안그룹 생성
aws ec2 create-security-group --group-name app-sg --description "App server SG" --vpc-id vpc-xxx

# 인바운드 규칙 추가 (ALB SG에서 8080 허용)
aws ec2 authorize-security-group-ingress --group-id sg-app --protocol tcp --port 8080 --source-group sg-alb

6. NACL (Network ACL)

상세 내용

NACL = 서브넷 단위의 방화벽

항목 Security Group NACL
적용 단위 인스턴스 서브넷
상태 Stateful Stateless
규칙 허용만 허용 + 거부
평가 순서 전체 평가 번호 순서대로 (낮은 번호 우선)
기본 동작 인바운드 차단 Default NACL은 모든 허용, 새로 만든 Custom NACL은 모든 차단

Stateless란?

인바운드 허용해도 아웃바운드를 별도로 열어줘야 응답이 나갑니다. 이걸 놓치면 “접속은 되는데 응답이 안 오는” 상황.

NACL 규칙 예시

규칙 번호 유형 포트 소스 허용/거부
100 HTTP 80 0.0.0.0/0 허용
110 HTTPS 443 0.0.0.0/0 허용
120 SSH 22 10.0.0.0/16 허용
200 모든 모든 특정IP 거부
* 모든 모든 0.0.0.0/0 거부

규칙 번호는 1부터 32766까지 쓸 수 있고, 번호가 낮은 규칙부터 평가됩니다. 트래픽이 어떤 규칙에 매칭되면 그 규칙이 적용되고 뒤쪽 규칙은 보지 않습니다. 그래서 특정 IP를 차단하려면 허용 규칙보다 낮은 번호에 거부 규칙을 넣어야 합니다. 마지막 * 규칙은 어떤 번호 규칙에도 매칭되지 않은 패킷을 거부하는 항목이고 수정할 수 없습니다. 공식 문서는 나중에 규칙을 끼워 넣기 쉽도록 100, 200처럼 번호 사이에 간격을 두라고 권장합니다.

어느 쪽을 쓸지 판단하는 기준: 보안그룹은 stateful하고 인스턴스 단위라, 허용한 요청의 응답 트래픽은 반대 방향 규칙 없이도 통과합니다. NACL은 stateless하고 서브넷 단위라 인바운드와 아웃바운드를 각각 열어야 합니다. 그래서 인스턴스별 접근 제어는 보안그룹으로 표현되고, NACL이 필요한 경우는 두 가지입니다. 보안그룹에는 거부 규칙이 없으므로 특정 소스를 명시적으로 차단해야 할 때, 그리고 서브넷에 속한 리소스 전체에 같은 규칙을 한 번에 적용해야 할 때입니다.

7. VPC 피어링과 Transit Gateway

상세 내용

VPC 피어링 = 두 VPC를 직접 연결

서로 다른 VPC, 서로 다른 계정의 VPC끼리 프라이빗 통신이 가능합니다.

VPC A (10.0.0.0/16) ←→ 피어링 ←→ VPC B (10.1.0.0/16)
  • CIDR이 겹치면 피어링 불가
  • 양쪽 라우팅 테이블에 상대방 CIDR 추가 필요
  • 전이적 라우팅 안 됨 (A↔B, B↔C 피어링해도 A↔C 직접 불가)

Transit Gateway = 여러 VPC를 중앙 허브로 연결

VPC가 3개 이상이면 피어링은 복잡해집니다. Transit Gateway가 중앙 라우터 역할.

VPC A ─┐
VPC B ──┼── Transit Gateway ── On-Premise (VPN/Direct Connect)
VPC C ─┘
방식 VPC 2개 VPC 3개+ 비용
피어링 간단 복잡 (N×N) 낮음
Transit Gateway 과함 깔끔 높음 (시간당 과금)
# VPC 피어링 요청
aws ec2 create-vpc-peering-connection --vpc-id vpc-a --peer-vpc-id vpc-b

# 수락
aws ec2 accept-vpc-peering-connection --vpc-peering-connection-id pcx-xxx

관련 포스트

AWS IAM 유저, 역할, 정책 — 최소 권한 원칙과 크로스 계정 접근 IAM User와 Role 차이, Policy 작성법, STS로 임시 자격 증명 받기, 크로스 계정 접근까지 … EC2, ECS, EKS 차이점과 Auto Scaling, Fargate 구성 방법 EC2 인스턴스 타입 선택부터 Auto Scaling Group, ECS vs EKS 비교, Fargate …