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.
nithincs
Staff & Editor
Staff & Editor
Article Id 385202
Description This article explains the working of the DPD mechanism set to 'on-demand'.
Scope FortiGate.
Solution

When DPD is set to on-demand, this will notify FortiGate to send DPD message to check the liveliness of the remote VPN peer only when the VPN tunnel does not receive any ESP packets from the remote VPN peer for a specific amount of time (dpd-retryinterval). 

If the VPN tunnel did not receive the DPD R-U-THERE ack from the remote VPN peer for a specific number of seconds (dpd-retrycount * dpd-retryinterval), FortiGate will understand the remote peer is not active and bring down the tunnel.

 

On-demand will eliminate the regular DPD check and only get triggered when there is no response; the decrypt packet count is not incrementing for DPD retryinterval time.

 

For example:

PC---HO FGT (Tunnel name: SPOKE)---IPSEC tunnel---SPOKE FGT ---SERVER

 

VPN Tunnel SPOKE is up, and test ICMP traffic is initiated from a client behind HO. However, there is no response from the destination. So in HO FortiGate, one-way communication is happening via the tunnel, which results in only egress of ESP packets from HO to Spoke (tunnel ENC count gets incremented), and there is no ingress of ESP packets from SPOKE to HO (DEC count is stagnant).

 

  • The below output shows the enc and dec count when phase 2 came up.
  • DPD is set to on-demand, and it is seqno=54. Seqno increases when FortiGate performs the DPD probe.

 

FGT1_HO_TLP # diagnose vpn tunnel list
list all ipsec tunnel in vd 0
------------------------------------------------------
name=SPOKE ver=1 serial=2 10.40.51.6:0->10.40.19.18:0 nexthop=10.40.51.41 tun_id=10.40.19.18 tun_id6=::10.40.19.18 status=up dst_mtu=1500 weight=1
bound_if=4 real_if=4 lgwy=static/1 tun=intf mode=auto/1 encap=none/552 options[0228]=npu frag-rfc run_state=0 role=primary accept_traffic=1 overlay_id=0

proxyid_num=1 child_num=0 refcnt=4 ilast=113 olast=113 ad=/0
stat: rxp=0 txp=0 rxb=0 txb=0
dpd: mode=on-demand on=1 status=ok idle=20000ms retry=3 count=0 seqno=54
natt: mode=none draft=0 interval=0 remote_port=0
fec: egress=0 ingress=0
proxyid=SPOKE proto=0 sa=1 ref=2 serial=5 auto-negotiate
src: 0:172.31.196.0-172.31.196.255:0
dst: 0:172.31.131.0-172.31.131.255:0
SA: ref=3 options=38203 type=00 soft=0 mtu=1438 expire=1765/0B replaywin=2048
seqno=1 esn=0 replaywin_lastseq=00000000 qat=0 rekey=0 hash_search_len=1
life: type=01 bytes=0/0 timeout=1773/1800
dec: spi=19fb7ee9 esp=aes key=16 a3c1a15dfde7e76a78f6605401ade6f9
ah=sha256 key=32 52be712344033a35511516763cadc7a6052381a3df7561e7173cd548c32bf982
enc: spi=8763525a esp=aes key=16 d4546f24c0aa519e1824673e06abecb1
ah=sha256 key=32 948cbca32078b38ee34e9a0b68674f38b4c23c725848b42917e5c881998a6af7
dec:pkts/bytes=0/0, enc:pkts/bytes=0/0
npu_flag=00 npu_rgwy=10.40.19.18 npu_lgwy=10.40.51.6 npu_selid=4 dec_npuid=0 enc_npuid=0

 

ICMP communication is initiated, which results in an increment in enc count; the dec count stays 0 since the ICMP response is blocked at the remote site.

 

