How Pangolin Punches Through NATs and Firewalls

Owen Schwartz
Owen Schwartz
Co-founder & CTO
Cover Image for How Pangolin Punches Through NATs and Firewalls

How Pangolin Navigates NATs and Firewalls

Pangolin is designed to forge encrypted links between your hardware and distant networks without the headache of manual port forwarding or wrestling with complicated router settings. This deep dive explores the mechanics of establishing direct peer-to-peer communication across Network Address Translators (NATs) and stateful security barriers. We will break down the challenge from the ground up, illustrating how Pangolin connects a mobile device to a remote site regardless of the digital hurdles in between. Whether your traffic originates from a public Wi-Fi hotspot, a restrictive corporate office, or a standard home router, our system coordinates multiple techniques to find the most efficient data path.

The Core Essentials: UDP and Socket Management

Before we can bypass NAT constraints, two architectural prerequisites must be met. First, the communication must rely on UDP rather than TCP. While traversing TCP is technically possible, it is notoriously cumbersome and often requires invasive kernel-level adjustments. Because Pangolin is built on WireGuard - which is natively UDP-based - it is perfectly primed for this kind of traversal.

Second, the application must maintain absolute authority over the network socket. Successful NAT traversal involves managing auxiliary packets alongside the primary protocol traffic. You cannot achieve this by simply using a high-level, "black box" library. The traversal logic and the main data stream have to operate on the exact same socket, as NAT devices assign unique mappings to every individual socket. Once these foundations are set, we can tackle the primary obstacles: firewalls and NATs.

Navigating Stateful Firewalls

Stateful firewalls represent the first, more manageable hurdle. Since nearly every NAT device includes a stateful firewall, mastering this is a prerequisite for broader connectivity. You likely interact with these daily via Windows Defender, Linux iptables, or cloud-based security groups. While they are highly flexible, most follow a simple "default-deny" logic: outbound traffic is fine, but unsolicited inbound traffic is blocked.

However, "inbound" and "outbound" are just conceptual labels; on the wire, there are only individual packets. How does the firewall decide what to let in?

The secret is the "state". The firewall keeps a log of outgoing packets and uses that history to vet incoming ones. For UDP, the rule is simple: the firewall allows an incoming packet only if it matches a destination that the internal device recently messaged. If your laptop pings a remote server, the firewall makes a mental note to let that specific server ping you back. Because the trusted internal device started the conversation, the firewall assumes the response is safe.

The Deadlock of Facing Firewalls

This logic works great for simple client-server models, but it creates a "who goes first?" dilemma when two firewalled clients try to talk directly. Both sides are waiting for the other to initiate, but neither can receive the initial "hello" because their respective firewalls block it. While opening ports manually is an option, it is a nightmare to manage at scale and impossible on networks you don't control, like at an airport. We need a more elegant workaround.

Piercing the Veil Without Manual Setup

The key is that an outbound packet must clear the path before an inbound one can enter. Crucially, the firewall doesn't care if the original outgoing packet actually reached its destination; it only cares that the attempt was made. To exploit this, both peers must first know each other's ip:port. Pangolin uses a central coordination server to swap this metadata securely.

Once the peers have each other’s addresses, they start firing UDP packets at one another. Many of these initial packets will vanish into the void, which is a normal part of the process. Consider a laptop and a server:

  • The laptop sends a packet to the server. It clears the laptop's firewall but is killed by the server's corporate firewall.

  • Crucially, the laptop's firewall is now "open" for a response from the server.

  • Simultaneously, the server sends a packet to the laptop.

  • Because the laptop’s firewall already saw an outbound attempt to the server, it identifies this incoming packet as a valid "response" and lets it through.

  • Now the server’s firewall also opens up, recognizing the laptop as a legitimate contact.

By sending a follow-up packet, the laptop completes the bridge. We have now forced a two-way street through two defensive walls that were designed to stay closed.

Vital Considerations for Success

This process requires precision. What are the traps?

  • Timing is everything: Both sides need to try connecting at roughly the same time so the firewall windows overlap. Rather than guessing, Pangolin uses a coordination "side channel" to sync the start time using the websocket connection to the Pangolin server.

  • The Gerbil Role: The coordination and relay (Gerbil) handles this discovery and provides a safety net if direct paths fail.

  • Staying Alive: Firewalls have short memories (often just 30 seconds for UDP). We have to send "heartbeat" packets regularly to keep the connection active.

  • Layering: The best part is that this works regardless of how many firewall layers are stacked in between, as long as they all allow outbound traffic.

The NAT Complication

NAT devices add a layer of translation to the firewall logic. Because your home network uses private IP space (like 192.168.1.0/24) that cannot be routed on the open internet, your router must act as a translator.

When your laptop (192.168.1.50:1234) sends data to a server at 77.88.99.100:5678, your router intercepts it. It picks a random available port on its own public interface—for example, 11.22.33.44:4242. It then creates a mapping: internal 192.168.1.50:1234 is now represented globally as 11.22.33.44:4242.

The remote server only ever sees the public address (11.22.33.44:4242) and sends its replies there. The router then transparently swaps the addresses back so your laptop receives the data without ever knowing its "identity" was changed.

However, some "difficult" corporate NATs change this mapping for every new destination. If you send data to one peer at 55.66.77.88:1234 and another at 77.88.99.100:2345, a restrictive NAT might assign you two completely different public ports on 11.22.33.44, breaking the simple discovery model.

Finding Your Public Identity

The problem is that neither peer knows where to aim their packets because their public ip:port doesn't technically exist until they start talking. To solve this, Pangolin asks our Gerbil relay servers: "How do I look to you?". The server tells the client its observed public ip:port, and the client then shares that info with its peers using the central Pangolin server. This is why using the same socket for the protocol and the discovery is mandatory; a new socket would result in a totally different NAT mapping.

When Simple Discovery Stalls

While this works for most home users, it often fails on "high-security" corporate NATs. Some "easy" NATs use the same public mapping for every destination. However, "difficult" NATs create a unique mapping for every single destination you contact. If the port you use to talk to the Gerbil server is different from the port you use to talk to your peer, the connection will fail.

The Safety Net: Gerbil Relay Servers

When all the NAT-piercing tricks in the book fail, Pangolin doesn't give up. We utilize a relay system where both sides connect to a middleman that passes packets between them. While this adds a slight bit of latency, if the relay is well-positioned, the impact is minimal. It is infinitely better than having no connection at all.

Some environments are so restrictive they block everything but DNS traffic. In these cases, no amount of cleverness can force a direct path. Gerbil acts as a multi-tool: it handles the initial handshake, helps with endpoint discovery, and steps in as a high-performance relay whenever a direct peer-to-peer path is blocked.

How the Relay Works

The relay server hosts a simple UDP socket for the clients on default port 21820. Any client can send Wireguard packets to this port and the Gerbil server identifies them as WG packets using their headers. If its a relay Wireguard connection it checks with all of the sites connected using their direct backhaul Wireguard tunnels. If the destination site is already connected and ready to accept traffic from the client, it sends it right down that same tunnel we use for proxy connections. When a client connects to the relay, it establishes a secure WireGuard tunnel end to end. The relay then forwards packets between the two clients as needed. This allows us to maintain end-to-end encryption and authentication, even when the traffic is passing through an intermediary.

While some services use the WebRTC standard STUN and TURN protocols for NAT traversal and relaying, we built our own custom solution to have more control over the process and to optimize for our specific use case. The relay server is designed to be lightweight and efficient, minimizing latency while maximizing reliability.

From the Site's Perspective

When a site connects to the Gerbil relay, it establishes a secure WireGuard tunnel end to end - directly to the relay server. This tunnel is used for the public pangolin application resources that use proxy connections from the Pangolin server. Its the secure transport to get from the proxy to the site. The nice thing is we can also use this same tunnel to forward packets for clients that are connecting through the relay. This means that even if a client is connecting through the relay, the traffic is still encrypted end-to-end between the client and the site, with the relay simply acting as a pass-through.

How Pangolin Discovers the Best Path

To connect, we first compile a list of "candidate" endpoints - every possible way to reach a site.

We swap these lists via the websocket backend side channel and then blast probe packets at every single candidate on the list. These "pings" serve two roles: they punch through the NAT/firewall and they measure the quality of the path.

We don't just guess which path is best; we observe which ones actually work and select the one with the lowest round-trip latency. This prioritizes direct WAN over relays. Because we start communicating through the relay immediately, the connection feels instant, even while we are quietly upgrading you to a faster direct path in the background.

Maintenance and Security

Connections are living things. Pangolin continuously sends probes to keep NAT mappings from expiring and to ensure the path is still healthy. If a direct path suddenly dies, we immediately drop back to the Gerbil relay and start searching for a new direct route.

Security is baked into the protocol itself. Because we use WireGuard's public key crypto, it doesn't matter which IP path we use; the data is always encrypted and authenticated end-to-end. Even our discovery packets are encrypted to prevent any potential tampering.

Summary of the Process

  1. Identify all local and public ip:port candidates.

  2. Coordinate with peers via the Gerbil side channel to swap keys and addresses.

  3. Initiate immediate connectivity through the Gerbil relay.

  4. Probe all direct paths to pierce firewalls and NATs.

  5. Upgrade to the fastest discovered direct path transparently.

  6. Monitor and fail back to relays if the network environment changes.

The result is a connection that is as robust as it is fast, working in nearly every network configuration on the planet.

Would you like me to help you set up a self-hosted Gerbil server or walk through the WireGuard configuration for your specific site?

Learn more

Want to see Pangolin's NAT traversal in action? Get started with a free account or self-host the open-source server.

For questions about how Pangolin handles your specific network environment, reach out to our team.