FortiGate
FortiGate Next Generation Firewall utilizes purpose-built security processors and threat intelligence security services from FortiGuard labs to deliver top-rated protection and high performance, including encrypted traffic.
vdralio
Staff
Staff

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

 


hairpin_diag.png

 


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:"

 

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