NAT와 사설망 — 주소 하나로 수백 대가 인터넷을 쓰는 법, 그리고 P2P가 막히는 이유
NAT가 IPv4 고갈을 푸는 방법, NAPT 포트 다중화 변환 테이블, NAT 종류(full-cone·symmetric), 포트포워딩과 홀펀칭(STUN·TURN), conntrack, AWS NAT Gateway까지 사설망 통신을 다룹니다.
“공인 IP는 한 개인데, 집 안 기기는 열 개”
집 공유기에 노트북·폰·TV·콘솔이 다 붙어 있어도, ISP가 준 공인 IP는 보통 한 개입니다. 그런데 다들 동시에 인터넷이 됩니다. 이걸 가능하게 하는 게 NAT(Network Address Translation) 입니다.
NAT는 단순한 “주소 바꿔치기”가 아닙니다. IPv4 주소 고갈을 20년 넘게 버티게 한 핵심 기술이자, 동시에 P2P·화상통화·게임이 그렇게 고생하는 근본 원인이며, AWS에서 사설 서브넷이 인터넷에 나가는 유일한 통로(NAT Gateway)이기도 합니다. 이 글은 NAT의 변환 테이블을 들여다보고, 왜 어떤 NAT는 P2P가 되고 어떤 건 절대 안 되는지까지 내려갑니다.
NAPT 변환 테이블: NAT의 심장
집에서 쓰는 NAT는 정확히는 NAPT(Network Address Port Translation), 흔히 PAT라 부릅니다. 핵심은 포트 번호로 여러 내부 호스트를 구분한다는 것입니다.
내부 호스트가 패킷을 내보내면 NAT는 ① 출발지 주소·포트를 자신의 공인 IP·새 포트로 재작성하고 ② 그 매핑을 변환 테이블에 기록합니다. 응답이 돌아오면 그 테이블을 역조회해 원래 내부 호스트로 되돌립니다.
이 테이블 덕분에 NAT 뒤의 모든 기기가 같은 공인 IP를 공유하면서도, 응답이 엉뚱한 기기로 가지 않습니다. 구분자는 NAT가 새로 배정한 포트 번호(위에서 40001)입니다. 포트가 16비트라 이론상 한 공인 IP로 6만여 개의 동시 흐름을 다중화할 수 있습니다.
flowchart LR
A["사설 192.168.0.10:51000"] -->|out| N["NAT<br/>src 재작성 + 테이블 기록"]
N -->|"203.0.113.5:40001"| S[웹 서버]
S -->|"to 203.0.113.5:40001"| N2["NAT<br/>테이블 역조회"]
N2 -->|"to 192.168.0.10:51000"| A
NAT는 한 종류가 아니다 — P2P의 운명을 가르는 분류
NAT가 응답 패킷을 받아들이는 조건이 얼마나 까다로운지에 따라 동작이 갈립니다. 이 분류가 화상통화·게임의 P2P 성공률을 결정합니다.
| 유형 | 매핑 재사용 | 외부에서 들어오는 패킷 허용 조건 | P2P |
|---|---|---|---|
| Full-cone | 같은 내부 (IP:port) → 항상 같은 공인 포트 | 누구든 그 공인 포트로 보내면 통과 | 쉬움 |
| Restricted-cone | 〃 | 내가 먼저 보낸 적 있는 IP에서 온 것만 | 가능 |
| Port-restricted | 〃 | 내가 먼저 보낸 IP:port에서 온 것만 | 가능 |
| Symmetric | 목적지마다 다른 공인 포트 배정 | 그 목적지에서 온 것만 | 거의 불가 |
왜 symmetric NAT에서 P2P가 막히나. symmetric NAT는 목적지가 다르면 외부 포트도 다르게 배정합니다. 그래서 STUN 서버에 물어 알아낸 내 공인 포트가, 실제 상대에게 보낼 때는 다른 포트로 바뀝니다. 상대가 STUN으로 안 포트는 이미 무효 — 구멍이 안 뚫립니다. 통신사 모바일망·기업망이 흔히 이 유형이라, WebRTC가 TURN 릴레이로 폴백하는 이유가 됩니다.
NAT 트래버설: 막힌 문에 구멍 뚫기 (홀 펀칭)
서버는 공인 IP로 가만히 기다리면 되지만, NAT 뒤 두 피어가 서로 직접 연결하려면 문제가 생깁니다. 둘 다 사설망 안이라 상대가 먼저 들어올 수 없습니다. 해법이 홀 펀칭입니다. 공개된 랑데부(STUN) 서버로 서로의 공인 (IP:port)를 알아낸 뒤, 동시에 서로에게 패킷을 쏘아 각자의 NAT에 “나간 적 있음” 매핑을 만들어 구멍을 뚫습니다.
이게 안 되면(symmetric NAT 등) TURN 서버가 트래픽을 중계합니다 — 직접 연결 실패 시의 보험입니다. WebRTC의 ICE는 이 후보들(직접/STUN/TURN)을 순서대로 시도합니다.
디버깅: 변환 테이블을 직접 보라
NAT 문제는 추측하지 말고 테이블을 봐야 합니다. 리눅스에서 NAT는 netfilter의 conntrack이 상태를 추적합니다.
1
2
3
4
5
6
7
8
9
10
11
# NAT 규칙(어떤 트래픽이 MASQUERADE/SNAT/DNAT 되는지)
sudo iptables -t nat -L -n -v
# 살아있는 변환(연결 추적) 테이블 — 실제 매핑이 여기 있다
sudo conntrack -L | head
# tcp 6 431999 ESTABLISHED src=192.168.0.10 dst=93.184.216.34
# sport=51000 dport=443 src=93.184.216.34 dst=203.0.113.5
# sport=443 dport=40001 ...
# 현재 추적 중인 연결 수 / 한도
sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_max
프로덕션 함정 — conntrack 테이블 고갈. 트래픽이 폭증하면
nf_conntrack_count가nf_conntrack_max에 닿고, 그 순간 새 연결이 조용히 드롭됩니다(nf_conntrack: table full, dropping packet로그). 증상은 “간헐적 연결 실패”라 원인 찾기가 고약합니다. AWS NAT Gateway도 동시 연결·포트 배정에 한도가 있어, 한 목적지로 동시 연결이 폭주하면ErrorPortAllocation이 납니다 → 목적지를 분산하거나 NAT GW를 늘립니다.
AWS에서의 NAT: 사설 서브넷의 유일한 바깥문
AWS VPC에서 사설 서브넷의 인스턴스(예: 내부 DB·배치 서버)는 공인 IP가 없어 인터넷에 직접 못 나갑니다. 그런데 OS 패치·외부 API 호출은 해야 하죠. 이때 NAT Gateway가 공인 서브넷에 놓여 아웃바운드만 대신 내보내고 응답을 받아 돌려줍니다.
- 왜 아웃바운드 전용인가: 외부에서 먼저 들어오는 연결은 막아 사설 자원을 보호하면서, 안에서 시작한 연결의 응답만 통과시킵니다(상태 추적). NAT의 본질이 곧 보안 경계가 됩니다.
- 포트포워딩(DNAT) 은 반대 방향: 외부 → 내부 특정 호스트로 들여보내기. 집 공유기의 “포트 개방”, AWS에선 로드 밸런서/타깃 그룹이 그 역할을 합니다.
자세한 서브넷·라우팅 테이블 배치는 VPC 글, 인바운드 차단 규칙은 방화벽·보안그룹 글에서 다룹니다. NAT가 사설/공인 주소를 다루는 토대는 IP 주소·서브넷팅, 변환 후 패킷이 길을 찾는 과정은 라우팅에 있습니다.
면접/리뷰 단골 질문
- Q. NAT 하나로 어떻게 수백 대가 동시에 인터넷을 쓰나? → NAPT가 포트 번호로 흐름을 구분해 다중화한다. 응답은 변환 테이블 역조회로 원래 호스트에 돌아간다.
- Q. symmetric NAT에서 P2P가 왜 안 되나? → 목적지마다 외부 포트를 다르게 배정해서, STUN으로 알아낸 포트가 실제 상대에게 보낼 땐 무효가 된다 → 홀 펀칭 실패 → TURN 릴레이로 폴백.
- Q. 간헐적 연결 실패, NAT가 의심된다. 첫 확인은? →
nf_conntrack_countvsmax, AWS면 NAT GW의ErrorPortAllocation/연결 수 메트릭. 테이블 고갈이면 새 연결만 드롭된다. - Q. NAT는 방화벽인가? → 부수효과로 인바운드를 막지만, 보안 기능이 아니다. 명시적 방화벽/보안그룹과 함께 써야 한다.
정리
- NAT(정확히 NAPT)는 포트로 흐름을 구분해 공인 IP 하나에 수많은 사설 호스트를 다중화한다 — 변환 테이블이 심장.
- NAT 유형(cone/symmetric)이 P2P 성공 여부를 가른다. symmetric은 홀 펀칭 실패 → STUN/TURN으로 보완.
- 리눅스는 conntrack으로 상태 추적 → 테이블 고갈이 간헐적 드롭의 단골 원인.
- AWS NAT Gateway는 사설 서브넷의 아웃바운드 전용 통로. 인바운드는 포트포워딩(DNAT)/LB가 담당.
다음 글: NAT 뒤에서 여러 서버로 트래픽을 고르게 나누는 로드 밸런싱으로 이어집니다.
