Created on
03-18-2024
08:30 AM
Edited on
06-26-2025
09:49 PM
By
Jean-Philippe_P
This article describes the new anti-spoof IPsec VPN logic that was introduced in FortiOS v7.4.2. If proper conditions are not met, the traffic may be dropped as 'anti-spoof check failed, drop'.
FortiOS v7.4.2+.
By default, traffic arriving through the IPsec VPN tunnel must match a valid traffic selector negotiated in the phase2 configuration of the IPsec VPN.
Starting from FortiOS v7.4.2, if there is no match for the traffic, the traffic is dropped as a spoof.
Case 1:
Packet sniffer shows traffic arriving:
diagnose sniffer packet any " host 10.20.50.2 and icmp " 4 0 l
interfaces=[any]
filters=[ host 10.26.10.41 and icmp ]
2024-02-27 17:26:13.425459 TESTVPN in 10.10.50.2 -> 10.20.50.2: icmp: echo request
2024-02-27 17:26:14.443703 TESTVPN in 10.10.50.2 -> 10.20.50.2: icmp: echo request
2024-02-27 17:26:15.425146 TESTVPN in 10.10.50.2 -> 10.20.50.2: icmp: echo request
2024-02-27 17:26:16.435445 TESTVPN in 10.10.50.2 -> 10.20.50.2: icmp: echo request
2024-02-27 17:26:17.452851 TESTVPN in 10.10.50.2 -> 10.20.50.2: icmp: echo request
Debug flow shows the following output:
2024-02-27 17:45:40 id=65308 trace_id=1311 func=print_pkt_detail line=5888 msg="vd-root:0 received a packet(proto=1, 10.10.50.2:53450->10.20.50.2:2048) tun_id=123.123.123.123 from TESTVPN. type=8, code=0, id=53450, seq=0."
2024-02-27 17:45:40 id=65308 trace_id=1311 func=ipsec_input4 line=279 msg="anti-spoof check failed, drop"
Confirm negotiated phase2 settings with the command 'diagnose vpn tunnel list'.
proxyid_num=2 child_num=0 refcnt=5 ilast=0 olast=3 ad=/0
stat: rxp=80022 txp=395 rxb=14809443 txb=25814
dpd: mode=on-idle on=1 idle=20000ms retry=3 count=0 seqno=36
natt: mode=none draft=0 interval=0 remote_port=0
fec: egress=0 ingress=0
proxyid=TESTVPN proto=0 sa=1 ref=3 serial=13
src: 0:0.0.0.0-255.255.255.255:0
dst: 0:192.168.10.0-192.168.10.3:0
SA: ref=3 options=10025 type=00 soft=0 mtu=1446 expire=1733/0B replaywin=0
seqno=8 esn=0 replaywin_lastseq=00000000 qat=0 rekey=0 hash_search_len=1
life: type=01 bytes=0/0 timeout=1767/1800
dec: spi=36123e0e esp=3des key=24 d569b167770be97121e5b0a6545519b52c991f526864ec12
ah=sha1 key=20 f028a15a42b0dcdd26ffc77838b4851928c875ea
enc: spi=dd113712 esp=3des key=24 991b59099c3f8dd69576fa102e3c308997b544a62a3fc2b8
ah=sha1 key=20 3494b9d54e11e14486554b0f0ad70522586b065a
dec:pkts/bytes=1365/263845, enc:pkts/bytes=7/824
npu_flag=00 npu_rgwy=123.123.123.123 npu_lgwy=123.123.123.123 npu_selid=ff dec_npuid=0 enc_npuid=0
proxyid=TESTVPN proto=0 sa=0 ref=1 serial=14
The remote host '10.10.50.2' is not part of the negotiated traffic selectors for the VPN tunnel 'TESTVPN'. Traffic from 10.10.50.2 is dropped as a spoof.
Case 2:
Drop to reply.
Using:
Source IP: 10.180.244.217.
Destination IP: 10.190.9.27.
Sniffer shows 'request', and 'reply' to source and destination traffic.
So FortiGate is dropping or not processing incoming traffic.
diagnose sniffer packet any 'host 10.180.244.217 and host 10.190.9.27 and icmp' 4
interfaces=[any]
filters=[host 10.180.244.217 and host 10.190.9.27 and icmp]
6.892227 LAN_CORE in 10.180.244.217 -> 10.190.9.27: icmp: echo request
6.892254 AMA_CHRIS_GTD_2 out 10.180.244.217 -> 10.190.9.27: icmp: echo request
7.045048 AMA_CHRIS_GTD_2 in 10.190.9.27 -> 10.180.244.217: icmp: echo reply
11.643004 LAN_CORE in 10.180.244.217 -> 10.190.9.27: icmp: echo request
11.643013 AMA_CHRIS_GTD_2 out 10.180.244.217 -> 10.190.9.27: icmp: echo request
11.795494 AMA_CHRIS_GTD_2 in 10.190.9.27 -> 10.180.244.217: icmp: echo reply
16.794303 AMA_CHRIS_GTD_2 in 10.190.9.27 -> 10.180.244.217: icmp: echo reply
It is possible to see increasing RX errors.
VPN is sending and receiving packages.
But there are some RX errors.
get vpn ipsec tunnel summary | grep AMA_CHRIS_GTD_2
'AMA_CHRIS_GTD_2' 52.71.79.65:0 selectors(total,up): 4/3 rx(pkt,err): 484/484 tx(pkt,err): 601/2
get vpn ipsec tunnel summary | grep AMA_CHRIS_GTD_2
'AMA_CHRIS_GTD_2' 52.71.79.65:0 selectors(total,up): 4/3 rx(pkt,err): 818/818 tx(pkt,err): 904/2
diagnose debug flow filter addr 10.180.244.217 10.190.9.27 and
diagnose debug flow show function-name enable
diagnose debug flow show iprope enable
diagnose debug flow trace start 1000
diagnose debug enable
func=print_pkt_detail line=6005 msg="vd-root:0 received a packet(proto=1, 10.180.244.217:1->10.190.9.27:2048) tun_id=0.0.0.0 from LAN_CORE. type=8, code=0, id=1, seq=18979."
func=init_ip_session_common line=6204 msg="allocate a new session-16eab499"
func=iprope_dnat_check line=5481 msg="in-[LAN_CORE], out-[]"
func=iprope_dnat_tree_check line=824 msg="len=0"
func=iprope_dnat_check line=5506 msg="result: skb_flags-02000000, vid-0, ret-no-match, act-accept, flag-00000000"
func=__vf_ip_route_input_rcu line=1989 msg="find a route: flag=00000000 gw-52.71.79.65 via AMA_CHRIS_GTD_2"
func=__iprope_fwd_check line=810 msg="in-[LAN_CORE], out-[AMA_CHRIS_GTD_2], skb_flags-02000000, vid-0, app_id: 0, url_cat_id: 0"
func=__iprope_tree_check line=524 msg="gnum-100004, use int hash, slot=4, len=10"
func=__iprope_user_identity_check line=1903 msg="ret-matched"
func=__iprope_check line=2404 msg="gnum-4e20, check-ffffffffa002cf60"
func=__iprope_check line=2421 msg="gnum-4e20 check result: ret-no-match, act-accept, flag-00000000, flag2-00000000"
func=__iprope_check_one_policy line=2374 msg="policy-1218 is matched, act-accept"
func=__iprope_fwd_check line=847 msg="after iprope_captive_check(): is_captive-0, ret-matched, act-accept, idx-1218"
func=iprope_fwd_auth_check line=876 msg="after iprope_captive_check(): is_captive-0, ret-matched, act-accept, idx-1218"
func=iprope_shaping_check line=974 msg="in-[LAN_CORE], out-[AMA_CHRIS_GTD_2], skb_flags-02000000, vid-0"
func=__iprope_check line=2404 msg="gnum-100015, check-ffffffffa002c2f0"
func=__iprope_check line=2421 msg="gnum-100015 check result: ret-no-match, act-accept, flag-00000000, flag2-00000000"
func=iprope_policy_group_check line=4903 msg="after check: ret-no-match, act-accept, flag-00000000, flag2-00000000"
func=fw_forward_handler line=1002 msg="Allowed by Policy-1218:"
func=ip_session_confirm_final line=3179 msg="npu_state=0x40000, hook=4"
func=ipsecdev_hard_start_xmit line=662 msg="enter IPSec interface AMA_CHRIS_GTD_2, tun_id=0.0.0.0"
func=_do_ipsecdev_hard_start_xmit line=222 msg="output to IPSec tunnel AMA_CHRIS_GTD_2, tun_id=52.71.79.65, vrf 0"
func=esp_output4 line=917 msg="IPsec encrypt/auth"
func=nipsec_set_ipsec_sa_enc line=934 msg="Trying to offload IPsec encrypt SA (p1/p2/spi={AMA_CHRIS_GTD_2/AMA_CHRIS_GTD_2_6/0xc47154a0}), npudev=1,
skb-dev=INTERNET_GTD"
func=ipsec_output_finish line=676 msg="send to 190.153.209.145 via intf-INTERNET_GTD"
id=65308 trace_id=102 func=print_pkt_detail line=6005 msg="vd-root:0 received a packet(proto=1, 10.190.9.27:1->10.180.244.217:0) tun_id=52.71.79.65 from AMA_CHRIS_GTD_2.
type=0, code=0, id=1, seq=18979."
id=65308 trace_id=102 func=resolve_ip_tuple_fast line=6107 msg="Find an existing session, id-16eab499, reply direction"
id=65308 trace_id=102 func=ipsec_spoofed4 line=243 msg="src ip 10.190.9.27 mismatch selector 0 range 10.155.0.0-10.155.255.255"
id=65308 trace_id=102 func=ipsec_input4 line=287 msg="anti-spoof check failed, drop"
Error:
id=65308 trace_id=102 func=ipsec_spoofed4 line=243 msg="src ip 10.190.9.27 mismatch selector 0 range 10.155.0.0-10.155.255.255"
id=65308 trace_id=102 func=ipsec_input4 line=287 msg="anti-spoof check failed, drop"
Conclusion:
Error: msg="anti-spoof check failed, drop"
Solution:
Configure selectors to: 0.0.0.0/0, or to address this problem, both VPN gateways must agree on proper traffic selectors for the expected traffic through the tunnel.
Related documents:
How to run a debug flow
Troubleshooting Tip: FortiOS to AWS VPN Anti-Spoofing issue
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 2025 Fortinet, Inc. All Rights Reserved.