1. 안녕하세요! COTURN입니다. (그런데 누구신지?) WebRTC에서 “연결이 왜 안 되지?”라는 문제를 파고들면 결국 ICE(Interactive Connectivity Establishment) 과정과 마주하게 된다. ICE는 두 단말이 서로 통신 가능한 경로 후보(candidate)를 수집하고, 그중 최적의 경로를 선택하여 연결하는 절차다. COTURN은 ICE 과정에서 필요한 STUN/TURN 서버 역할을 수행하는 대표적인 오픈소스 구현체다. P2P가 가능한 환경에서는 연결을 빠르고 간편하게 만들고, P2P가 불가능한 환경에서는 […] ||
1. 안녕하세요! COTURN입니다. (그런데 누구신지?)
WebRTC에서 “연결이 왜 안 되지?”라는 문제를 파고들면 결국 ICE(Interactive Connectivity Establishment) 과정과 마주하게 된다. ICE는 두 단말이 서로 통신 가능한 경로 후보(candidate)를 수집하고, 그중 최적의 경로를 선택하여 연결하는 절차다.
COTURN은 ICE 과정에서 필요한 STUN/TURN 서버 역할을 수행하는 대표적인 오픈소스 구현체다. P2P가 가능한 환경에서는 연결을 빠르고 간편하게 만들고, P2P가 불가능한 환경에서는 Relay(중계) 경로를 제공해 연결 실패를 막아주는 안전장치 역할을 한다.
이 문서는 Coturn을 Docker 기반으로 배포하고, 방화벽·포트 제한 환경에서도 안정적으로 운영할 수 있도록 설정한 뒤, Trickle ICE를 통해 relay 후보(typ relay)까지 검증하는 과정을 정리한다.
1.1 COTURN이 하는 일 (ICE 관점)
ICE는 크게 세 가지 후보를 수집한다.
Host candidate: 단말의 로컬 IP (동일 네트워크 내 통신 시 사용)
Srflx(Server Reflexive) candidate: STUN을 통해 확인한 “외부에서 보이는 IP/Port” 후보
Relay candidate: TURN 서버를 통해 미디어를 중계하는 후보
COTURN은 이 중 STUN 기능으로 srflx 후보를 생성하고, TURN 기능으로 relay 후보를 생성한다. 실제 운영 시 P2P(srflx)에만 의존하면 연결 성공률이 불안정해질 수 있으므로, TURN을 통해 성공률을 보장하는 인프라를 구축하는 것이 핵심이다.
1.2 STUN으로 NAT 넘어보기 (P2P)
대부분의 클라이언트는 사설 IP를 사용하는 NAT 환경 뒤에 있다. 이 상태에서는 상대 피어가 로컬 주소로 직접 접속할 수 없다. 그래서 ICE는 STUN을 통해 “외부에서 보이는 나의 주소”를 먼저 확인한다.
과정은 다음과 같다.
클라이언트 → STUN 서버로 요청
STUN 서버 → “외부에서는 <공인 IP:포트>로 보인다”라고 응답
클라이언트는 이를 srflx candidate로 등록
이 방식이 정상 동작하면 미디어는 TURN을 거치지 않고 P2P로 직접 전달된다. 레이턴시와 서버 비용 측면에서도 가장 유리하다.
하지만 STUN은 어디까지나 “주소를 알아내는 단계”일 뿐이다. NAT 유형이나 방화벽 정책에 따라 후보는 수집되지만 실제 미디어 경로는 성립하지 않는 경우가 자주 발생한다.
1.3 연결 정책이 복잡하다면? “TURN” (RELAY)
현실 환경에서는 다음과 같은 상황이 빈번하게 발생한다.
기업·학교 망에서 UDP가 제한되거나 차단됨
Symmetric NAT 구조로 외부 매핑이 까다로운 환경
공용 Wi-Fi처럼 임의 포트가 쉽게 차단되는 네트워크
이때 TURN은 사실상 우회 경로 역할을 한다.
클라이언트가 TURN 서버에 인증 후 relay allocation을 요청한다.
두 단말은 서로 직접 통신하지 않는다.
TURN 서버가 중간에서 미디어를 중계한다.
“STUN은 가능성을 높이고, TURN은 실패를 막는다.”
이 문서의 최종 목표도 여기에 있다.
어떤 네트워크 환경에서도 relay 후보가 안정적으로 생성되고, 실제 연결까지 이어지는지를