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.
haljawhari
Staff
Staff
Article Id 192929

Description

 

This article describes how local-in policy behaves with ingressing ESP packets.

Solution

 

A local-in policy can be created to block ESP (protocol 50) packets, but this is not recommended as a main security practice as it eliminates SPI validation.
When FortiGate VPN events show logs similar to the one below, it indicates the packets are not dropped by the local-in policy.
When FortiGate receives an ESP packet, whether it’s UDP encapsulated or not, the IPSec handler checks whether the packet matches an existing SPI.
If it does not, it will drop the packet and generate the below log. By design, ESP packets checks happen before the local-in policy check.

 

Message meets Alert condition
date=2020-02-24 time=02:07:20 devname=TUNNEL-1 devid=FG1K5Dxxxxxxxxxx logid="0101037131" type="event" subtype="vpn" level="error" vd="root" eventtime=000000000 logdesc="IPsec ESP" msg="IPsec ESP" action="error" remip=208.85.5.74 locip=20.20.20.1 remport=6185 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="4f501234" seq="4f4e1234"


Explanation:

What happens with the observed log is that FortiGate is not checking incoming ESP packets against the local-in policies. Instead, the IPsec engine (IPsec handler) reports and drops received ESP packets. 

When FortiGate receives an ESP packet, it will always verify whether the received packet matches an existing SPI for the IPsec traffic. If the incoming ESP packet does not match an existing SPI, it is dropped by the IKE daemon by default.

 

There are two ways in which ESP packets are validated:

  1. FortiOS checks the local-in policy and blocks any IKE / UDP encapsulated ESP.
  2. The IPSec engine reports if a UDP encapsulated ESP packet without a matching SPI is received.

 

Action 2 takes precedence over action 1 since it existed before local-in policies, plus Action 2 comes first in the packet flow. This makes it so that this validation process only be modified in more recent versions.

The packet flow processing can be checked in Packet flow ingress and egress: FortiGates without network processor offloading and Packet flow: NP6 and NP6lite sessions.


This ESP validation behaviour can be changed starting on FortiOS 7.2.4, with the introduced detect-unknown-esp feature.

 

When detect-unknown-esp is enabled, the firewall detects the unknown ESP packets based on SPIs and the ike daemon drops them before the packet reaches the local-in-policy, generating the 'Received ESP packet with unknown SPI' VPN Event.

However, when it is disabled, FortiOS checks the local-in policy to block traffic instead. Disabling detect-unknown-esp will make FortiGate no longer check the SPI value against the SAs of existing tunnels.

In terms of packet processing, ESP checking (dealt by IPsec engine) comes before local-in policies. So, by disabling it, FortiGate will only validate packets against the local-in policy and will no longer check the SPI values. Note that this is not a good security practice.

 

  • detect-unknown-esp enabled (recommended):
    • Incoming IPsec traffic -> Check SPI against existing SAs (Alerts: 'Received ESP packet with unknown SPI.', if no match is found) -> Check local-in policy
      • SPI validation -> IP + ports validation.

  • detect-unknown-esp disabled (not recommended):
    • Incoming IPsec traffic -> Check local-in policy
      • IP + ports validation


It is recommended to leave 'detect-unknown-esp enable' to always check for the SPIs and keep the local-in policy as additional security.


In certain scenarios, it is desirable to not generate these logs.
To prevent these logs from being generated, follow Technical Tip: Prevent a log from being generated and filter for logid="0101037131".

 

The filter configuration should look like this:

 

config log memory filter

set severity information

set forward-traffic enable

set local-traffic enable

set multicast-traffic enable

set sniffer-traffic enable

set anomaly enable

set voip enable

set filter "logid(0101037131)"

set filter-type exclude

end

 

Related article:

Technical Tip: Filter ingress traffic going to the FortiGate using local-in-policy