Tailscale은 어떻게 연결될까? STUN, Hole Punching, DERP 정리
Tailscale은 NAT(공유기)나 방화벽 뒤에 있는 기기들끼리도 복잡한 포트포워딩 설정 없이 안전하게 연결해 줍니다. Tailscale이 최적의 P2P 경로를 찾고, 실패 시 우회하는 전체 통신 매커니즘을 3단계로 나누어 알아보겠습니다.

* STUN: Session Traversal Utilities for NAT
* DERP: Designated Encrypted Relay for Packets
Step 1. The Setup (TCP 및 STUN을 통한 초기 준비)
통신을 시작하기 전, 각 노드(Node A, Node B)는 네트워크 상태와 자신의 공인 주소를 파악해야 합니다.
- TCP 443 세션 개방 (Relay 대비): 노드 A와 B는 부팅 즉시 가장 가까운 DERP 서버로 TCP 443(TLS) 세션을 상시 연결해 둡니다. 이는 추후 P2P 연결에 실패할 때 사용할 비상 통로입니다.
- STUN 질의 (UDP 3478): 동시에 DERP 서버가 겸임하는 STUN 서비스(UDP 3478)로 바인딩 요청을 보냅니다. 이를 통해 공유기 너머 외부에서 보이는 자신의 공인 IP 및 외부 포트를 확인합니다.
- 좌표 교환: 각 노드는 STUN으로 알아낸 자신의 공인 주소 정보를 Tailscale 제어 서버(Coordination Server)를 통해 서로 안전하게 교환합니다.
Step 2. P2P Success (Hole Punching 성공 시)
서로의 공인 좌표를 확보한 노드 A와 B는 중계 서버 없이 직접 통신하기 위해 Hole Punching(홀 펀칭)을 시도합니다.
- 동시 UDP 패킷 발송: 노드 A와 B가 서로의 공인 IP:포트를 향해 동시에 WireGuard UDP 패킷을 발송합니다.
- 방화벽 구멍 개통: 양쪽 방화벽에 서로를 향한 Outbound 상태(세션 Table)가 형성되면서 방화벽을 통과할 수 있는 구멍이 뚫립니다.
- P2P 직통 터널 개통: 양쪽 모두 Hole Punching에 성공하면, DERP 서버를 거치지 않고 WireGuard UDP 기반의 P2P 직접 연결이 성립됩니다. 최저 지연시간(Latency)과 최고 속도를 제공하는 가장 이상적인 상태입니다.
Step 3. DERP Replay Routing (Hole Punching 실패 시)
하지만 대칭형 NAT(Symmetric NAT)이나 엄격한 기업 방화벽 환경에서는 Hole Punching이 실패할 수 있습니다.
- UDP 차단 감지: 한쪽 방화벽에서 외부 UDP를 모두 Drop하거나 포트 번호가 무작위로 계속 변경(Symmetric NAT)되면 P2P 패킷 전송이 실패합니다.
- DERP 전환 준비: P2P 연결이 불가능하다고 판단되면, 노드 A는 즉시 Step 1에서 미리 열어두었던 DERP 릴레이 통로로 트래픽을 회피시킵니다.
- Public Key 지정: 보내려는 패킷의 겉표지(Relay Header)에 목적지인 노드 B의 Public Key를 주소로 지정하여 DERP 서버로 전송합니다.
- End-to-End 암호화 유지: DERP 서버는 전달받은 패킷 내부의 실제 데이터(WireGuard 페이로드)를 복호화할 수 없습니다. 오직 패킷 겉면에 적힌 Public Key 헤더만 확인합니다.
- 소켓 매핑 및 포워딩: DERP 서버는 자신의 메모리 매핑 테이블에서 노드 B의 Public Key에 연결되어 있는 TCP 443 소켓을 찾아 패킷을 노드 B로 즉시 전달(Relay Routing)합니다.
- 양방향 릴레이: 노드 B 역시 노드 A의 Public Key를 목적지로 지정하여 응답 패킷을 보내며, 두 노드는 P2P 실패와 상관없이 100% 안정적인 암호화 통신을 유지합니다.
