Mis à jour il y a 1 mois
대부분의 장치는 외부로 나가는 연결은 허용하지만 허가되지 않은 수신 트래픽은 차단하는 NAT 방화벽 뒤에 자리 잡고 있습니다. NAT로 보호된 두 장치는 불가능한 교착 상태에 놓입니다: 어느 쪽도 먼저 상대방에게 접근할 수 없습니다.
UDP 홀 펀칭은 이 문제를 깔끔한 방법으로 해결합니다: 두 장치가 동시에 손을 뻗고, 그 과정에서 각자 상대방에게 필요한 통로를 만들어냅니다.
교착 상태
장치가 NAT를 통해 데이터를 보내면 라우터는 임시 매핑을 생성합니다—내부 주소와 포트가 외부 주소와 포트에 연결됩니다. 반환 트래픽은 이 매핑을 통해 장치에 도달합니다. 하지만 허가되지 않은 수신 트래픽은 차단됩니다.
NAT 뒤에 있는 두 장치는 서로 연결할 수 없습니다. 장치 A는 B로 데이터를 보낼 수 없습니다. B의 라우터가 예상치 못한 패킷을 거부하기 때문입니다. 장치 B도 같은 이유로 A로 보낼 수 없습니다. A가 B에 도달하려면 B의 NAT가 먼저 매핑을 만들어야 하는데, B의 NAT는 B가 먼저 뭔가를 보내기 전까지는 매핑을 만들지 않습니다.
전통적인 해결책은 피어 간에 모든 트래픽을 중계하는 릴레이 서버입니다. 효과는 있지만 지연 시간이 생깁니다. 화상 통화나 멀티플레이어 게임에서 그 지연은 사용 경험을 망가뜨립니다.
동시에 문을 두드리다
UDP 홀 펀칭은 NAT의 예측 가능한 동작을 활용합니다: 아웃바운드 UDP 패킷이 매핑을 만들면, 라우터는 그 외부 포트로 들어오는 패킷을 수락합니다—장치가 직접 연락한 적 없는 곳에서 오는 패킷이라도 마찬가지입니다.
이 기술에는 세 참가자가 필요합니다: 두 피어, 그리고 외부에서 접근 가능한 랑데부 서버.
두 피어 모두 랑데부 서버에 연결합니다. A가 서버에 UDP 패킷을 보내면 A의 NAT는 매핑을 생성합니다—예를 들어 외부 IP 203.0.113.10, 포트 5000. 서버는 이를 기록합니다. B도 마찬가지로 연결하면, 198.51.100.20, 포트 6000으로 나타납니다.
이제 서버는 두 피어의 공개 엔드포인트를 모두 알고 있습니다. A에게는 B의 위치를, B에게는 A의 위치를 알려줍니다.
핵심은 여기에 있습니다: 두 피어가 동시에 서로의 공개 엔드포인트로 UDP 패킷을 보냅니다.
A가 B의 엔드포인트(198.51.100.20:6000)로 패킷을 보내면, 아마 차단될 겁니다—B의 NAT가 아직 A에 대한 매핑을 만들지 않았기 때문입니다. 하지만 이 아웃바운드 패킷 덕분에 A의 NAT에 구멍이 뚫립니다. 포트 5000이 이제 수신 대기 상태가 됩니다.
동시에 B가 A의 엔드포인트(203.0.113.10:5000)로 패킷을 보냅니다. 이 패킷은 B의 NAT에 구멍을 뚫으면서—마침 A의 NAT가 트래픽을 받아들이고 있는 바로 그 포트에 도달합니다.
두 피어 모두 거부당할 패킷을 보냅니다—하지만 거부당하는 그 순간, 서로를 받아들일 조건이 만들어집니다.
수 밀리초 안에 양쪽에 구멍이 뚫리고 패킷이 양방향으로 흐르기 시작합니다. 랑데부 서버의 역할은 끝납니다. 피어들은 직접 통신합니다.
STUN과 TURN
인터넷 엔지니어링 태스크 포스(IETF)가 이 과정을 표준화했습니다:
STUN(Session Traversal Utilities for NAT) 서버는 장치가 자신의 공개 엔드포인트를 알아내도록 도와줍니다. 요청을 보내면 서버가 자신이 본 주소와 포트를 알려줍니다. STUN 서버는 가볍습니다—정보를 돌려줄 뿐, 트래픽을 중계하지 않습니다.
TURN(Traversal Using Relays around NAT) 서버는 홀 펀칭이 실패했을 때의 대안입니다. TURN 서버는 피어 간 트래픽을 실제로 중계합니다. 직접 연결의 대역폭·지연 시간 이점은 포기해야 하지만, 다른 방법이 모두 실패했을 때 연결을 보장합니다.
현대 애플리케이션은 **ICE(Interactive Connectivity Establishment)**를 사용하여 여러 전략을 동시에 시도합니다: 직접 연결, STUN을 통한 홀 펀칭, TURN을 통한 중계. 가장 잘 작동하는 방법이 사용됩니다.
실패하는 경우
홀 펀칭은 대부분의 일반 라우터에서는 잘 작동하지만, 몇 가지 상황에서는 실패합니다:
대칭 NAT는 목적지에 따라 다른 외부 포트를 할당합니다. A가 STUN 서버에 연락할 때 받는 외부 포트와, A가 B에게 보낼 때 할당되는 포트가 완전히 달라집니다. STUN에서 얻은 엔드포인트 정보가 쓸모없어지는 겁니다. 인터넷 사용자의 약 11%가 이런 유형의 NAT 뒤에 있습니다1.
포트 제한형 NAT는 장치가 이미 통신한 주소에서 오는 수신 패킷만 허용합니다. B가 A에게 보낸 패킷은, A가 처음에 연락했던 정확한 주소에서 오지 않으면 차단됩니다—문제는 A가 B 자체가 아니라 B의 NAT 주소로 보냈다는 것입니다.
기업용 방화벽은 UDP를 완전히 차단하거나 애플리케이션 계층에서 트래픽을 검사하기도 합니다.
TCP는 같은 방식으로 작동하지 않습니다. TCP의 3방향 핸드셰이크는 대부분의 NAT 구현이 제대로 처리하지 못하는 "동시 개방" 시나리오를 만들어냅니다. 홀 펀칭은 본질적으로 UDP 기술이지만, 최근 연구에 따르면 정밀한 타이밍 동기화를 활용하면 TCP와 QUIC도 비슷한 성공률을 달성할 수 있습니다2.
홀 펀칭은 실제 환경에서 약 70-82% 성공률을 보입니다3. 나머지 경우에는 TURN 릴레이가 지연 시간을 감수하고 연결을 제공합니다.
이미 사용하고 있는 곳
VoIP 통화가 이 기술을 개척했습니다. Skype는 홀 펀칭으로 직접 오디오 스트림을 구성했습니다—실시간 음성은 릴레이 지연을 감당할 수 없기 때문입니다.
멀티플레이어 게임은 끊임없이 구멍을 뚫습니다. 총싸움의 승패가 10밀리초에 갈릴 때, 중앙 서버를 거칠 여유가 없습니다. 게임 클라이언트는 매치메이킹을 위해 랑데부 서버를 쓴 다음, 실제 게임플레이는 직접 UDP 연결로 진행합니다.
WebRTC는 홀 펀칭을 브라우저로 가져왔습니다. 화상 회의에 참여하면 ICE가 자동으로 네트워크 환경을 파악하고, 홀 펀칭을 시도하며, 필요하면 릴레이로 전환합니다. "참여" 버튼 하나로 P2P 화상 통화가 이루어집니다.
이 기술은 파일 공유, 원격 데스크톱 도구, IoT 장치 통신에도 쓰입니다. NAT 뒤에 있으면서 직접 연결이 필요한 곳이라면, 어떤 형태의 홀 펀칭이 그것을 가능하게 합니다.
UDP 홀 펀칭 자주 묻는 질문
왜 "홀 펀칭"이라고 부르나요?
이름은 실제로 일어나는 일에서 비롯됐습니다: 허가되지 않은 수신 트래픽을 차단하는 방화벽에 임시 구멍을 만드는 것입니다. 아웃바운드 패킷이 NAT 방어를 "뚫어서" 반환 트래픽이 들어올 통로를 남깁니다.
홀 펀칭은 보안에 문제가 생기지 않나요?
문제는 거의 없습니다. 구멍은 트래픽이 흐르는 동안만 존재합니다—NAT 매핑은 일정 시간 동안 통신이 없으면 만료되며, UDP의 경우 보통 약 5분입니다4. 구멍은 UDP 패킷만 받아들이며, 임의의 연결을 허용하지 않습니다. NAT는 여전히 다른 모든 포트로 향하는 비허가 트래픽을 차단합니다.
TCP 홀 펀칭은 왜 잘 안 되나요?
TCP는 연결을 맺으려면 3방향 핸드셰이크(SYN, SYN-ACK, ACK)가 필요합니다. 양쪽이 동시에 SYN 패킷을 보내면 "동시 개방" 시나리오가 만들어지는데, 대부분의 NAT 구현은 이를 제대로 처리하지 못합니다. UDP의 비연결 특성 덕분에 동시 전송 방식이 안정적으로 동작합니다.
랑데부 서버가 다운되면 어떻게 되나요?
이미 맺어진 P2P 연결은 계속 유지됩니다—초기 조율 이후에는 서버가 필요하지 않기 때문입니다. 다만 서버가 복구될 때까지 새 연결을 맺을 수 없습니다. 중요한 서비스는 이중화를 위해 여러 랑데부 서버를 운영합니다.
ISP가 홀 펀칭을 막을 수 있나요?
그렇습니다. 캐리어급 NAT(CGN)를 사용하거나 대규모로 대칭 NAT를 운용하는 ISP는 홀 펀칭을 차단할 수 있습니다. 일부 모바일 네트워크가 이런 문제를 안고 있습니다. 그 경우 애플리케이션은 TURN 릴레이로 전환하며, 지연 시간은 늘어나지만 연결 자체는 유지됩니다.
출처
Cette page vous a-t-elle été utile ?