{"id":1047,"date":"2026-05-18T15:55:50","date_gmt":"2026-05-18T08:55:50","guid":{"rendered":"https:\/\/liveapi.com\/blog\/nat-traversal\/"},"modified":"2026-05-18T15:56:32","modified_gmt":"2026-05-18T08:56:32","slug":"nat-traversal","status":"publish","type":"post","link":"https:\/\/liveapi.com\/blog\/nat-traversal\/","title":{"rendered":"What Is NAT Traversal? How It Works, Techniques, and Use Cases"},"content":{"rendered":"<span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Reading Time: <\/span> <span class=\"rt-time\">14<\/span> <span class=\"rt-label rt-postfix\">minutes<\/span><\/span><p>More than 90% of consumer devices sit behind a router that performs Network Address Translation (NAT). That single fact is the reason peer-to-peer video calls, multiplayer games, and remote desktop tools can&#8217;t just send packets to each other the way two servers in a data center can. NAT traversal is the set of techniques that gets around this restriction so two devices on different private networks can still establish a direct connection \u2014 or at least a working one.<\/p>\n<p>This guide walks through what NAT traversal is, why it matters, the core techniques (STUN, TURN, ICE, UDP hole punching, port mapping), how it shows up in IPsec and WebRTC, and how to think about it when you&#8217;re building real-time video and streaming applications.<\/p>\n<h2>What Is NAT Traversal?<\/h2>\n<p>NAT traversal is a networking technique for establishing and maintaining IP connections across gateways that perform network address translation. In plain terms: it&#8217;s the collection of tricks that lets a device behind a NAT receive incoming connections, even though the NAT is designed to block them.<\/p>\n<p>A NAT device translates many private IP addresses inside a local network (like <code>192.168.1.x<\/code>) into a single public IP address on the open internet. It does this by rewriting source addresses and ports as packets leave the network, and reversing the mapping when responses come back. The side effect is that the outside world doesn&#8217;t know how to reach a specific device inside \u2014 it only sees the NAT&#8217;s public address.<\/p>\n<p>NAT traversal solves three core problems:<\/p>\n<ol>\n<li><strong>Discovery<\/strong> \u2014 Figuring out the public IP and port that a NAT has assigned to your local socket.<\/li>\n<li><strong>Hole punching<\/strong> \u2014 Getting the NAT to permit incoming packets from a specific remote peer.<\/li>\n<li><strong>Fallback<\/strong> \u2014 Relaying traffic through a public server when a direct path isn&#8217;t possible.<\/li>\n<\/ol>\n<table>\n<thead>\n<tr>\n<th>NAT vs. NAT Traversal<\/th>\n<th>NAT<\/th>\n<th>NAT Traversal<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Goal<\/td>\n<td>Share one public IP across many devices<\/td>\n<td>Allow connections through NAT to reach internal hosts<\/td>\n<\/tr>\n<tr>\n<td>Direction<\/td>\n<td>Outbound by default<\/td>\n<td>Inbound or peer-to-peer<\/td>\n<\/tr>\n<tr>\n<td>Operates on<\/td>\n<td>Router\/firewall<\/td>\n<td>Endpoints + helper servers<\/td>\n<\/tr>\n<tr>\n<td>Common protocols<\/td>\n<td>NAT44, NAT64, CGNAT<\/td>\n<td>STUN, TURN, ICE, UPnP, NAT-PMP, PCP<\/td>\n<\/tr>\n<tr>\n<td>Visible to apps<\/td>\n<td>No (transparent)<\/td>\n<td>Yes (signaling is required)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>According to the <a href=\"https:\/\/en.wikipedia.org\/wiki\/NAT_traversal\" target=\"_blank\" rel=\"nofollow\">NAT traversal article on Wikipedia<\/a>, the techniques are standardized across more than a dozen IETF RFCs covering NAT terminology, IPsec compatibility, hole punching, and ICE.<\/p>\n<h2>Why NAT Is a Problem for Direct Connections<\/h2>\n<p>A NAT is, in effect, a stateful firewall. It tracks every outbound flow and creates a mapping entry: &#8220;internal <code>10.0.0.5:54321<\/code> \u2194 external <code>203.0.113.10:62000<\/code> for destination <code>198.51.100.7:443<\/code>.&#8221; Packets that arrive on the public side without a matching mapping are dropped.<\/p>\n<p>This works fine for client-server traffic. Your browser opens an outbound connection to a web server, the NAT creates a mapping, and replies flow back through the same hole. It breaks down for three scenarios:<\/p>\n<ul>\n<li><strong>Peer-to-peer connections<\/strong> \u2014 Two devices, both behind their own NATs, with no public IP between them. Neither side can initiate.<\/li>\n<li><strong>Inbound services on a residential network<\/strong> \u2014 A camera, a game server, or a self-hosted VPN endpoint that needs to accept connections from the internet.<\/li>\n<li><strong>Long-lived UDP flows<\/strong> \u2014 Voice, video, and gaming sessions where NAT mappings can expire after 30 seconds of silence.<\/li>\n<\/ul>\n<p>For one-to-many live broadcasts, this is usually solved by pushing the stream out to a server using a <a href=\"https:\/\/liveapi.com\/blog\/what-is-rtmp\/\" target=\"_blank\">push-based protocol like RTMP<\/a> \u2014 the client initiates outbound, so NAT is no obstacle. But for any application that wants real peer-to-peer media flow, NAT traversal is mandatory.<\/p>\n<h2>Types of NAT (and Why They Matter)<\/h2>\n<p>Not all NATs behave the same way. RFC 3489 originally classified NATs into four types based on how strictly they enforce mapping rules. Newer terminology (from RFC 4787) groups them by mapping behavior and filtering behavior. Either way, the type determines which traversal technique will work.<\/p>\n<table>\n<thead>\n<tr>\n<th>NAT Type<\/th>\n<th>Mapping Behavior<\/th>\n<th>What It Accepts<\/th>\n<th>Traversal Difficulty<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>Full Cone<\/strong><\/td>\n<td>Same external port for any destination<\/td>\n<td>Any external host<\/td>\n<td>Easy<\/td>\n<\/tr>\n<tr>\n<td><strong>Restricted Cone<\/strong><\/td>\n<td>Same external port for any destination<\/td>\n<td>Only hosts you&#8217;ve contacted (by IP)<\/td>\n<td>Easy<\/td>\n<\/tr>\n<tr>\n<td><strong>Port-Restricted Cone<\/strong><\/td>\n<td>Same external port for any destination<\/td>\n<td>Only IP+port combos you&#8217;ve contacted<\/td>\n<td>Moderate<\/td>\n<\/tr>\n<tr>\n<td><strong>Symmetric NAT<\/strong><\/td>\n<td>Different external port per destination<\/td>\n<td>Only the exact remote IP+port you contacted<\/td>\n<td>Hard \u2014 usually needs TURN<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Two more categories show up in modern networks:<\/p>\n<ul>\n<li><strong>Carrier-Grade NAT (CGNAT)<\/strong> \u2014 Used by mobile carriers and many fiber ISPs. Often layers another NAT on top of the customer&#8217;s home router. Frequently symmetric, and a major reason WebRTC connections fall back to relays.<\/li>\n<li><strong>Double NAT<\/strong> \u2014 A NAT inside another NAT (e.g., ISP-provided gateway plus your own router). Mostly transparent for outbound traffic, but breaks port forwarding and increases the chance of symmetric behavior.<\/li>\n<\/ul>\n<p>Modern NAT traversal stacks treat NATs as either <strong>endpoint-independent mapping (EIM)<\/strong> \u2014 &#8220;easy&#8221; NATs where a single external port maps to a single internal socket \u2014 or <strong>endpoint-dependent mapping (EDM)<\/strong> \u2014 &#8220;hard&#8221; NATs where each destination gets its own external port. EIM-to-EIM and EIM-to-EDM connections can usually be hole-punched. EDM-to-EDM almost always requires a relay.<\/p>\n<h2>How NAT Traversal Works: The Three-Step Pattern<\/h2>\n<p>Almost every NAT traversal system follows the same high-level pattern, regardless of whether it&#8217;s WebRTC, WireGuard, or a video conferencing SDK.<\/p>\n<ol>\n<li><strong>Signaling<\/strong> \u2014 Both peers connect to a shared rendezvous server (sometimes called a <a href=\"https:\/\/liveapi.com\/blog\/webrtc-signaling-server\/\" target=\"_blank\">signaling server<\/a>) over a normal client-server channel. They exchange the metadata they&#8217;ll need to find each other: addresses, ports, supported protocols, and cryptographic keys.<\/li>\n<li><strong>Candidate gathering<\/strong> \u2014 Each peer collects every plausible network address it might be reachable at: its local LAN address, its NAT&#8217;s public address (discovered via STUN), and a relay address (allocated on a TURN server) as a fallback.<\/li>\n<li><strong>Connectivity checks<\/strong> \u2014 The peers swap their candidate lists and simultaneously probe each pairing. They pick the best path that actually works, usually preferring direct connections over relays.<\/li>\n<\/ol>\n<p>The clever part is the simultaneous probing. When both peers send packets to each other&#8217;s public IP and port at roughly the same time, each NAT sees its own user &#8220;initiating&#8221; the flow and opens a return hole for the remote address. The peers then receive each other&#8217;s packets through the holes they just punched.<\/p>\n<h2>Core NAT Traversal Techniques<\/h2>\n<p>Different techniques solve different parts of the problem. Most production systems combine three or four of them.<\/p>\n<h3>STUN (Session Traversal Utilities for NAT)<\/h3>\n<p>STUN is the discovery layer. A client sends a UDP packet to a public STUN server, and the server replies with the source IP and port it observed. That public <code>ip:port<\/code> is the NAT mapping the client needs to share with its peer.<\/p>\n<ul>\n<li>Defined in RFC 5389 (and updated by RFC 8489)<\/li>\n<li>Tiny protocol: one request, one response, a few bytes each<\/li>\n<li>Works for any NAT that creates predictable mappings (full cone, restricted, port-restricted)<\/li>\n<li>Fails on symmetric NATs because the mapping depends on the destination \u2014 the STUN server sees a different port than the peer will see<\/li>\n<\/ul>\n<p>STUN servers are cheap to operate and there are several public ones available (Google, Cloudflare, Twilio). For a production application, you usually run your own to avoid rate limits and downtime. The <a href=\"https:\/\/pinggy.io\/blog\/how_nat_traversal_works\/\" target=\"_blank\" rel=\"nofollow\">Pinggy team summarizes the role<\/a> cleanly: STUN tells you &#8220;what address does the outside world see for me?&#8221;<\/p>\n<h3>TURN (Traversal Using Relays around NAT)<\/h3>\n<p>When direct connection fails \u2014 typically because one or both peers are behind a symmetric NAT \u2014 TURN provides a fallback. Both peers establish outbound connections to a TURN server, which then relays packets between them.<\/p>\n<ul>\n<li>Defined in RFC 5766 (and updated by RFC 8656)<\/li>\n<li>Acts as a media relay, so it consumes significant bandwidth and costs money to operate<\/li>\n<li>Required for around 10\u201320% of consumer connections globally, much higher behind corporate firewalls<\/li>\n<li>Supports UDP, TCP, and TLS allocations to handle restrictive networks<\/li>\n<\/ul>\n<p>The trade-off is latency and cost. Every byte of media traverses the TURN server twice (in and out), and the geographic location of the server affects the round-trip time. A poorly placed TURN server can add 100ms+ to a connection that would otherwise be a few milliseconds.<\/p>\n<h3>ICE (Interactive Connectivity Establishment)<\/h3>\n<p>ICE is the orchestration framework that combines STUN and TURN into a single algorithm. It&#8217;s the most widely deployed NAT traversal framework \u2014 every <a href=\"https:\/\/liveapi.com\/blog\/what-is-webrtc\/\" target=\"_blank\">WebRTC<\/a> implementation uses it under the hood.<\/p>\n<p>The ICE algorithm, in one sentence: gather every plausible candidate, exchange them via signaling, probe them all in parallel, and pick the best one that works.<\/p>\n<p>Candidate types in priority order:<\/p>\n<ol>\n<li><strong>Host candidates<\/strong> \u2014 Direct LAN addresses (best when both peers are on the same network)<\/li>\n<li><strong>Server-reflexive candidates<\/strong> \u2014 STUN-discovered public addresses (best for cross-NAT connections)<\/li>\n<li><strong>Peer-reflexive candidates<\/strong> \u2014 Addresses learned during connectivity checks<\/li>\n<li><strong>Relayed candidates<\/strong> \u2014 TURN-allocated addresses (fallback)<\/li>\n<\/ol>\n<p>ICE runs connectivity checks using STUN binding requests sent over the candidate pairs. Once a working path is found, ICE keeps probing in case a better one appears (or in case the current one breaks). This is what lets a WebRTC call survive a network change like Wi-Fi to cellular.<\/p>\n<h3>UDP Hole Punching<\/h3>\n<p>UDP hole punching is the actual mechanism that creates a direct path between two NATted peers. It&#8217;s what STUN and ICE rely on to make connections work without a relay.<\/p>\n<p>The technique:<\/p>\n<ol>\n<li>Both peers learn each other&#8217;s public <code>ip:port<\/code> via signaling.<\/li>\n<li>Both peers send UDP packets to each other&#8217;s public endpoint at roughly the same time.<\/li>\n<li>Each NAT, on seeing an outbound packet from its internal user, creates a mapping that permits return traffic from the destination.<\/li>\n<li>Within milliseconds, the next round of packets passes through both holes.<\/li>\n<\/ol>\n<p>It sounds fragile, and it is. Success rates depend on NAT type, timing, and packet loss. Symmetric NATs break it because the mapping for the peer&#8217;s IP differs from the mapping the STUN server saw. TCP hole punching exists too, but it&#8217;s much harder because TCP requires a full handshake; many implementations skip it.<\/p>\n<h3>Port Forwarding and IGD Protocols<\/h3>\n<p>If a NAT cooperates, you don&#8217;t need hole punching at all. The router can be asked to create a permanent mapping for an internal device.<\/p>\n<ul>\n<li><strong>UPnP IGD<\/strong> \u2014 Universal Plug and Play Internet Gateway Device protocol. Widely supported on consumer routers, frequently disabled by default for security reasons.<\/li>\n<li><strong>NAT-PMP<\/strong> \u2014 Apple&#8217;s simpler alternative.<\/li>\n<li><strong>PCP (Port Control Protocol)<\/strong> \u2014 RFC 6887, the modern successor designed to work with CGNAT.<\/li>\n<\/ul>\n<p>These are great when they work. They fail silently in many environments: enterprise networks disable them, CGNAT routers ignore them, and many ISPs filter inbound traffic anyway. Production systems treat them as an optimization, not a primary mechanism.<\/p>\n<h3>Relays as a Universal Fallback<\/h3>\n<p>A relay is just a public server with a known address that both peers can reach with outbound connections. It accepts packets from one peer and forwards them to the other. TURN is the standard relay protocol for WebRTC, but custom relays show up in many systems \u2014 Tailscale&#8217;s DERP, gaming services&#8217; dedicated game servers, and the regional edge nodes in a <a href=\"https:\/\/liveapi.com\/blog\/cdn-for-live-streaming\/\" target=\"_blank\">content delivery network<\/a> all play this role.<\/p>\n<p>The downside is always the same: cost, latency, and a centralized point of failure. The upside is reliability \u2014 a relay works through any NAT, any firewall, any network.<\/p>\n<h2>NAT Traversal in IPsec (NAT-T)<\/h2>\n<p>IPsec VPNs hit a specific NAT problem: the IPsec ESP protocol uses IP protocol 50, which has no port numbers. A NAT can&#8217;t multiplex multiple ESP flows behind a single public IP, because there&#8217;s nothing to multiplex on.<\/p>\n<p>NAT Traversal for IPsec (often called <strong>NAT-T<\/strong>, defined in RFC 3947 and RFC 3948) wraps ESP packets inside UDP on port 4500. The NAT can then track the UDP port and translate normally.<\/p>\n<p>How NAT-T negotiation works:<\/p>\n<ol>\n<li>During IKE phase 1 (UDP 500), both peers send a NAT-D payload \u2014 a hash of their IP and port.<\/li>\n<li>Each peer compares the received hash against the actual source it sees. A mismatch means a NAT is in the path.<\/li>\n<li>If a NAT is detected, both peers switch to UDP 4500 and encapsulate ESP in UDP.<\/li>\n<li>Keepalives are sent every 20 seconds to prevent the NAT mapping from timing out.<\/li>\n<\/ol>\n<p>NAT-T is mostly transparent to the user, but it&#8217;s worth knowing about when debugging IPsec connectivity issues. If UDP 4500 is blocked anywhere in the path, the tunnel will fail to come up.<\/p>\n<h2>NAT Traversal in WebRTC<\/h2>\n<p><a href=\"https:\/\/liveapi.com\/blog\/webrtc-live-streaming\/\" target=\"_blank\">WebRTC<\/a> is the most common place developers encounter NAT traversal in practice. Every browser-based real-time call, every video conferencing SDK, every multiplayer WebRTC game runs through ICE on every connection.<\/p>\n<p>The WebRTC NAT traversal flow:<\/p>\n<ol>\n<li>The application sets up a signaling channel \u2014 see how <a href=\"https:\/\/liveapi.com\/blog\/webrtc-vs-websocket\/\" target=\"_blank\">WebRTC compares to WebSocket<\/a> for transport options \u2014 to exchange offers and candidates.<\/li>\n<li>Each peer creates an <code>RTCPeerConnection<\/code> configured with one or more STUN and TURN servers.<\/li>\n<li>ICE gathering runs: the peer collects host, srflx, and relay candidates and emits them as <code>icecandidate<\/code> events.<\/li>\n<li>The application forwards candidates to the remote peer via signaling.<\/li>\n<li>Each side performs ICE connectivity checks against the received candidates.<\/li>\n<li>The first working pair becomes the active connection. Media starts flowing.<\/li>\n<\/ol>\n<p>For one-to-one calls, this works well \u2014 direct connections succeed roughly 80\u201390% of the time, and TURN catches the rest. For many-to-many calls, the math gets harder: pure mesh topologies require N(N-1)\/2 NAT traversals, and most production systems route media through a <a href=\"https:\/\/liveapi.com\/blog\/webrtc-server\/\" target=\"_blank\">WebRTC server<\/a> (an SFU or MCU) to avoid the explosion.<\/p>\n<p>The trade-offs between <a href=\"https:\/\/liveapi.com\/blog\/webrtc-vs-rtmp\/\" target=\"_blank\">WebRTC and RTMP<\/a> come down to exactly this. WebRTC pays the NAT traversal cost to get sub-500ms latency for interactive sessions. RTMP skips it entirely because the publisher initiates outbound to a server.<\/p>\n<h2>Challenges and Limitations of NAT Traversal<\/h2>\n<p>Even with STUN, TURN, and ICE all working together, several scenarios still cause real problems.<\/p>\n<h3>Symmetric NAT<\/h3>\n<p>Symmetric NATs assign a different external port for every destination. The mapping STUN reports is the one used for the STUN server&#8217;s IP \u2014 useless to a peer at a different IP. Symmetric NATs are common on:<\/p>\n<ul>\n<li>Mobile carriers (almost universally)<\/li>\n<li>Corporate networks with strict outbound policies<\/li>\n<li>Some consumer ISPs<\/li>\n<li>Hotel and conference Wi-Fi<\/li>\n<\/ul>\n<p>The only reliable solution is TURN, which is why operating TURN servers is a real cost line item for any WebRTC product.<\/p>\n<h3>CGNAT (Carrier-Grade NAT)<\/h3>\n<p>CGNAT places another layer of NAT between your home router and the public internet, sharing one public IPv4 address across hundreds of customers. Port forwarding doesn&#8217;t work because you don&#8217;t control the carrier-side NAT. UPnP doesn&#8217;t work for the same reason. Hole punching usually works for EIM CGNATs, but mobile carriers often use EDM behavior.<\/p>\n<p>The long-term fix is IPv6, which has no NAT \u2014 every device gets a globally routable address. Most major mobile carriers now deploy IPv6 by default, and dual-stack networks fix many of the worst cases.<\/p>\n<h3>NAT Mapping Lifetimes<\/h3>\n<p>UDP mappings on consumer NATs expire after 30 seconds to a few minutes of silence. A long-lived voice or video session needs to send keepalive packets to prevent the mapping from closing. WebRTC handles this with STUN consent freshness checks every 5 seconds. Custom protocols need their own keepalive logic.<\/p>\n<h3>Asymmetric Routing and Hairpinning<\/h3>\n<p>Hairpinning happens when two devices behind the same NAT try to reach each other via the NAT&#8217;s public address. The NAT has to receive the packet on its external interface and route it back to its own internal network \u2014 many NATs simply drop these packets. ICE handles this by also gathering host (LAN) candidates, but only if both devices are explicitly on the same subnet.<\/p>\n<h3>Security and Trust<\/h3>\n<p>NAT traversal creates inbound paths that didn&#8217;t exist before. Hole punching, TURN allocations, and port mapping all open channels that an attacker could try to abuse. Production systems pair NAT traversal with end-to-end encryption (DTLS-SRTP in WebRTC, Noise framework in WireGuard, IPsec ESP in NAT-T) so that opening a path doesn&#8217;t mean trusting it.<\/p>\n<hr>\n<p>Direct peer-to-peer connections aren&#8217;t always the right answer. For one-to-many video \u2014 a live broadcast, a webinar, an OTT stream \u2014 you don&#8217;t need NAT traversal at all. The publisher pushes outbound to an ingest server, the server fans out to viewers via CDN, and every connection is initiated from the client side. The complexity of STUN, TURN, and ICE disappears, replaced by a simpler client-server streaming model. The next sections cover how to apply NAT traversal where you actually need it, and where you can sidestep it entirely.<\/p>\n<h2>How to Implement NAT Traversal in Real Apps<\/h2>\n<p>The implementation pattern depends on what you&#8217;re building. Here&#8217;s how the major use cases break down.<\/p>\n<h3>Real-Time Peer-to-Peer (Video Calls, Gaming, Remote Desktop)<\/h3>\n<p>Use WebRTC or a WebRTC-based library. Don&#8217;t try to build NAT traversal from scratch \u2014 the ICE state machine, the STUN binding logic, the candidate prioritization, the TURN allocation flow, and the cross-browser quirks add up to thousands of lines of code that have to be exactly right.<\/p>\n<pre><code class=\"language-javascript\">const pc = new RTCPeerConnection({\n  iceServers: [\n    { urls: 'stun:stun.example.com:3478' },\n    {\n      urls: 'turn:turn.example.com:3478',\n      username: 'user',\n      credential: 'pass'\n    }\n  ],\n  iceTransportPolicy: 'all',  \/\/ or 'relay' to force TURN\n  bundlePolicy: 'max-bundle'\n});\n\npc.onicecandidate = (event) =&gt; {\n  if (event.candidate) {\n    signalingChannel.send({ candidate: event.candidate });\n  }\n};\n\npc.ontrack = (event) =&gt; {\n  videoElement.srcObject = event.streams[0];\n};<\/code><\/pre>\n<p>Operational checklist:<\/p>\n<ul>\n<li>Run STUN and TURN servers in multiple regions (a single TURN region adds 50\u2013200ms for distant users).<\/li>\n<li>Use coturn or eturnal as the TURN implementation. Both are battle-tested.<\/li>\n<li>Generate short-lived TURN credentials per session (RFC 7635) to prevent abuse.<\/li>\n<li>Monitor TURN bandwidth \u2014 it can be the biggest line item on a WebRTC product.<\/li>\n<\/ul>\n<h3>Live Streaming and Broadcast<\/h3>\n<p>For one-to-many live video, skip NAT traversal entirely. The publisher pushes outbound to an ingest server using <a href=\"https:\/\/liveapi.com\/blog\/rtmp-server\/\" target=\"_blank\">RTMP<\/a> or <a href=\"https:\/\/liveapi.com\/blog\/srt-protocol\/\" target=\"_blank\">SRT<\/a>, the server transcodes and packages, and viewers pull <a href=\"https:\/\/liveapi.com\/blog\/what-is-hls-streaming\/\" target=\"_blank\">HLS<\/a> over HTTP via a CDN. Every link is initiated by the client, so NAT just works.<\/p>\n<p>This is the model <a href=\"https:\/\/liveapi.com\/live-streaming-api\/\" target=\"_blank\">LiveAPI&#8217;s live streaming API<\/a> uses. A broadcaster&#8217;s OBS or hardware encoder pushes to <code>rtmps:\/\/ingest.liveapi.com\/...<\/code> \u2014 outbound, NAT-friendly, no STUN required. Viewers pull HLS segments over HTTPS from the nearest edge \u2014 again outbound, again NAT-friendly. For 99% of live streaming scenarios, this is the right answer because it&#8217;s simpler, scales better, and avoids the per-connection cost of TURN relays.<\/p>\n<h3>VPN and Site-to-Site Connectivity<\/h3>\n<p>For IPsec, enable NAT-T (UDP 4500 encapsulation) on both endpoints. Most enterprise firewalls and VPN concentrators do this automatically. Make sure UDP 4500 is not blocked anywhere in the path.<\/p>\n<p>For WireGuard, NAT traversal is intentionally minimal. WireGuard expects at least one endpoint to be reachable (either with a public IP or via a port forward). For mobile or roaming clients behind NAT, you typically set <code>PersistentKeepalive = 25<\/code> so the NAT mapping stays open from the client side.<\/p>\n<h3>IoT and Remote Access<\/h3>\n<p>For an IoT device that needs to be reachable from a phone, the common pattern is:<\/p>\n<ol>\n<li>The device connects outbound to a cloud relay over MQTT or WebSocket on startup.<\/li>\n<li>The phone connects outbound to the same relay.<\/li>\n<li>The relay multiplexes commands and telemetry.<\/li>\n<\/ol>\n<p>If real-time media (camera feeds, two-way audio) is needed, layer WebRTC on top of the signaling channel and let ICE handle the path optimization.<\/p>\n<h2>Tools and Infrastructure for NAT Traversal<\/h2>\n<table>\n<thead>\n<tr>\n<th>Category<\/th>\n<th>Open Source<\/th>\n<th>Hosted \/ Commercial<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>STUN servers<\/strong><\/td>\n<td>coturn, stunner<\/td>\n<td>Google STUN (free), Twilio, Cloudflare<\/td>\n<\/tr>\n<tr>\n<td><strong>TURN servers<\/strong><\/td>\n<td>coturn, eturnal, Pion TURN<\/td>\n<td>Twilio Network Traversal, Xirsys, Cloudflare TURN<\/td>\n<\/tr>\n<tr>\n<td><strong>WebRTC stacks<\/strong><\/td>\n<td>libwebrtc, Pion, mediasoup, Janus<\/td>\n<td>Daily, Agora, Vonage, <a href=\"https:\/\/liveapi.com\/blog\/video-conferencing-api\/\" target=\"_blank\">video conferencing APIs<\/a><\/td>\n<\/tr>\n<tr>\n<td><strong>VPN with built-in NAT traversal<\/strong><\/td>\n<td>Tailscale, ZeroTier, Nebula<\/td>\n<td>Twingate, NordLayer<\/td>\n<\/tr>\n<tr>\n<td><strong>Signaling<\/strong><\/td>\n<td>Socket.IO, custom WebSocket<\/td>\n<td>Pusher, Ably, Firebase<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>For most real-time applications, you&#8217;ll combine three pieces: a signaling server, a STUN service (free is fine for low volume), and a TURN service (which is where the real bandwidth costs land). For a <a href=\"https:\/\/liveapi.com\/blog\/video-sdk\/\" target=\"_blank\">video SDK<\/a> you build on top of, the SDK usually wraps all three. The <a href=\"https:\/\/liveapi.com\/blog\/webrtc-vs-hls\/\" target=\"_blank\">WebRTC vs HLS<\/a> decision often comes down to whether you can afford the TURN overhead \u2014 and for one-to-many distribution, you usually can&#8217;t.<\/p>\n<p>If you&#8217;re building anything with live video streaming, it&#8217;s worth asking whether you actually need peer-to-peer at all. A streaming API platform like LiveAPI handles ingest, transcoding, <a href=\"https:\/\/liveapi.com\/blog\/adaptive-bitrate-streaming\/\" target=\"_blank\">adaptive bitrate streaming<\/a>, CDN delivery, and recording without ever asking your app to deal with NAT traversal. RTMP and SRT push, HLS pull, end of story.<\/p>\n<h2>Is NAT Traversal Right for Your Project?<\/h2>\n<p>NAT traversal makes sense when:<\/p>\n<ul>\n<li>You need true peer-to-peer connectivity (lowest latency, no media server cost)<\/li>\n<li>Your media flows are interactive \u2014 two-way calls, gaming, control sessions<\/li>\n<li>You can afford to run STUN and TURN infrastructure (or pay a vendor)<\/li>\n<li>You can tolerate ~10\u201320% of sessions falling back to relays<\/li>\n<\/ul>\n<p>You can skip NAT traversal when:<\/p>\n<ul>\n<li>Your traffic is one-to-many (live broadcasts, OTT, video on demand)<\/li>\n<li>Latency requirements are >1 second (HLS-class streams)<\/li>\n<li>The publisher can initiate outbound (RTMP, SRT, HLS push)<\/li>\n<li>You&#8217;d rather pay for CDN bandwidth than maintain TURN servers<\/li>\n<\/ul>\n<p>For most consumer-facing video products \u2014 webinars, sermons, e-commerce livestreams, <a href=\"https:\/\/liveapi.com\/blog\/what-is-ott-platform\/\" target=\"_blank\">OTT platforms<\/a> \u2014 the second list applies. For video conferencing, telehealth, and interactive games, the first list does.<\/p>\n<h2>NAT Traversal FAQ<\/h2>\n<h3>What is the difference between NAT and NAT traversal?<\/h3>\n<p>NAT (Network Address Translation) is what a router does to share one public IP across many private devices. NAT traversal is a set of techniques that lets a device behind a NAT receive or initiate connections that NAT would otherwise block. NAT is server-side functionality; NAT traversal is client-side and protocol-side.<\/p>\n<h3>Why does NAT traversal sometimes fail?<\/h3>\n<p>The most common cause is symmetric NAT \u2014 typically on mobile carriers or corporate networks \u2014 where the NAT assigns a different external port for every destination. STUN can&#8217;t predict the mapping the peer will see, so direct connection fails and the session falls back to a TURN relay (or fails entirely if no TURN is configured).<\/p>\n<h3>Is STUN or TURN better for NAT traversal?<\/h3>\n<p>They serve different roles. STUN is a lightweight protocol that helps two peers find each other&#8217;s public address so they can attempt a direct connection. TURN is a relay that actually carries the traffic when a direct connection isn&#8217;t possible. Production WebRTC applications use both: STUN for the common case, TURN as a fallback.<\/p>\n<h3>What is NAT-T in IPsec?<\/h3>\n<p>NAT-T (NAT Traversal for IPsec, RFC 3947\/3948) wraps IPsec ESP packets inside UDP port 4500 so they can pass through a NAT. Without NAT-T, ESP packets (IP protocol 50) have no port number and a NAT can&#8217;t track multiple flows. Modern IPsec implementations detect NAT in the path and switch to UDP encapsulation automatically.<\/p>\n<h3>Do I need NAT traversal for <a href=\"https:\/\/liveapi.com\/blog\/how-to-build-a-video-streaming-app\/\" target=\"_blank\">live streaming<\/a>?<\/h3>\n<p>Almost never, for one-to-many streaming. Live streaming protocols like RTMP, SRT, and HLS use outbound client-server connections, which NAT permits by default. NAT traversal becomes relevant only when you need true peer-to-peer media flow \u2014 typically WebRTC-based video conferencing or interactive sessions.<\/p>\n<h3>Does IPv6 eliminate the need for NAT traversal?<\/h3>\n<p>In theory, yes. Every IPv6 device has a globally routable address, so there&#8217;s nothing to traverse. In practice, most networks are still dual-stack or IPv4-only, and stateful firewalls still block unsolicited inbound traffic even on IPv6. Hole punching and ICE-style candidate gathering still apply, just without the address translation step.<\/p>\n<h3>How does WireGuard handle NAT traversal?<\/h3>\n<p>WireGuard deliberately keeps things minimal. It expects at least one peer to be reachable (public IP or port forward). For clients behind NAT, the <code>PersistentKeepalive<\/code> setting (commonly 25 seconds) sends a small packet on a regular interval to keep the NAT mapping open, allowing the server to send packets back when needed.<\/p>\n<h3>Can NAT traversal work without a server at all?<\/h3>\n<p>No. Every NAT traversal technique needs some external rendezvous point \u2014 at minimum a signaling channel so peers can exchange addresses, and a STUN server to discover NAT mappings. The server cost can be tiny (STUN is bandwidth-cheap), but it can&#8217;t be zero.<\/p>\n<h3>What&#8217;s the typical success rate of direct peer-to-peer connections?<\/h3>\n<p>Around 80\u201390% globally, depending on the user base. Pure consumer Wi-Fi is highest. Mobile carriers and corporate networks are lowest, mostly due to symmetric NAT and CGNAT. The remaining 10\u201320% need a TURN relay to connect at all.<\/p>\n<hr>\n<p>NAT traversal is one of those things that&#8217;s invisible when it works and infuriating when it doesn&#8217;t. For interactive real-time applications, you need to budget for it: signaling, STUN, TURN, and the operational work of keeping all three running across regions. For everything else \u2014 and especially for the one-to-many video streaming that most products actually need \u2014 there&#8217;s a simpler path through a server-mediated streaming API.<\/p>\n<p>If you&#8217;re building a live streaming or <a href=\"https:\/\/liveapi.com\/blog\/video-hosting-api\/\" target=\"_blank\">video hosting<\/a> feature and don&#8217;t want to deal with TURN bandwidth bills or ICE state machines, <a href=\"https:\/\/liveapi.com\/\" target=\"_blank\">Get started with LiveAPI<\/a> to push streams over RTMP or SRT and deliver to any device over HLS \u2014 no NAT traversal required.<\/p>\n","protected":false},"excerpt":{"rendered":"<p><span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Reading Time: <\/span> <span class=\"rt-time\">14<\/span> <span class=\"rt-label rt-postfix\">minutes<\/span><\/span> More than 90% of consumer devices sit behind a router that performs Network Address Translation (NAT). That single fact is the reason peer-to-peer video calls, multiplayer games, and remote desktop tools can&#8217;t just send packets to each other the way two servers in a data center can. NAT traversal is the set of techniques that [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1048,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_yoast_wpseo_title":"What Is NAT Traversal? STUN, TURN, ICE Explained %%sep%% %%sitename%%","_yoast_wpseo_metadesc":"Learn what NAT traversal is, how it works, the role of STUN, TURN, ICE, and UDP hole punching, and how to apply it to video streaming and real-time apps.","inline_featured_image":false,"footnotes":""},"categories":[31],"tags":[],"class_list":["post-1047","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-webrtc"],"jetpack_featured_media_url":"https:\/\/liveapi.com\/blog\/wp-content\/uploads\/2026\/05\/nat-traversal.jpg","yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v15.6.2 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<meta name=\"description\" content=\"Learn what NAT traversal is, how it works, the role of STUN, TURN, ICE, and UDP hole punching, and how to apply it to video streaming and real-time apps.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/liveapi.com\/blog\/nat-traversal\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"What Is NAT Traversal? STUN, TURN, ICE Explained - LiveAPI Blog\" \/>\n<meta property=\"og:description\" content=\"Learn what NAT traversal is, how it works, the role of STUN, TURN, ICE, and UDP hole punching, and how to apply it to video streaming and real-time apps.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/liveapi.com\/blog\/nat-traversal\/\" \/>\n<meta property=\"og:site_name\" content=\"LiveAPI Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-05-18T08:55:50+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-05-18T08:56:32+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\">\n\t<meta name=\"twitter:data1\" content=\"20 minutes\">\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"https:\/\/liveapi.com\/blog\/#website\",\"url\":\"https:\/\/liveapi.com\/blog\/\",\"name\":\"LiveAPI Blog\",\"description\":\"Live Video Streaming API Blog\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":\"https:\/\/liveapi.com\/blog\/?s={search_term_string}\",\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/liveapi.com\/blog\/nat-traversal\/#primaryimage\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/liveapi.com\/blog\/wp-content\/uploads\/2026\/05\/nat-traversal.jpg\",\"width\":940,\"height\":625,\"caption\":\"Photo by Brett Sayles on Pexels\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/liveapi.com\/blog\/nat-traversal\/#webpage\",\"url\":\"https:\/\/liveapi.com\/blog\/nat-traversal\/\",\"name\":\"What Is NAT Traversal? STUN, TURN, ICE Explained - LiveAPI Blog\",\"isPartOf\":{\"@id\":\"https:\/\/liveapi.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/liveapi.com\/blog\/nat-traversal\/#primaryimage\"},\"datePublished\":\"2026-05-18T08:55:50+00:00\",\"dateModified\":\"2026-05-18T08:56:32+00:00\",\"author\":{\"@id\":\"https:\/\/liveapi.com\/blog\/#\/schema\/person\/98f2ee8b3a0bd93351c0d9e8ce490e4a\"},\"description\":\"Learn what NAT traversal is, how it works, the role of STUN, TURN, ICE, and UDP hole punching, and how to apply it to video streaming and real-time apps.\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/liveapi.com\/blog\/nat-traversal\/\"]}]},{\"@type\":\"Person\",\"@id\":\"https:\/\/liveapi.com\/blog\/#\/schema\/person\/98f2ee8b3a0bd93351c0d9e8ce490e4a\",\"name\":\"govz\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/liveapi.com\/blog\/#personlogo\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/ab5cbe0543c0a44dc944c720159323bd001fc39a8ba5b1f137cd22e7578e84c9?s=96&d=mm&r=g\",\"caption\":\"govz\"},\"sameAs\":[\"https:\/\/liveapi.com\/blog\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","_links":{"self":[{"href":"https:\/\/liveapi.com\/blog\/wp-json\/wp\/v2\/posts\/1047","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/liveapi.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/liveapi.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/liveapi.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/liveapi.com\/blog\/wp-json\/wp\/v2\/comments?post=1047"}],"version-history":[{"count":1,"href":"https:\/\/liveapi.com\/blog\/wp-json\/wp\/v2\/posts\/1047\/revisions"}],"predecessor-version":[{"id":1049,"href":"https:\/\/liveapi.com\/blog\/wp-json\/wp\/v2\/posts\/1047\/revisions\/1049"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/liveapi.com\/blog\/wp-json\/wp\/v2\/media\/1048"}],"wp:attachment":[{"href":"https:\/\/liveapi.com\/blog\/wp-json\/wp\/v2\/media?parent=1047"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/liveapi.com\/blog\/wp-json\/wp\/v2\/categories?post=1047"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/liveapi.com\/blog\/wp-json\/wp\/v2\/tags?post=1047"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}