Skip to main content
jdoyon
Visitor III
September 7, 2023
Question

Problem with Virtual Server and Policy Route: reverse path check fail, drop

  • September 7, 2023
  • 3 replies
  • 12261 views

Hello!

 

Hoping someone might have some insight into this, because I'm stumped ...

 

Setup:

 

- 2 paths to the internet, via "port1" and down a VPN Tunnel.

- Default route is port1

- 3 Virtual Servers attached to port1

- Policy routes decide where to send outbound packets, port1 or tunnel.

 

All is working well until ...

 

If I change the default route to the tunnel instead of port1, the Virtual Servers stop working, even though I have policy routes that specifically force the outbound traffic for those virtual servers to port1, which is where the traffic comes in for them (always).

 

Everything else adapts pretty well ... just not the virtual servers.

 

When I look I see that traffic incoming to the virtual servers on port1 gets dropped with "reverse path check fail, drop". It doesn't find a path back ... even though there is a policy route?

 

Working incoming session:

 

Packet Trace #2772023-09-07 11:21vd-root:0 received a packet(proto=6, 40.83.2.68:24801->10.1.9.7:443) tun_id=0.0.0.0 from port1. flag [S], seq 4182754383, ack 0, win 64240
Packet Trace #2772023-09-07 11:21allocate a new session-011f89f8, tun_id=0.0.0.0
Packet Trace #2772023-09-07 11:21in-[port1], out-[]
Packet Trace #2772023-09-07 11:21len=1
Packet Trace #2772023-09-07 11:21checking gnum-100000 policy-3
Packet Trace #2772023-09-07 11:21match vip-Public Web Site Virtual Server - HTTPS, naddr=10.1.13.7, nport=80
Packet Trace #2772023-09-07 11:21matched policy-3, act=accept, vip=3, flag=100, sflag=2000400
Packet Trace #2772023-09-07 11:21result: skb_flags-02000400, vid-3, ret-matched, act-accept, flag-00000100
Packet Trace #2772023-09-07 11:21VIP-10.1.13.7:80, outdev-port1
Packet Trace #2772023-09-07 11:21DNAT 10.1.9.7:443->10.1.13.7:80
Packet Trace #2772023-09-07 11:21find a route: flag=00000000 gw-10.1.11.1 via port2
Packet Trace #2772023-09-07 11:21in-[port1], out-[port2], skb_flags-020004c0, vid-3, app_id: 0, url_cat_id: 0
Packet Trace #2772023-09-07 11:21gnum-100004, use int hash, slot=28, len=5
Packet Trace #2772023-09-07 11:21checked gnum-100004 policy-42, ret-no-match, act-accept
Packet Trace #2772023-09-07 11:21checked gnum-100004 policy-48, ret-no-match, act-accept
Packet Trace #2772023-09-07 11:21checked gnum-100004 policy-48, ret-matched, act-accept
Packet Trace #2772023-09-07 11:21ret-matched
Packet Trace #2772023-09-07 11:21gnum-4e26, check-0000000080c870ab
Packet Trace #2772023-09-07 11:21checked gnum-4e26 policy-4294967295, ret-no-match, act-accept
Packet Trace #2772023-09-07 11:21checked gnum-4e26 policy-9, ret-matched, act-accept
Packet Trace #2772023-09-07 11:21policy-9 is matched, act-accept
Packet Trace #2772023-09-07 11:21gnum-4e26 check result: ret-matched, act-accept, flag-00a02008, flag2-00000000
Packet Trace #2772023-09-07 11:21policy-48 is matched, act-accept
Packet Trace #2772023-09-07 11:21after iprope_captive_check(): is_captive-0, ret-matched, act-accept, idx-48
Packet Trace #2772023-09-07 11:21after iprope_captive_check(): is_captive-0, ret-matched, act-accept, idx-48
Packet Trace #2772023-09-07 11:21Allowed by Policy-48: AV
Packet Trace #2772023-09-07 11:21npu_state=0x1100, hook=4
Packet Trace #2772023-09-07 11:21send to ips
Packet Trace #2772023-09-07 11:21send to application layer

 

When I change the default route:

 