name=SPOKE ver=1 serial=2 10.40.51.6:0->10.40.19.18:0 nexthop=10.40.51.41 tun_id=10.40.19.18 tun_id6=::10.40.19.18 status=up dst_mtu=1500 weight=1
bound_if=4 real_if=4 lgwy=static/1 tun=intf mode=auto/1 encap=none/552 options[0228]=npu frag-rfc run_state=0 role=primary accept_traffic=1 overlay_id=0

proxyid_num=1 child_num=0 refcnt=4 ilast=0 olast=0 ad=/0
stat: rxp=0 txp=2 rxb=0 txb=120
dpd: mode=on-demand on=1 status=ok idle=20000ms retry=3 count=0 seqno=54
.
.
dec:pkts/bytes=0/0, enc:pkts/bytes=2/248
npu_flag=00 npu_rgwy=10.40.19.18 npu_lgwy=10.40.51.6 npu_selid=4 dec_npuid=0 enc_npuid=0

------------------------------------------------------
name=SPOKE ver=1 serial=2 10.40.51.6:0->10.40.19.18:0 nexthop=10.40.51.41 tun_id=10.40.19.18 tun_id6=::10.40.19.18 status=up dst_mtu=1500 weight=1
bound_if=4 real_if=4 lgwy=static/1 tun=intf mode=auto/1 encap=none/552 options[0228]=npu frag-rfc run_state=0 role=primary accept_traffic=1 overlay_id=0

proxyid_num=1 child_num=0 refcnt=4 ilast=32 olast=0 ad=/0
stat: rxp=0 txp=9 rxb=0 txb=540
dpd: mode=on-demand on=1 status=ok idle=20000ms retry=3 count=0 seqno=54
.
.
dec:pkts/bytes=0/0, enc:pkts/bytes=9/1116 >>>> (9 packets are sent but there is no return traffic.)
npu_flag=00 npu_rgwy=10.40.19.18 npu_lgwy=10.40.51.6 npu_selid=4 dec_npuid=0 enc_npuid=0

 

As there is no ingress traffic through the VPN tunnel for the DPD retry interval, the DPD probe will get triggered.

 

FGT1_HO_TLP # diagnose vpn tunnel list2025-03-27 03:25:33.214797 ike V=root:0:SPOKE: link is idle 4 10.40.51.6->10.40.19.18:0 dpd=2 seqno=55 rr=0
2025-03-27 03:25:33.216419 ike V=root:0:SPOKE:164: send IKEv1 DPD probe, seqno 55
2025-03-27 03:25:33.217624 ike 0:SPOKE:164: enc
2025-03-27 03:25:33.220155 ike 0:SPOKE:164: out
2025-03-27 03:25:33.222931 ike V=root:0:SPOKE:164: sent IKE msg (R-U-THERE): 10.40.51.6:500->10.40.19.18:500, len=108, vrf=0, id=a68b80504abf95f9/9f10db795a942608:f4ef
5332
2025-03-27 03:25:33.224822 ike V=root:0: comes 10.40.19.18:500->10.40.51.6:500,ifindex=4,vrf=0,len=108....
2025-03-27 03:25:33.226005 ike V=root:0: IKEv1 exchange=Informational id=a68b80504abf95f9/9f10db795a942608:6ce4ab90 len=108 vrf=0
2025-03-27 03:25:33.227375 ike 0: in 3
2025-03-27 03:25:33.230060 ike 0:SPOKE:164: dec
2025-03-27 03:25:33.232839 ike V=root:0:SPOKE:164: notify msg received: R-U-THERE-ACK

 

FortiGate receives a DPD notify msg response from a remote VPN peer so Tunnel will stay up and working. If there is no response for a number of dpd-retrycount attempts, the tunnel will go down due to DPD failure.

 

In this example, DPD notified by the initiator is getting a response; this confirms the tunnel is up and stable, but communication is not successful due to some reason.

 

Once there is an ingress ESP packet matching phase 2 received within the dpd-retryinterval, DPD on demand will not get triggered.

 

Related articles: