왜 P2P가 막히는가? — NAT, STUN, TURN 인터넷 구조 이해하기
분명 STUN이 알려준 공인 주소를 상대에게 전달했는데도 P2P 연결이 막히는 경험, 해본 적 있으신가요? 범인은 대개 공유기의 NAT입니다. 이 글은 NAT가 사설 주소와 공인 주소를 어떻게 매핑하는지, 그리고 Symmetric NAT에서 목적지가 바뀔 때마다 포트가 달라져 홀펀칭이 실패하는 과정을 단계별로 풀어 줍니다. 왜 이때 TURN 릴레이가 필요한지, ICE가 host에서 STUN, TURN 순으로 후보를 시도하는 이유까지 자연스럽게 이해하게 됩니다.
P2P(피어 간 직접 연결)가 공유기(NAT) 나 방화벽 때문에 실패하는 경우가 많습니다. 이 글에서는 NAT가 무엇인지, NAT 4가지 타입과 그 차이, 그리고 Symmetric NAT에서 왜 “STUN이 알려준 포트로 상대가 접속해도 막히는지”를 단계별로 정리합니다.
NAT란?
NAT(Network Address Translation)는 내부망(가정·회사)의 사설 IP:포트와 외부에 보이는 공인 IP:포트를 매핑해 주는 장치입니다. 외부에서는 “공인 IP:포트”로만 보이기 때문에, 상대방이 “내가 보이는 주소”를 모르면 P2P 연결을 시도하기 어렵습니다. STUN 서버에 요청을 보내면 “당신의 공인 주소는 1.2.3.4:5000입니다”처럼 알려 주고, 이 주소를 상대에게 전달해 서로 연결을 시도합니다. 다만 NAT 종류에 따라 “한 번 매핑된 포트로 누가 접속해도 되는지”, “목적지가 바뀌면 포트도 바뀌는지”가 달라져 P2P가 막히는 경우가 있습니다.
📊 NAT 4가지 타입
| NAT 타입 | 설명 |
|---|---|
| Full Cone | 한 번 매핑되면 어디서든 해당 포트로 접속 가능 |
| Restricted Cone | 클라이언트가 접속했던 IP에서만 해당 포트로 접속 가능 |
| Port Restricted Cone | 접속했던 IP:포트에서만 접속 가능 |
| Symmetric | 목적지(IP:포트)마다 다른 포트가 매핑됨 → P2P가 가장 까다로움 |
정정: 위 4분류는 RFC 3489(구 STUN)의 모델로, 개념 이해에는 유용하지만 현행 STUN(RFC 8489)에서는 이 엄격한 분류를 폐기하고 매핑(Mapping)/필터링(Filtering) 동작을 분리해 기술합니다(RFC 4787, BEHAVE). 실제 NAT는 EIM(Endpoint-Independent Mapping)/EDM(Endpoint-Dependent Mapping)와 필터링 정책의 조합으로 동작이 결정되며, "Symmetric NAT"는 사실상 EDM에 해당합니다.
Symmetric NAT에서는 “목적지가 바뀌면 포트도 바뀌기” 때문에, STUN이 알려준 주소로 상대가 접속해 와도 공유기가 다른 세션으로 보고 막아 버립니다. 이때는 TURN 서버가 중간에서 릴레이해 줘야 연결이 됩니다.
📦 Symmetric NAT 시나리오: 왜 포트가 달라지나? (클릭 시 시각화)
1. STUN 서버에 패킷을 보낼 때
STUN 서버가 "당신의 공인 주소는 1.2.3.4:5000 입니다"라고 알려 줍니다.
2. Peer B에게 패킷을 보낼 때
목적지가 다르면 NAT가 다른 포트를 새로 만들어 버립니다.
3. 왜 B가 5000으로 접속하면 차단되나요?
- B는 STUN을 통해 “상대 주소는 1.2.3.4:5000”이라고만 알고 있습니다.
- 하지만 공유기 입장에서 5000번은 “STUN 서버와 통신할 때 쓴 전용 문”입니다.
- B가 5000번으로 접속해 오면, 공유기는 “이 문은 STUN 전용인데?”라고 보고 차단합니다.
- B가 들어올 수 있는 문은 5001번인데, B는 그 번호를 알 수 없습니다.
즉, Port-Dependent Mapping 때문에 “STUN으로 알려준 포트”와 “Peer B와 통신할 때 쓰는 포트”가 달라지고, 그 결과 홀펀칭이 불가능해져 TURN 릴레이가 필요해집니다.
TURN이란? (클릭 시 시각화)
TURN(Traversal Using Relays around NAT)은 RFC 5766(현행 RFC 8656로 개정)에 정의된 릴레이 프로토콜입니다. STUN으로 P2P가 되지 않을 때(예: Symmetric NAT, 엄격한 방화벽), TURN 서버가 중간에서 미디어를 받아 상대 피어에게 전달합니다.
- Allocate: 클라이언트가 TURN 서버에 요청을 보내면, 서버가 릴레이 전용 주소(IP:포트) 를 발급합니다. 이 주소를 시그널링으로 상대에게 알려 주면, 상대는 그 주소로 패킷을 보냅니다.
- Permission: 아무나 릴레이 주소로 보낼 수 없도록, "이 Peer의 IP만 허용"하는 Permission을 등록합니다. TURN 서버는 허가된 IP에서 오는 패킷만 해당 클라이언트에게 전달합니다.
- 데이터 중계: 실제 오디오·영상 데이터는 내 PC ↔ TURN ↔ Peer 경로로 모두 서버를 경유합니다. 따라서 대역폭·비용이 들지만, "연결이 안 되는 경우"의 최후 수단으로 사용됩니다.
WebRTC(ICE)는 host → srflx(STUN) → relay(TURN) 순으로 후보를 시도하므로, 직접 연결이 불가능할 때만 TURN이 선택됩니다.
ICE는 가능한 모든 후보 쌍(local×remote)을 동시에 STUN 바인딩으로 점검(connectivity check)하고, 성공한 쌍 중 우선순위가 가장 높은 경로를 선택합니다. relay는 priority 값이 가장 낮게 설정되어, 다른 경로가 모두 실패할 때만 채택됩니다.
방화벽
NAT 외에도 방화벽이 들어오는 연결을 막는 경우가 있습니다. 회사·학교·공공 Wi‑Fi에서는 아웃바운드만 허용하고 인바운드를 차단하는 정책이 많아, STUN만으로는 P2P가 되지 않고 TURN으로 릴레이해야 합니다.
한 줄 요약: NAT·방화벽 때문에 P2P가 막힐 수 있고, Symmetric NAT에서는 목적지마다 포트가 달라져 STUN만으로는 부족해 TURN이 필요합니다.
관련 글
- #0 WebRTC란? ICE/STUN/NAT/TURN 기초 — ICE/STUN/NAT/TURN 전체 그림을 먼저 잡고 이 글로 들어오면 이해가 빠릅니다
- #9 Agora 기업 방화벽 우회 — Cloud Proxy — STUN/TURN으로도 안 되는 엄격한 기업 방화벽을 우회하는 실전 해법
- #32 시그널링과 미디어 분리 — RTSP/SIP vs RTP — STUN으로 교환한 후보 주소를 어떤 시그널링 채널로 주고받는지 연결됩니다
- #47 WebRTC 벤더 지형도 — TURN 인프라를 직접 운영할지 매니지드를 쓸지 판단할 때 참고
참고 자료
- RFC 8489 — Session Traversal Utilities for NAT (STUN) — 현행 STUN 표준. RFC 3489/5389를 대체
- RFC 8656 — Traversal Using Relays around NAT (TURN) — 현행 TURN 표준. RFC 5766을 개정
- RFC 8445 — Interactive Connectivity Establishment (ICE) — host/srflx/relay 후보 수집과 우선순위·연결성 점검 절차
- RFC 4787 — NAT Behavioral Requirements for Unicast UDP — 매핑/필터링 동작 분리(EIM·EDM) 정의, Symmetric NAT를 대체하는 현행 분류
- WebRTC for the Curious — Connecting (ICE/STUN/TURN) — NAT 트래버설과 홀펀칭을 그림으로 설명한 입문 자료
- MDN — WebRTC connectivity (ICE/STUN/TURN) — 브라우저 관점의 연결 수립 개요
실제 데모
/agora-demo/rtc