10:18:45
vd-root:0 received a packet(proto=6, 36.75.221.151:51442->10.1.9.7:443) tun_id=0.0.0.0 from port1. flag [S], seq 3117427467, ack 0, win 64240
10:18:45
allocate a new session-011e0cf6, tun_id=0.0.0.0
10:18:45
in-[port1], out-[]
10:18:45
len=1
10:18:45
checking gnum-100000 policy-3
10:18:45
match vip-Public Web Site Virtual Server - HTTPS, naddr=10.1.13.7, nport=80
10:18:45
matched policy-3, act=accept, vip=3, flag=100, sflag=2000400
10:18:45
result: skb_flags-02000400, vid-3, ret-matched, act-accept, flag-00000100
10:18:45
VIP-10.1.13.7:80, outdev-port1
10:18:45
DNAT 10.1.9.7:443->10.1.13.7:80
10:18:45
reverse path check fail, drop
10:18:45
trace

 

Policy route that should work I'm pretty sure ... :

 

config router policy
edit 13
set input-device "port2"
set src "10.1.13.7/255.255.255.255" "10.1.13.5/255.255.255.255" "10.1.13.6/255.255.255.255" "10.1.13.8/255.255.255.255"
set dstaddr "Internet"
set gateway 10.1.9.1
set output-device "port1"
next
end

 

10.1.9.7 is the Virtual Server IP, 10.1.13.7 is the backend server IP.

 

Are policy routes not used to check return path??

 

Thanks!

3 replies

saneeshpv_FTNT
Staff
Staff
September 8, 2023

Hi @jdoyon ,

 

The answer to your problem is

 

"If no routes are found in the routing table, then the policy route does not match the packet. The FortiGate continues down the policy route list until it reaches the end. If no matches are found, then the FortiGate does a route lookup using the routing table."

 

So you need a route in routing table for Policy route to work, but this route need not be the best route. So you can have two default route and the one using tunnel with Higher Preference (Low Priority Value and same distance) and the one using port1 with Lower preference (high Priority and same distance as other default route).

 

https://docs.fortinet.com/document/fortigate/7.4.1/administration-guide/144044/policy-routes#:~:text=If%20no%20routes%20are%20found,lookup%20using%20the%20routing%20table.

 

Best Regards,

San

jdoyon
jdoyonAuthor
Visitor III
September 8, 2023

Bu there are static routes, 2 of relevance here, they are:

 

1 static default route, goes out port1, priority 10.

1 static default route, goes down the tunnel, priority 1.

 

When the tunnel route is disabled, all is well. When I enable the tunnel route, the above mentioned problem occurs, and suddenly there's no return path ... even though there's a policy route that says there should be (Said policy route has data flow through it when using the port1 default route, so that's a good sign it "works"?).

saneeshpv_FTNT
Staff
Staff
September 8, 2023

Hi @jdoyon 

 

As per the logs traffic is failing due to reverse path check fail, which means when the Firewall check for a route back to the source 40.83.2.68 via Port1, it doesn't find a route in the Kernel routing table and policy route will not be considered here as it only look at the routing table and moreover your Policy criteria say input interface is Port2 where here traffic in entering on Port1. Policy route will be effective in the outbound traffic scenarios based on the criteria you defined.  

 

If you don't mind could you please provide below information with and without tunnel disabled, because I strongly doubt there is no route in the Routing table for destination 40.83.2.68 when tunnel is enabled. 

 

get router info routing-table all

get router info kernel

 

Best Regards,

 

akristof
Staff
Staff
September 11, 2023

Hi.

Maybe I've missed something. But if you have default route via port1, everything is working as expected. But if you remove default route (port1) and keeps default via VPN and you add policy route (input port2, output port1, ...) then it is not working? You expect that the policy route will be used for RPF check?

jdoyon
jdoyonAuthor
Visitor III
September 11, 2023

It is not clear form the docs whether policy routes are looked at for RPF from the docs IIRC (but i could be wrong). From what was said above, static / kernel routes have to match first on RPF check? In which case, the port1 route, which is still there, but at lower priority than the tunnel, should still be found when RPF is not "strict", but that does not seem to happen. If at least that worked, the RPF would "pass", and when the traffic ACTUALLY returns, the policy route would apply ... ?

 

Funny side note: I could've sworn I was at 7.4.1 ... now it says 7.2.5 ... and apparently there was a VM "crash' or something last night ... hummm ...