Technical Tip: Configuring Hairpin NAT (VIP) in policy route
Description
This article describes how to configure FortiGate for Hairpin NAT for the internal network to access the VIP when the policy route is configured over a different VIP external interface.
Scope
FortiGate.
Diagram.

Interface Configuration:
config system interface
edit "port2"
set vdom "root"
set ip 192.168.1.1 255.255.255.0
set allowaccess ping
set type physical
set alias "wan1"
set snmp-index 2
next
end
Fw1 # show system interface port3
config system interface
edit "port3"
set vdom "root"
set ip 192.168.2.1 255.255.255.0
set allowaccess ping
set type physical
set alias "wan2"
set snmp-index 3
next
end
Fw1 # show system interface port4
config system interface
edit "port4"
set vdom "root"
set ip 10.0.0.1 255.255.255.0
set allowaccess ping
set type physical
set snmp-index 4
next
end
Fw1 # show system interface port5
config system interface
edit "port5"
set vdom "root"
set ip 172.16.0.1 255.255.255.0
set allowaccess ping
set type physical
set snmp-index 5
next
end
edit 1
set input-device "port4"
set src "10.0.0.0/255.255.255.0"
set dstaddr "all"
set gateway 192.168.2.2
set output-device "port3"
next
end
config firewall policy
edit 1
set name "vip"
set uuid d7b467a8-cec5-51eb-5f31-55cc9964d349
set srcintf "port2"
set dstintf "port5"
set srcaddr "all"
set dstaddr "Test-VIP"
set action accept
set schedule "always"
set service "HTTP"
set inspection-mode proxy
next
id=20085 trace_id=1 func=init_ip_session_common line=5871 msg="allocate a new session-00000860"
id=20085 trace_id=1 func=fw_pre_route_handler line=182 msg="VIP-172.16.0.2:80, outdev-unknown"
id=20085 trace_id=1 func=__ip_session_run_tuple line=3492 msg="DNAT 192.168.1.100:80->172.16.0.2:80"
id=20085 trace_id=1 func=vf_ip_route_input_common line=2566 msg="Match policy routing id=1: to 192.168.2.2 via ifindex-5"
id=20085 trace_id=1 func=vf_ip_route_input_common line=2584 msg="find a route: flag=04000000 gw-192.168.2.2 via port3"
id=20085 trace_id=1 func=fw_forward_handler line=640 msg="Denied by forward policy check (policy 0)"
id=20085 trace_id=2 func=print_pkt_detail line=5700 msg="vd-root:0 received a packet(proto=6, 10.0.0.2:54494->192.168.1.100:80) from port4. flag [S], seq 324277149, ack 0, win 64240"
Solution
STOP the policy route from the LAN to the Real server.
Fw1 # show router policy
config router policy
edit 2
set input-device "port4"
set srcaddr "Lan_10.0.0.0_24"
set dst "172.16.0.2/255.255.255.255"
set action deny
set status enable
next
id=20085 trace_id=6 func=print_pkt_detail line=5700 msg="vd-root:0 received a packet(proto=6, 10.0.0.2:54495->192.168.1.100:80) from port4. flag [S], seq 4123342479, ack 0, win 64240"
id=20085 trace_id=6 func=init_ip_session_common line=5871 msg="allocate a new session-0000096a"
id=20085 trace_id=6 func=fw_pre_route_handler line=182 msg="VIP-172.16.0.2:80, outdev-unknown"
id=20085 trace_id=6 func=__ip_session_run_tuple line=3492 msg="DNAT 192.168.1.100:80->172.16.0.2:80"
id=20085 trace_id=6 func=vf_ip_route_input_common line=2584 msg="find a route: flag=04000000 gw-172.16.0.2 via port5"
id=20085 trace_id=6 func=fw_forward_handler line=796 msg="Allowed by Policy-1:"
id=20085 trace_id=6 func=ipd_post_route_handler line=490 msg="out port5 vwl_zone_id 0, state2 0x0, quality 0.
All the traffic from the LAN 10.0.0.0/24 routed over the WAN2 as per policy route except the VIP(192.168.1.100).
Related article:
