💡 Hairpin NAT (NAT Loopback) — Allow Internal Users to Access Internal Servers Using Public Domain Names
🧱 1. The Scenario
In many corporate or home networks, administrators use NAT (Network Address Translation) to expose internal servers to the Internet.
For example:
- Server IP:
192.168.1.10 - Public IP:
122.116.109.114 - Service:
mail.example.com → 122.116.109.114 → 192.168.1.10
External users can access mail.example.com without issues.
However, when internal users try to access the same domain, they often find that:
❌ The connection times out or fails entirely.
This is a classic Hairpin NAT (also known as NAT Loopback) problem.
🧭 2. Understanding the Problem
A NAT device (such as a router, firewall, or Linux gateway) typically handles traffic like this:
- An internal client (
192.168.1.20) tries to connect tomail.example.com(which resolves to122.116.109.114). - The router sees that the destination IP is its own WAN address, but the source is inside the LAN.
- Without Hairpin NAT configured, the router won’t forward the packet back into the LAN — the connection simply fails.
In short, traditional NAT only handles external → internal translation.
It doesn’t loop traffic originating from inside the same network.
Think of it like mailing a letter to your own house using your public mailing address — the postman doesn’t know he should just hand it back to you.
⚙️ 3. How Hairpin NAT Works
Hairpin NAT allows a packet that originates inside the LAN and targets the router’s public IP to “loop back” to the correct internal server.
Here’s what happens step by step:
- Client (
192.168.1.20) connects to122.116.109.114:443. - The gateway rewrites the destination (via DNAT) to
192.168.1.10(the internal server). - The gateway also rewrites the source (via SNAT) to its own LAN IP,
192.168.1.1. - The server (
192.168.1.10) sends its reply to192.168.1.1, which then SNATs it back to192.168.1.20.
The key step is #3 — SNAT:
Without changing the source IP, the server would see another local IP (192.168.1.20) and reply directly, bypassing the NAT.
This causes asymmetric routing and broken connections.
🧩 4. Common Configuration Methods
🔹 1️⃣ Linux / iptables
# DNAT: Forward external IP to internal server
iptables -t nat -A PREROUTING -d 122.116.109.114 -p tcp --dport 443 -j DNAT --to-destination 192.168.1.10
# SNAT: Ensure return traffic loops correctly for same subnet
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -d 192.168.1.10 -j SNAT --to-source 192.168.1.1
🔹 2️⃣ OPNsense / pfSense
In the GUI:
- Go to Firewall → NAT → Outbound
- Choose Hybrid Outbound NAT
- Add a rule:
- Source: LAN subnet
- Destination: LAN subnet (or specify the internal server IP)
- Translation: Interface address
- Save and apply changes.
🔹 3️⃣ Routers / Home Gateways
Some routers (ASUS, Mikrotik, etc.) include a built-in “NAT Loopback” or “Hairpin NAT” feature.
Just enable it, and LAN users can access internal services via the public domain.
In Mikrotik, for example, a
masqueraderule automatically handles hairpin NAT behavior.
🧰 5. Alternative Solution — Split DNS
Instead of configuring Hairpin NAT, you can implement Split DNS (also known as internal/external DNS separation):
| Network Zone | DNS Response |
|---|---|
| External | mail.example.com → 122.116.109.114 |
| Internal | mail.example.com → 192.168.1.10 |
Internal clients directly resolve the local IP, bypassing NAT entirely.
📘 Tip: If you’re running your own DNS server (like BIND9, Unbound, or AdGuard Home),
Split DNS is often a cleaner and more efficient solution.
✅ 6. Conclusion
| Solution | Pros | Cons |
|---|---|---|
| Hairpin NAT | No DNS modification; same domain inside and outside | Requires correct NAT/firewall setup |
| Split DNS | Fast and stable; DNS-based control | Requires managing internal DNS zones |
If your environment already uses an internal DNS server, Split DNS is the better long-term approach.
Otherwise, enabling Hairpin NAT is a quick and practical fix to keep internal and external access consistent.