블로그 목록
Media15분 읽기

P2P 연결이 막히는 이유 — NAT, ICE, STUN, TURN

NAT mapping과 filtering 동작 때문에 endpoint끼리 직접 연결되지 않는 경우를 설명합니다. ICE agent가 host·server-reflexive·relay candidate pair를 검사하고 STUN binding과 TURN relay를 사용하는 흐름을 현재 RFC 기준으로 정리합니다. 오래된 NAT 네 가지 분류는 진단의 참고 모델로만 다룹니다.

NATP2PTURNWebRTC방화벽

P2P(피어 간 직접 연결)는 공유기(NAT) 의 매핑·필터링 동작이나 방화벽 정책 때문에 실패할 수 있습니다. 이 글에서는 레거시 NAT 4분류와 현행 RFC의 동작 기반 분류, STUN·TURN·ICE의 관계를 정리합니다.

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의 레거시 모델입니다. 현행 문서에서는 매핑(Mapping) 과 필터링(Filtering) 을 분리해 설명합니다. RFC 4787의 UDP 매핑 동작은 Endpoint-Independent, Address-Dependent, Address-and-Port-Dependent로 구분합니다. "Symmetric NAT"를 하나의 현행 분류와 일대일로 대응시키기보다 매핑·필터링 조합을 확인하는 편이 정확합니다.

레거시 용어의 Symmetric NAT에서 흔히 설명하는 시나리오는 목적지에 따라 외부 매핑이 달라지는 경우입니다. 이때 STUN 서버를 대상으로 얻은 주소가 다른 피어와 통신할 때 그대로 유효하지 않을 수 있습니다. 다만 실제 연결 가능성은 양쪽 NAT의 매핑·필터링과 ICE 후보 조합에 따라 달라지며, 직접 후보 쌍이 모두 실패할 때 TURN relay를 사용합니다.

Symmetric NAT 예시: 목적지별 포트 매핑 (클릭 시 시각화)

1. STUN 서버에 패킷을 보낼 때

내 PC → 공유기 → STUN 서버
              ↑
       NAT가 포트 5000 할당
       (1.2.3.4:5000 → STUN)

STUN 서버가 "당신의 공인 주소는 1.2.3.4:5000 입니다"라고 알려 줍니다.

2. Peer B에게 패킷을 보낼 때

내 PC → 공유기 → Peer B
              ↑
       NAT가 포트 5001 할당  ← 목적지에 따라 다른 포트
       (1.2.3.4:5001 → Peer B)

목적지가 다르면 NAT가 다른 포트를 새로 만들어 버립니다.

3. 왜 B가 5000으로 접속하면 차단되나요?

  • B는 STUN을 통해 “상대 주소는 1.2.3.4:5000”이라고만 알고 있습니다.
  • 하지만 공유기 입장에서 5000번은 “STUN 서버와 통신할 때 쓴 전용 문”입니다.
  • B가 5000번으로 접속해 오면, 공유기는 “이 문은 STUN 전용인데?”라고 보고 차단합니다.
  • B가 들어올 수 있는 문은 5001번인데, B는 그 번호를 알 수 없습니다.

이 예시는 Address-and-Port-Dependent Mapping 때문에 STUN 서버에 대한 매핑과 Peer B에 대한 매핑이 달라지는 상황입니다. 이것만으로 모든 피어 조합의 홀펀칭이 불가능하다고 단정할 수는 없지만, ICE의 직접 후보 쌍 검사가 실패하면 TURN relay가 필요합니다.

TURN이란? (클릭 시 시각화)

TURN(Traversal Using Relays around NAT)은 현행 RFC 8656에 정의된 릴레이 프로토콜입니다. 직접 후보 쌍의 연결 검사가 실패하면 TURN 서버가 중간에서 미디어를 받아 상대 피어에게 전달합니다.

  • Allocate: 클라이언트가 TURN 서버에 요청을 보내면, 서버가 릴레이 전용 주소(IP:포트) 를 발급합니다. 이 주소를 시그널링으로 상대에게 알려 주면, 상대는 그 주소로 패킷을 보냅니다.
  • Permission: 아무나 릴레이 주소로 보낼 수 없도록, "이 Peer의 IP만 허용"하는 Permission을 등록합니다. TURN 서버는 허가된 IP에서 오는 패킷만 해당 클라이언트에게 전달합니다.
  • 데이터 중계: 실제 오디오·영상 데이터는 내 PC ↔ TURN ↔ Peer 경로로 모두 서버를 경유합니다. 따라서 대역폭·비용이 들지만, "연결이 안 되는 경우"의 최후 수단으로 사용됩니다.

ICE는 host·srflx·relay 후보로 후보 쌍 체크리스트를 만들고 우선순위 순서로 연결 검사를 수행합니다. 세 후보 유형을 고정된 세 단계로 하나씩 시도하는 구조는 아닙니다.

Local candidates                  Remote candidates
host / srflx / relay              host / srflx / relay
          └──────────┬──────────┘
                     ▼
           후보 쌍과 우선순위 계산
                     ▼
        paced connectivity checks (STUN)
                     ▼
            유효한 후보 쌍 nominate
          ┌──────────┴──────────┐
          ▼                     ▼
      direct pair           relayed pair

ICE는 local×remote 후보 쌍으로 체크리스트를 만들고, RFC 8445의 우선순위와 pacing 규칙에 따라 STUN 연결 검사를 진행한 뒤 유효한 쌍을 nominate합니다. 기본 type preference는 일반적으로 직접 후보를 relay보다 선호하지만, iceTransportPolicy: "relay"처럼 정책이 relay만 허용할 수도 있습니다.

방화벽

NAT 외에도 방화벽 정책이 후보 쌍의 연결 검사를 막을 수 있습니다. 회사·학교·공공 Wi‑Fi처럼 허용 포트·전송 프로토콜이 제한된 환경에서는 직접 후보가 실패할 수 있으며, 그 경우 허용된 전송을 사용하는 TURN relay가 대안이 됩니다.


한 줄 요약: NAT의 매핑·필터링과 방화벽 정책에 따라 직접 P2P 후보가 실패할 수 있으며, ICE가 유효한 직접 후보 쌍을 찾지 못하면 TURN relay를 사용합니다.

관련 글

참고 자료

실제 데모

/agora-demo/rtc

© 2026 Frank Kim. All rights reserved.