WebRTC란? ICE? STUN? NAT? TURN?
브라우저 간 실시간 통신의 기반이 되는 WebRTC와, P2P 연결을 가능하게 하는 NAT·STUN·TURN·ICE 개념을 정리합니다.
목차(15개 항목)
- WebRTC란?
- NAT와 P2P 연결의 한계
- STUN (Session Traversal Utilities for NAT)
- TURN (Traversal Using Relays around NAT)
ICE (Interactive Connectivity Establishment)
- WebRTC API 관점에서 정리
Agora Web SDK를 쓰면? 인프라는 SDK가 처리해 줍니다
- 참고 자료
WebRTC(Web Real-Time Communication)는 플러그인이나 별도 소프트웨어 없이 브라우저 간에 오디오·영상·데이터를 실시간으로 주고받을 수 있게 하는 기술입니다. 화상 통화, 화면 공유, P2P 파일 전송 등에 쓰이며, Agora RTC 같은 상용 SDK도 내부적으로 WebRTC 계열 표준을 활용합니다. 이 글에서는 WebRTC가 무엇인지, 그리고 P2P 연결을 위해 함께 등장하는 NAT, STUN, TURN, ICE가 어떤 역할을 하는지 정리합니다.
WebRTC란?
MDN WebRTC API 문서에 따르면, WebRTC는 다음을 가능하게 합니다.
- 미디어 캡처·스트리밍: 카메라, 마이크 등에서 오디오·영상을 가져와 브라우저 간에 전송
- 임의 데이터 교환: 플러그인 없이 피어 간 직접 데이터 채널로 바이너리·텍스트 전송
- 종단 간 통신: 중간 서버 없이 두 피어가 직접 연결되는 P2P 구조를 목표로 함
두 피어 간 연결은 RTCPeerConnection 인터페이스로 다루며, 연결이 수립되면 미디어 스트림(MediaStream)이나 데이터 채널(RTCDataChannel)을 붙여서 음성·영상·파일 등을 주고받습니다. 다만 실제 네트워크에는 NAT·방화벽이 있어서, “서로의 주소만 알면 바로 연결”이 되지 않는 경우가 많습니다. 이때 STUN, TURN, ICE가 필요합니다.
NAT와 P2P 연결의 한계
NAT는 내부망과 외부망 사이에서 사설 IP:포트와 공인 IP:포트를 매핑해 주는 장치입니다. 외부에서는 “공인 IP:포트”로만 보이기 때문에, 상대방이 “내가 보이는 주소”를 모르면 P2P 연결을 시도하기 어렵습니다. 또한 NAT 종류에 따라 “한 번 매핑된 포트로 누가 접속해도 되는지”, “내가 접속했던 상대만 나에게 접속할 수 있는지” 등이 달라져서, P2P 연결에 제약이 생깁니다.
- Full Cone NAT: 한 번 매핑되면 다른 쪽에서도 해당 포트로 접속 가능
- Restricted Cone NAT: 클라이언트가 접속했던 서버(IP 기준)만 해당 포트로 접속 가능
- Port Restricted Cone NAT: 접속했던 서버의 IP·포트만 접속 가능
- Symmetric NAT: 목적지에 따라 매핑된 포트가 달라질 수 있어 P2P가 가장 까다로움
그래서 “내가 외부에 어떻게 보이는지 알아내는 것”과 “그 정보를 상대에게 전달해 서로 연결을 시도하는 것”을 표준화한 프로토콜이 STUN, TURN, ICE입니다.
STUN (Session Traversal Utilities for NAT)
STUN은 IETF RFC 5389에 정의된 프로토콜로, 다음 역할을 합니다.
- NAT/방화벽 뒤에 있는지 판단
- 공인 IP·포트(Server Reflexive Address) 를 알려 줌 → “외부에서 나에게 접속할 때 쓰는 주소”를 발견
클라이언트가 STUN 서버에 요청을 보내면, STUN 서버는 “요청이 도달한 출발지 주소(공인 IP:포트)”를 응답으로 돌려줍니다. 이 주소를 상대 피어에게 전달하면, 상대는 이 주소로 직접 연결을 시도할 수 있습니다. STUN은 “주소만 알려 주는” 역할이며, 실제 미디어는 피어 간에 직접 흐릅니다. 대부분의 WebRTC 호출은 STUN만으로 P2P 연결이 성공한다고 알려져 있습니다.
TURN (Traversal Using Relays around NAT)
TURN은 RFC 5766에 정의된 릴레이 프로토콜입니다. STUN으로도 P2P가 되지 않는 환경(예: 엄격한 Symmetric NAT, 방화벽 정책)에서는, TURN 서버가 중간에서 미디어를 받아 다른 피어에게 전달합니다.
- 클라이언트는 TURN 서버에 Allocate Request를 보내고, 서버가 할당한 Relayed Transport Address를 받습니다.
- 이 주소를 시그널링을 통해 상대에게 전달하면, 상대는 그 주소(TURN 서버)로 접속하고, TURN 서버가 해당 클라이언트와의 세션으로 패킷을 릴레이합니다.
TURN은 실제 미디어가 서버를 경유하므로 대역폭·비용이 들지만, “연결이 안 되는 경우”의 fallback으로 필수에 가깝게 사용됩니다.
ICE (Interactive Connectivity Establishment)
ICE는 사용 가능한 모든 연결 후보(Candidate) 를 모아서, 그중에서 실제로 연결 가능한 경로를 선택하는 방식입니다. 후보는 대략 세 가지입니다.
- Host Candidate: 로컬 네트워크 인터페이스의 주소(같은 LAN 내 연결용)
- Server Reflexive Candidate: STUN을 통해 얻은 공인 IP:포트
- Relayed Candidate: TURN 서버가 할당한 릴레이 주소
ICE는 이 후보들을 상대에게 전달하고(SDP/시그널링), 각 경로에 대해 연결 체크를 수행한 뒤, 지연·대역폭·안정성 등을 고려해 최적의 한 쌍을 선택합니다. WebRTC에서는 이 과정이 RTCPeerConnection 설정 시 자동으로 이루어지며, 개발자는 STUN/TURN 서버 주소만 RTCConfiguration.iceServers에 넣어 주면 됩니다.
💡 핵심 흐름 순서
- ① STUN 요청 → 공인 IP:포트 획득
- ② SDP/ICE 후보 → Signaling Server 통해 교환
- ③ ICE 체크 → 최적 경로 선택
- ✅ P2P 직접 연결 또는 ④ TURN 릴레이 (Fallback) (클릭 시 연결 흐름 이미지)
WebRTC API 관점에서 정리
MDN WebRTC API 문서에서 강조하는 것처럼, WebRTC는 다음처럼 구성됩니다.
- RTCPeerConnection: 피어 간 연결의 생성·관리
- MediaStream / MediaStreamTrack: 오디오·영상 캡처 및 스트리밍
- RTCDataChannel: 임의 데이터(파일, 채팅 등) 교환
- RTCIceCandidate, RTCSessionDescription: ICE 후보와 SDP를 이용한 시그널링
시그널링(누가 누구에게 어떤 주소·코덱을 쓸지 협상)은 WebRTC 표준 밖에 있으므로, 웹소켓·HTTP 등으로 자유롭게 구현합니다. Agora 같은 서비스는 이 시그널링과 채널 관리·인증을 대신 해 주고, 내부적으로는 STUN/TURN/ICE와 유사한 원리로 최적 경로를 선택합니다.
WebRTC API 요약 코드
아래는 위 네 가지를 브라우저 JavaScript로 다룰 때의 요약 예시입니다. 시그널링(offer/answer·ICE 교환)은 웹소켓 등 별도 채널로 전달한다고 가정합니다.
RTCPeerConnection: 피어 간 연결의 생성·관리
MediaStream / MediaStreamTrack: 오디오·영상 캡처 및 스트리밍
RTCDataChannel: 임의 데이터(파일, 채팅 등) 교환
RTCIceCandidate, RTCSessionDescription: ICE 후보와 SDP를 이용한 시그널링
위 순서(offer → answer → ICE 후보 교환)와 SDP·ICE 후보를 웹소켓 등으로 주고받는 부분이 시그널링이며, WebRTC 표준에는 포함되지 않습니다.
Agora Web SDK를 쓰면? 인프라는 SDK가 처리해 줍니다
위의 WebRTC API 요약 코드에서 다룬 것처럼, 네이티브 WebRTC로 화상 통화를 만들려면 RTCPeerConnection 생성·offer/answer·ICE 후보 교환·미디어 트랙 추가·데이터 채널 등 직접 손댈 게 많습니다. Agora Web SDK(JavaScript) 를 쓰면 이 부분은 전부 필요 없습니다. STUN/TURN/ICE, 시그널링, 채널 입퇴장, 인증(토큰)까지 Agora 인프라가 처리해 주기 때문에, 개발자는 채널 이름과 토큰만 넘기고 입장·퍼블리시·구독만 하면 됩니다. 걱정하지 않아도 됩니다.
Agora Web SDK로 화상 통화 시작하기 (간단 예시)
- RTCPeerConnection, offer/answer, ICE 후보 교환, addTrack/ontrack 같은 코드를 직접 쓸 필요가 없습니다.
- 채널 토큰만 백엔드에서 받아서
join에 넘기면, 나머지 연결·경로 선택은 Agora Web SDK와 서버가 알아서 처리합니다.
실제 동작하는 데모는 RTC 데모에서, 구현 단계는 Agora RTC를 활용한 실시간 화상 통화 구현하기에서 자세히 다룹니다.
참고 자료
- WebRTC API - MDN: WebRTC 개념, 인터페이스, 가이드
- IETF RFC 5389 (STUN), RFC 5766 (TURN)
실제 Agora RTC를 이용한 화상 통화 구현은 Agora RTC를 활용한 실시간 화상 통화 구현하기 글을 참고하면 됩니다.
실제 데모
/agora-demo/rtc