阻止异常 IKE/ESP 报文
阻止异常 IKE/ESP 报文
公网接口经常会收到来自互联网的 IPSec 连接探测或恶意 IKE 报文。可以使用 Local-in Policy 拒绝非可信来源访问 FortiGate 的 IKE 服务,降低恶意方尝试建立 IPSec 隧道并访问内部网络的风险。
无效 ESP 报文的处理路径与 IKE 报文不同:FortiOS 的 IPSec 本地入站处理模块会根据现有隧道的安全关联(SA)检查 SPI,并自动阻止 SPI 不匹配的 ESP 报文。
重要
IPSec 本地入站处理模块会在防火墙本地入站处理模块之前处理 ESP 报文。因此,无效 ESP 报文不会由本文配置的 Local-in Policy 静默丢弃,而会在 VPN 日志中记录速率受限的 unknown SPI 消息。
未知 ESP 报文检测
未知 ESP 报文检测默认开启。收到 SPI 与现有 SA 不匹配的 ESP 报文时,FortiGate 会阻止该报文并生成 VPN 事件日志,示例日志:
date=2026-07-15 time=14:36:27 devname=FGT-BRANCH01 devid=FGT101FXXXXXXXXXX logid="0101037131" type="event" subtype="vpn" level="error" vd="root" eventtime=1784097387583214700 tz="+0800" logdesc="IPsec ESP" msg="IPsec ESP" action="error" remip=203.0.113.86 locip=198.51.100.20 remport=51284 locport=500 outintf="wan1" cookies="N/A" user="N/A" group="N/A" xauthuser="N/A" xauthgroup="N/A" assignip=N/A vpntunnel="N/A" status="esp_error" error_num="Received ESP packet with unknown SPI." spi="9a73bc4e" seq="0000002d"可以通过 detect-unknown-esp 控制未知 ESP 报文检测:
config system settings
set detect-unknown-esp {enable | disable}
end重要
SPI 不匹配不一定表示恶意攻击。例如,隧道重协商期间 SPI 暂时不匹配,或者一端清除了隧道 SA,都可能产生 unknown SPI 日志。判断攻击前,应结合对端状态、重协商时间和相关 VPN 日志收集完整证据。
配置步骤
配置一个排除可信 VPN 对端的地址组。以下示例假设可信对端地址对象
trusted-vpn-peer已经存在,地址组最终匹配除该对象以外的所有源地址。config firewall addrgrp edit "untrusted-ike-sources" set member "all" set exclude enable set exclude-member "trusted-vpn-peer" next end创建 Local-in Policy,拒绝该地址组从
wan1访问 FortiGate 的 IKE 服务。config firewall local-in-policy edit 1 set intf "wan1" set srcaddr "untrusted-ike-sources" set dstaddr "all" set service "IKE" set schedule "always" next end相关信息
Local-in Policy 条目的默认动作为
deny。有关 Local-in Policy 的完整配置方式,请参考策略与对象 → 本地流量策略 → Local-in 策略。
结果验证
使用 Debug Flow 过滤 UDP 500,确认流量被 Local-in Policy ID 1 丢弃。参考输出:
diagnose debug flow filter dport 500 diagnose debug flow trace start 10 diagnose debug enable id=65308 trace_id=47 func=print_pkt_detail line=5888 msg="vd-root:0 received a packet(proto=17, 203.0.113.86:500->198.51.100.20:500) from wan1. " id=65308 trace_id=47 func=init_ip_session_common line=6073 msg="allocate a new session-0007ac31" id=65308 trace_id=47 func=__vf_ip_route_input_rcu line=1999 msg="find a route: flag=80000000 gw-198.51.100.20 via root" id=65308 trace_id=47 func=fw_local_in_handler line=618 msg="iprope_in_check() check failed on policy 1, drop"