Created on
02-27-2015
04:26 PM
Edited on
01-30-2023
10:38 AM
By
ksolovjova
Description
This article describes how to configure Hairpin NAT.
Hair-pinning also known as NAT loopback is a technique where a machine accesses another machine on the LAN or DMZ via an external network.
Traffic goes through LAN interface to the Internet, then goes back to the same interface,connecting to it is External IP. Traffic is then forwarded by Fortigate through virtual IP to local destination of LAN or DMZ
Scope
FortiGate
Solution
Article will describe how to configure Hairpin NAT depends on external IP. If external IP belongs to FortiGate (IP address of external interface), FortiGate will require different set of rules when the external IP is just from range, but not directly configured on FortiGate’s interfaces. In all examples, traffic will be flowing like this:
Client -> external IP -> FortiGate -> internal IP -> Server.
Example 1:
External IP is the same as the external interface and uses VIP1 from the diagram. In this example, doesn’t matter if extintf is any or wan.
# config firewall vip
edit "VIP1"
set extip 20.0.0.1
set extintf "any"
set portforward enable
set mappedip "172.16.1.2"
set extport 10443
set mappedport 10443
next
end
# config firewall vip
edit "VIP1"
set extip 20.0.0.1
set extintf "wan"
set portforward enable
set mappedip "172.16.1.2"
set extport 10443
set mappedport 10443
next
end
In both scenarios, extintf any or WAN, need to have two firewall policies. One to allow access from LAN to WANand second policy from WAN to DMZ.
# config firewall policy
edit 1
set name "AllLan1"
set srcintf "lan"
set dstintf "wan"
set srcaddr "all"
set dstaddr "all"
set action accept
set schedule "always"
set service "ALL"
set logtraffic all
set nat enable
next
edit 3
set name "VIP"
set srcintf "wan"
set dstintf "dmz"
set srcaddr "all"
set dstaddr "VIP1"
set action accept
set schedule "always"
set service "ALL"
set logtraffic all
next
end
Example 2:
The external IP address is from the same subnet but does not belong to FortiGate directly.
Use VIP2 from the diagram. There are two options to select extintf: any or specific.
Option 1:
# config firewall vip
edit "VIP2"
set extip 20.0.0.2
set extintf "any"
set portforward enable
set mappedip "172.16.1.2"
set extport 10443
set mappedport 10443
next
end
If the interface is any, there will be just one firewall policy from LAN to DMZ with VIP2 as the destination address.
# config firewall policy
edit 3
set name "VIP"
set srcintf "lan"
set dstintf "dmz"
set srcaddr "all"
set dstaddr "VIP2"
set action accept
set schedule "always"
set service "ALL"
set logtraffic all
next
end
Note:
If srcintf-filter to VIP2 is configured, LAN port will need to be a member of that filter.
In that case, the same firewall policy as the previous one will be enough.
If LAN will not be a member of the filter, but only WAN, hairpin will not work even if firewall policies are corrected when srcintf will be wan directly (next option).
Option 2:
With option 2, WAN as external interface.
There is a need to have same set of firewall policies as in Example 1. One to allow access from LAN to WAN and the second policy from wan to DMZ.
# config firewall vip
edit "VIP2"
set extip 20.0.0.2
set extintf "wan"
set portforward enable
set mappedip "172.16.1.2"
set extport 10443
set mappedport 10443
next
end
# config firewall policy
edit 3
set name "VIP"
set srcintf "wan"
set dstintf "dmz"
set srcaddr "all"
set dstaddr "VIP2"
set action accept
set schedule "always"
set service "ALL"
set logtraffic all
next
edit 1
set name "AllLan1"
set srcintf "lan"
set dstintf "wan"
set srcaddr "all"
set dstaddr "all"
set action accept
set schedule "always"
set service "ALL"
set logtraffic all
set nat enable
next
end
In all examples, hairpin traffic will never leave FortiGate.
Depending on the configuration, from debug flow it may look like traffic is coming from WAN after it is coming from LAN.
This debug flow is for Example 2, option 2 scenario:
2022-05-27 14:17:47 id=20085 trace_id=169 func=print_pkt_detail line=5664 msg="vd-root:0 received a packet(proto=6, 192.168.1.2:55940->20.0.0.2:10443) from lan. flag [S], seq 1916321154, ack 0, win 29200"
2022-05-27 14:17:47 id=20085 trace_id=169 func=init_ip_session_common line=5834 msg="allocate a new session-00001cab"
2022-05-27 14:17:47 id=20085 trace_id=169 func=iprope_dnat_check line=4880 msg="in-[lan], out-[]"
2022-05-27 14:17:47 id=20085 trace_id=169 func=get_new_addr line=1163 msg="find DNAT: IP-172.16.1.2, port-10443"
2022-05-27 14:17:47 id=20085 trace_id=169 func=iprope_fwd_check line=748 msg="in-[lan], out-[wan], skb_flags-02000000, vid-1, app_id: 0, url_cat_id: 0"
2022-05-27 14:17:48 id=20085 trace_id=169 func=get_new_addr line=1163 msg="find SNAT: IP-20.0.0.1(from IPPOOL), port-55940"
2022-05-27 14:17:48 id=20085 trace_id=169 func=fw_pre_route_handler line=181 msg="VIP-172.16.1.2:10443, outdev-unknown"
2022-05-27 14:17:48 id=20085 trace_id=169 func=__ip_session_run_tuple line=3427 msg="DNAT 20.0.0.2:10443->172.16.1.2:10443"
2022-05-27 14:17:48 id=20085 trace_id=169 func=vf_ip_route_input_common line=2581 msg="find a route: flag=04000000 gw-172.16.1.2 via dmz"
2022-05-27 14:17:48 id=20085 trace_id=169 func=iprope_fwd_check line=748 msg="in-[wan], out-[dmz], skb_flags-020000c0, vid-1, app_id: 0, url_cat_id: 0"
2022-05-27 14:17:48 id=20085 trace_id=169 func=fw_forward_handler line=777 msg="Allowed by Policy-3:"
Example 3:
Configuring Hairpin NAT when central NAT is enabled requires creating the corresponding VIP for NAT:
# config firewall vip
edit "VIP2"
set extip 20.0.0.2
set extintf "any"
set mappedip "172.16.1.2"
next
end
Port-forwarding can be added in the VIP configuration according to the setup.
An address object has to be created for the server in the DMZ - it will be used as a destination in the policy instead of VIP, unlike the setup without central NAT enabled:
# config firewall address
edit "server-VIP2"
set subnet 172.16.1.2 255.255.255.255
next
end
Next a firewall policy and a corresponding central NAT entry have to be configured:
# config firewall policy
edit 1
set name "VIP"
set srcintf "lan"
set dstintf "dmz"
set srcaddr "all"
set dstaddr "server-VIP2"
set action accept
set schedule "always"
set service "ALL"
next
end
# config firewall central-snat-map
edit 1
set srcintf "lan"
set dstintf "dmz"
set orig-addr "all"
set dstaddr "server-VIP2"
next
end
The NAT-ed session can be checked with the following command:
get sys session list | grep 20.0.0.2
PROTO EXPIRE SOURCE SOURCE-NAT DESTINATION DESTINATION-NAT
icmp 58 192.168.1.2:1 172.16.1.1:60723 20.0.0.2:8 172.16.1.2:1
Related Articles
Technical Tip: Firewall does not block incoming WAN to LAN
Technical Note: Using an auto hairpin to browse a webpage
Technical Tip: How to disable source NAT to enable a hairpin policy or one-arm firewa
The Fortinet Security Fabric brings together the concepts of convergence and consolidation to provide comprehensive cybersecurity protection for all users, devices, and applications and across all network edges.
Copyright 2023 Fortinet, Inc. All Rights Reserved.