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.
lbruno
Staff
Staff
Article Id 198479

Description
This article describes a particularity of Virtual Wire Pairs when traffic going through a VWP wants to go back into the same FortiGate via a non-VWP interface.

Solution
Imagine a scenario where a user has a normal LAN to Internet NATed access and at the same time has a second public IP address assigned to a Server that also needs firewall protection.
It is possible to try to accomplish this with the following scenario:



 
 
Technically it is possible to configure FortiGate in this way without any errors but although the access from the LAN to the Internet will work without any problems, the access from the LAN to the public IP address won't be possible.
 
In a FortiGate environment, several criteria is used to identify sessions, including VDOM, source IP + port, destination IP + port, etc.
 
The Virtual Wire Pair connects two interfaces as a transparent mode in a NAT mode environment.
So when in the same VDOM, the traffic goes through a Virtual Wire Pair and back into another interface (non-VWP), the FortiGate will not be able to understand if it should deal with it as transparent or NAT mode:
 
In the above scenario, this is what you would see if you tried to reach the Public IP address behind FortiGate (in this example we used 192.168.x.x to simulate public addresses - 192.168.0.3 is the IP address inside the Virtual Wire Pair):
348.962579 port2 (LAN PORT) in 172.16.0.2 -> 192.168.0.3: icmp: echo request
348.981858 port4 (INTERNET) out 192.168.0.1 -> 192.168.0.3: icmp: echo request
348.982101 port5 (VIRTUAL WIRE OUTSIDE PORT) in 192.168.0.1 -> 192.168.0.3: icmp: echo request
348.982139 port3 (VIRTUAL WIRE INSIDE PORT) out 192.168.0.1 -> 192.168.0.3: icmp: echo request
348.983057 port3 (VIRTUAL WIRE INSIDE PORT) in 192.168.0.3 -> 192.168.0.1: icmp: echo reply
348.983062 port5 (VIRTUAL WIRE OUTSIDE PORT) out 192.168.0.3 -> 192.168.0.1: icmp: echo reply
348.983299 port4 (INTERNET) in 192.168.0.3 -> 192.168.0.1: icmp: echo reply
***** Traffic stops here without being forwarded to the host on port2 (LAN)*****
 
In the flow trace you can see that everything seems to be working as expected with NAT being applied:
id=20085 trace_id=1 func=print_pkt_detail line=5320 msg="vd-root:0 received a packet(proto=1, 172.16.0.2:104->192.168.0.3:2048) from port2. type=8, code=0, id=104, seq=1."
id=20085 trace_id=1 func=init_ip_session_common line=5480 msg="allocate a new session-00000167"
id=20085 trace_id=1 func=vf_ip_route_input_common line=2590 msg="find a route: flag=04000000 gw-192.168.0.3 via port4"
id=20085 trace_id=1 func=fw_forward_handler line=749 msg="Allowed by Policy-1: SNAT"         <----- SNAT policy.
id=20085 trace_id=1 func=__ip_session_run_tuple line=3226 msg="SNAT 172.16.0.2->192.168.0.1:60520"
id=20085 trace_id=2 func=print_pkt_detail line=5320 msg="vd-root:0 received a packet(proto=1, 192.168.0.1:60520->192.168.0.3:2048) from port5. type=8, code=0, id=60520, seq=1."
id=20085 trace_id=2 func=init_ip_session_common line=5480 msg="allocate a new session-00000168"
id=20085 trace_id=2 func=br_fw_forward_handler line=539 msg="Allowed by Policy-2:"           <----- Virtual Wire Policy.
id=20085 trace_id=2 func=__if_queue_push_xmit line=388 msg="send out via dev-port3, dst-mac-02:09:6f:08:04:01"
So the only way to make this scenario work is to logically separate the traffic into two logical entities (VDOMs):
 
 
 
 
5.392380 port2 (LAN PORT) in 172.16.0.2 -> 192.168.0.3: icmp: echo request
5.392464 port4 (INTERNET) out 192.168.0.1 -> 192.168.0.3: icmp: echo request
5.392888 port5 (VIRTUAL WIRE OUTSIDE PORT) in 192.168.0.1 -> 192.168.0.3: icmp: echo request
5.392919 port3 (VIRTUAL WIRE INSIDE PORT) out 192.168.0.1 -> 192.168.0.3: icmp: echo request
5.394303 port3 (VIRTUAL WIRE INSIDE PORT) in 192.168.0.3 -> 192.168.0.1: icmp: echo reply
5.394320 port5 (VIRTUAL WIRE OUTSIDE PORT) out 192.168.0.3 -> 192.168.0.1: icmp: echo reply
5.394592 port4 (INTERNET) in 192.168.0.3 -> 192.168.0.1: icmp: echo reply
5.394615 port2 (LAN PORT) out 192.168.0.3 -> 172.16.0.2: icmp: echo reply
 
***** Traffic is now correctly delivered to port2 (LAN)*****
 
The flow trace however is quite similar:

 
id=20085 trace_id=1 func=print_pkt_detail line=5320 msg="vd-root:0 received a packet(proto=1, 172.16.0.2:128->192.168.0.3:2048) from port2. type=8, code=0, id=128, seq=1."
id=20085 trace_id=1 func=init_ip_session_common line=5480 msg="allocate a new session-0000108b"
id=20085 trace_id=1 func=vf_ip_route_input_common line=2590 msg="find a route: flag=04000000 gw-192.168.0.3 via port4"
id=20085 trace_id=1 func=fw_forward_handler line=749 msg="Allowed by Policy-1: SNAT"             <----- SNAT policy.
id=20085 trace_id=1 func=__ip_session_run_tuple line=3226 msg="SNAT 172.16.0.2->192.168.0.1:60544"
id=20085 trace_id=2 func=print_pkt_detail line=5320 msg="vd-Virtual:0 received a packet(proto=1, 192.168.0.1:60544->192.168.0.3:2048) from port5. type=8, code=0, id=60544, seq=1."
id=20085 trace_id=2 func=init_ip_session_common line=5480 msg="allocate a new session-0000108c"
id=20085 trace_id=2 func=br_fw_forward_handler line=539 msg="Allowed by Policy-2:"               <----- Virtual Wire Policy.                                  
id=20085 trace_id=2 func=__if_queue_push_xmit line=388 msg="send out via dev-port3, dst-mac-02:09:6f:08:04:01"

 

Contributors