STUN Server는 Session Traversal Utilities for NAT (STUN) 프로토콜의 서버로, 클라이언트가 자신의 외부 IP 주소와 포트를 확인하고 자신이 위치한 Network Address Translation (NAT)의 유형을 파악할 수 있게 합니다. IETF RFC 5389, 2008에 따르면 STUN은 WebRTC 인프라의 필수 구성 요소로, NAT 뒤에 있는 클라이언트 간의 직접 피어투피어 연결 설정을 가능하게 합니다.
핵심 요점
STUN Server(Session Traversal Utilities for NAT)는 RFC 5389에 정의되고 RFC 8489에서 업데이트된 프로토콜로 작동하는 네트워크 서비스입니다. STUN 서버의 주요 작업은 클라이언트에게 외부 네트워크에서 볼 수 있는 자신의 공용 IP 주소와 포트에 대한 정보를 제공하고 클라이언트와 인터넷 사이의 NAT 장치 유형을 결정하는 것입니다.
STUN 아키텍처는 두 가지 구성 요소로 이루어집니다. 애플리케이션(브라우저 또는 네이티브 WebRTC 앱 등)에 내장된 STUN 클라이언트와 공용 네트워크에 배포된 STUN 서버입니다. 클라이언트는 서버에 Binding Request를 보내고, 서버는 응답에서 요청의 소스 IP 주소와 포트, 즉 서버가 보는 클라이언트의 공용 주소를 알려줍니다. 이 데이터를 로컬 주소와 비교함으로써 클라이언트는 자신의 네트워크에서 사용 중인 NAT 유형을 확인할 수 있습니다.
STUN은 UDP(기본 포트 3478) 또는 TCP(포트 3478, TLS의 경우 5349)를 통해 작동합니다. STUN 메시지는 20바이트 헤더와 가변 개수의 속성으로 구성됩니다. 헤더에는 메시지 유형(Binding Request, Binding Response, Binding Error Response), 길이 및 요청과 응답을 매칭하는 고유 트랜잭션 ID(96비트)가 포함됩니다. 각 Binding Response에는 XOR-MAPPED-ADDRESS 속성(클라이언트의 외부 주소)이 포함되며, STUN 트래픽 가로채기에 기반한 공격으로부터 보호하기 위해 마스킹과 함께 인코딩됩니다.
STUN 서버는 간단한 요청-응답 프로토콜로 작동합니다. NAT 뒤에 있는 클라이언트는 Binding Request를 생성하여 STUN 서버에 보냅니다. 서버는 패킷을 수신하고 UDP 헤더에서 소스 IP 주소와 송신자 포트를 추출한 다음 Binding Response를 생성하여 이 주소를 XOR-MAPPED-ADDRESS 속성에 패키징합니다. 응답은 요청의 소스 주소로 다시 전송됩니다.
클라이언트는 응답을 수신하고 NAT 장치가 할당한 외부 IP 주소와 포트가 포함된 XOR-MAPPED-ADDRESS를 추출합니다. 그런 다음 클라이언트는 이 주소를 자신의 로컬(RFC 1919 — 개인) 주소와 비교합니다. 주소가 일치하면 클라이언트는 NAT 뒤에 있지 않습니다. 다르면 클라이언트는 NAT 뒤에 있으며 외부 주소는 WebRTC의 ICE(Interactive Connectivity Establishment)를 위한 후보로 사용됩니다.
STUN 서버는 일련의 테스트 요청을 통해 NAT 유형을 확인할 수 있습니다. 클라이언트는 다른 플래그(CHANGE-REQUEST)로 요청을 보내고 응답을 분석합니다. 전체 검색 주기에는 STUN 서버의 다른 IP 주소와 포트로 요청을 보내는 것이 포함됩니다. 서버가 변경된 포트로 요청에 응답하면 NAT는 Restricted Cone 유형입니다. 변경된 포트와 IP로 요청에 응답하지 않으면 NAT는 Symmetric 유형입니다. 이 정보는 WebRTC에서 ICE 전략을 선택하는 데 중요합니다.
STUN 서버는 네 가지 주요 NAT 유형을 감지할 수 있으며, 각 유형은 P2P 연결 설정 가능성에 다르게 영향을 미칩니다. NAT 유형은 STUN이 두 클라이언트 간의 직접 연결을 가능하게 하는지 여부를 결정합니다. 또한 연결에 사용될 ICE 후보(host, server reflexive 또는 relay)도 결정합니다.
| NAT 유형 | 동작 | STUN 작동 | ICE 폴백 |
|---|---|---|---|
| Full Cone | 모든 외부 호스트가 클라이언트에 패킷을 보낼 수 있음 | 예 | Server Reflexive |
| Restricted Cone | 클라이언트가 패킷을 보낸 호스트만 가능 | 예 | Server Reflexive |
| Port Restricted | Restricted와 유사하지만 소스 포트로도 필터링 | 예 | Server Reflexive |
| Symmetric NAT | 외부 주소가 호스트:포트 쌍마다 고유함 | 아니오 | Relay (TURN) |
Symmetric NAT은 STUN이 처리할 수 없는 유일한 유형입니다. Symmetric NAT에서는 새 대상 호스트에 대한 각 새 요청이 다른 외부 주소(IP 및/또는 포트)를 받습니다. STUN 서버는 STUN 서버 자체에 대한 연결 주소를 보고하므로 이 주소는 다른 클라이언트에 연결하는 데 부적합합니다. 이러한 경우 WebRTC는 트래픽을 중계하기 위해 TURN 서버를 사용합니다. 연구에 따르면(Ford et al., RFC 3489, 2003) 인터넷상의 모든 NAT 장치 중 약 8~10%가 대칭형입니다.
STUN 서버는 RTCPeerConnection 구성을 통해 WebRTC에 통합됩니다. 브라우저 또는 네이티브 애플리케이션은 STUN을 사용하여 ICE 후보를 수집하고, 이후 Signaling Server를 통해 교환됩니다. WebRTC 구성에서 STUN 서버는 iceServers 배열에 UDP의 경우 stun: 접두사, TLS 연결의 경우 stuns: 접두사로 지정됩니다.
WebRTC 애플리케이션용 RTCPeerConnection을 생성할 때 JavaScript에서 STUN 서버 설정의 예를 살펴보겠습니다.
const config = {
iceServers: [
{
urls: "stun:stun.l.google.com:19302"
},
{
urls: "stun:stun1.l.google.com:19302"
}
]
};
const pc = new RTCPeerConnection(config);
pc.onicecandidate = (event) => {
if (event.candidate) {
console.log("ICE 후보:", event.candidate.candidate);
}
};
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
이 예에서는 Google의 공용 STUN 서버(stun.l.google.com:19302)를 사용합니다. offer 또는 answer를 생성할 때 브라우저는 자동으로 지정된 서버에 STUN Binding Request를 보내고 외부 주소(server reflexive 후보)를 받아 ICE 후보 목록에 추가합니다. 모든 후보가 수집되면 Signaling Server를 통해 원격 피어로 전송되어 직접 P2P 연결 설정을 시도합니다.
ICE 프로세스에는 세 가지 후보 유형이 있습니다. host(로컬 주소), srflx(server reflexive — STUN에서 획득), relay(TURN을 통해 중계)입니다. STUN 서버는 srflx 후보 생성을 가능하게 합니다. srflx 후보는 relay 후보보다 우선순위가 높습니다. STUN 기반 연결은 직접 연결이며 중계가 필요하지 않기 때문입니다. ICE 프로세스는 두 피어의 모든 후보 조합(로컬 및 STUN에서 획득)을 가장 높은 우선순위부터 확인합니다.
STUN 서버는 프로토콜 아키텍처와 관련된 근본적인 제한 사항이 있습니다. 주요 제한 사항은 외부 호스트에 대한 각 새 요청이 고유한 외부 포트를 받는 Symmetric NAT에서 작동할 수 없다는 것입니다. 이 경우 STUN 서버에서 얻은 주소는 NAT가 STUN 서버 자체와의 통신을 위해서만 바인딩을 생성했기 때문에 다른 피어에 연결하는 데 사용할 수 없습니다.
두 번째 제한 사항은 STUN이 데이터 중계를 제공하지 않는다는 것입니다. 직접 P2P 연결이 불가능한 경우(두 피어 모두 Symmetric NAT 뒤에 있음) STUN은 데이터 전송을 위한 대체 경로를 제공하지 않습니다. 이 경우 TURN 서버가 필요하며, TURN 서버는 피어 간 미디어 트래픽 중계자 역할을 하여 한 참가자로부터 데이터를 받아 자체 공용 IP 주소를 통해 다른 참가자에게 보냅니다.
제한 사항에도 불구하고 STUN 서버는 WebRTC 인프라의 중요한 구성 요소로 남아 있습니다. 대부분의 경우(80~90%) STUN을 사용하여 직접 P2P 연결을 설정할 수 있어 TURN 중계 비용을 피하고 미디어 데이터 전송 지연 시간을 줄일 수 있습니다. 공용 WebRTC 애플리케이션의 경우 자동 폴백과 함께 STUN 및 TURN 서버를 조합하여 사용하는 것이 좋습니다.
자주 묻는 질문
STUN 서버는 인터넷상의 "거울"로 클라이언트에게 외부 IP 주소를 알려줍니다. 컴퓨터가 라우터(NAT) 뒤에 있을 때 자신의 공용 주소를 알지 못합니다. STUN 서버는 이를 찾아 다른 컴퓨터가 직접 연결할 수 있도록 도와줍니다.
WebRTC에서 STUN 서버는 RTCPeerConnection 구성에 지정됩니다. 브라우저는 외부 후보 주소(srflx)를 얻기 위해 STUN 요청을 보냅니다. 이 후보는 Signaling Server를 통해 원격 피어에 전달되며 ICE가 둘 사이의 직접 연결을 설정하려고 시도합니다.
STUN은 직접 P2P 연결을 위한 외부 주소를 찾는 데 도움을 줍니다. TURN은 P2P가 불가능할 때 자체 서버를 통해 트래픽을 중계합니다. STUN은 "거울", TURN은 "중개자"입니다. TURN은 서버에 부하를 주고 지연 시간을 추가하므로 STUN이 선호됩니다.
Google은 무료 STUN 서버를 제공합니다: stun.l.google.com:19302, stun1.l.google.com:19302. Twilio도 Network Traversal Service를 통해 STUN + TURN 인프라를 제공합니다. 프로덕션 애플리케이션의 경우 가용성이 보장된 자체 또는 상용 STUN/TURN 서버를 사용하는 것이 좋습니다.
Symmetric NAT은 "로컬 주소:대상 외부 주소" 쌍마다 고유한 외부 포트 매핑을 생성합니다. 클라이언트가 STUN 서버로부터 받는 주소는 해당 STUN 서버와의 연결에 고정됩니다. 다른 피어가 이 주소를 사용하려고 하면 Symmetric NAT는 새 대상 주소에 대한 포트 매핑이 다르기 때문에 패킷을 차단합니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.