FortiGate Hairpin NAT Fails: Asymmetric Return Path Detection
Hairpin NAT (also called NAT loopback or NAT reflection) allows internal clients to reach a server via its external public IP address rather than the internal IP. On FortiGate, this feature can fail silently when the return path from the server takes a different interface or routing path than the outbound request. This asymmetric return path triggers FortiGate's anti-spoofing and reverse-path filtering mechanisms, causing the connection to drop or reset.
How Hairpin NAT Works on FortiGate
When an internal client (192.168.1.100) connects to a public IP (203.0.113.5) that actually belongs to an internal server (192.168.1.50), FortiGate must intercept and rewrite the traffic. The outbound packet is rewritten so the destination becomes 192.168.1.50, and the source is rewritten to appear as if it came from the internal client's gateway. The return traffic from the server back to the client must be rewritten again to restore the public IP as the source.
This works smoothly when both directions traverse the same firewall interface and routing domain. Problems emerge when the return path is asymmetric: the outbound leg uses one path while the inbound leg uses another.
Asymmetric Return Path Detection and Rejection
FortiGate performs several checks on return traffic to prevent spoofing and reflection attacks. When a packet arrives on an interface, the firewall verifies that the source IP is reachable via that same interface (or at least via a consistent routing path). If the return traffic from the hairpin NAT connection arrives on a different interface or via an unexpected route, FortiGate may flag it as anomalous.
The firewall's asymmetric routing detection, combined with its strict reverse-path filtering (RPF) and anti-spoofing rules, can reject the return leg of the hairpin connection. This manifests as one-way traffic: the client's outbound SYN reaches the server, but the server's SYN-ACK is dropped before it reaches the client.
Common Scenarios and Causes
- →Multiple WAN links or failover paths: outbound traffic uses WAN1, but return uses WAN2 due to routing or failover state
- →Asymmetric ISP routing: your outbound packets take one carrier path; inbound packets take another
- →VLAN or interface mismatch: hairpin rule applies to one VLAN, but return traffic arrives on a different VLAN interface
- →Policy routing or PBR: outbound traffic is policy-routed to a specific interface, but return traffic follows the default route
- →NAT rule scope: hairpin NAT rule is not applied consistently to both directions, or implicit deny blocks the return
- →Loose RPF mode disabled: strict reverse-path filtering rejects the return packet because it arrives on an unexpected interface
Diagnosis and Remediation
Start by capturing traffic on both the outbound and inbound interfaces using FortiGate's packet sniffer or tcpdump. Look for the outbound SYN and check whether the return SYN-ACK arrives at all. If the outbound leg succeeds but the return is missing, asymmetric routing is the culprit.
diagnose sniffer packet any 'host 192.168.1.100 and host 203.0.113.5' 4 diagnose sniffer packet any 'host 192.168.1.50 and host 192.168.1.100' 4
Check the hairpin NAT rule configuration. Ensure it covers the correct source, destination, and interface pair. Verify that the rule is not limited to a single direction or interface.
show firewall vip show firewall ippool show firewall addrgrp
Enable logging on the NAT and firewall policies to see which rules are matching or being denied. Look for drops related to RPF or anti-spoofing.
set logtraffic all diagnose debug flow filter addr 192.168.1.100 diagnose debug flow show console enable diagnose debug flow trace start 100
If return traffic is arriving on a different interface than expected, adjust your routing policy or enable loose RPF mode (if security posture allows). Ensure that both WAN links have consistent metrics and that failover does not break the hairpin path symmetry.
Finally, confirm that the hairpin rule and any related IP pools or virtual IPs are applied to the correct interfaces and that no implicit deny rules block the return traffic. Test with a simple ping or curl from the internal client to the public IP and verify bidirectional flow.