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.
xshkurti
Staff
Staff
Article Id 354097
Description

This article describes the process of troubleshooting traffic flow when an IPPool is configured under the firewall policy for IPsec tunnel traffic.

Scope FortiGate all versions.
Solution

In common situations, when an IPsec VPN is created from templates, internal subnets from both ends of the tunnel are selected as phase2 encrypted subnets. Those subnets are expected to traverse through the tunnel in end-to-end communication.

When third parties are involved in a site-to-site, it is sometimes required to hide a real IP from being exposed, so NAT is involved. The change will require implementing NAT through the use of IPPools.

When an IPPool is implemented, traffic does work in most cases and is dropped by FortiGate.

 

See the following diagram for an example of the steps to troubleshoot and fix this issue.

 

S2S Tunnel.png

 

Initial configurations on both devices:

 

 

  1. FGT1 primary site configuration:

 

 

 

  1. IPsec config:

     

 

config vpn ipsec phase1-interface

    edit "Site1"

        set interface "port10"

        set ike-version 2

        set peertype any

        set net-device disable

        set proposal aes256-sha256

        set wizard-type static-fortigate

        set remote-gw 10.10.10.2

        set psksecret ENC 0C8KlBBjW8sMXJvCsyJRUCqF3iaHncJWSvK20yOpr2NK1kSjPle5ncdBBB

    next

end

config vpn ipsec phase2-interface

    edit "Site1"

        set phase1name "Site1"

        set proposal aes256-sha256

        set src-subnet 192.168.1.0 255.255.255.0

        set dst-subnet 172.16.1.0 255.255.255.0

    next

end

 

 

  1. Firewall Policy.

 

config firewall policy

    edit 1

        set name "vpn_Site1_local"

        set srcintf "port2"

        set dstintf "Site1"

        set action accept

        set srcaddr "192.168.1.0"

        set dstaddr "172.16.1.0"

        set schedule "always"

        set service "ALL"

    next

    edit 2

        set name "vpn_Site2_local”

        set srcintf "Site1"

        set dstintf "port2"

        set action accept

        set srcaddr "172.16.1.0"

        set dstaddr "192.168.1.0"

        set schedule "always"

        set service "ALL"

    next

end

 

 

  1. Static Routes (only VPN routers are shown):


config router static

 

    edit 2

        set dst 172.16.1.0 255.255.255.0

        set device "Site1"

    next

    edit 3

        set dst 172.16.1.0 255.255.255.0

        set distance 254

        set blackhole enable

        set vrf 0

    next

end

 

 

  1. FGT2 secondary site configuration:

 

 

 

  1. IPsec config

 

config vpn ipsec phase1-interface

    edit "Site2"

        set interface "port10"

        set ike-version 2

        set peertype any

        set net-device disable

        set proposal aes256-sha256

        set wizard-type static-fortigate

        set remote-gw 10.10.10.1

        set psksecret ENC uRGJQnmQ9uYV0xWyVMEiNvJTfzNdqrqCL6couXjy9Ob/cNawJ

    next

end

 

config vpn ipsec phase2-interface

    edit "Site2"

        set phase1name "Site2"

        set proposal aes256-sha256

        set src-subnet 172.16.1.0 255.255.255.0

        set dst-subnet 192.168.1.0 255.255.255.0

    next

end

 

 

  1. Firewall Policy:

 

config firewall policy

    edit 1

        set name "vpn_Site2_local"

        set srcintf "port2"

        set dstintf "Site2"

        set action accept

        set srcaddr "172.16.1.0"

        set dstaddr "192.168.1.0"

        set schedule "always"

        set service "ALL"

    next

    edit 2

        set name "vpn_Site2_remote"

        set srcintf "Site2"

        set dstintf "port2"

        set action accept

        set srcaddr "192.168.1.0"

        set dstaddr "172.16.1.0"

        set schedule "always"

        set service "ALL"

    next

end

 

 

  1. Static Routes (only VPN routers are shown):

 

config router static

    edit 4

        set dst 192.168.1.0 255.255.255.0

        set device "Site2"

    next

    edit 5

        set dst 192.168.1.0 255.255.255.0

        set distance 254

        set blackhole enable

        set vrf 0

    next

end

 

A ping test from 192.168.1.1 to 172.16.1.1, which are both sites' internal networks, shows a normal debug flow hitting the correct route, traffic encryption, and firewall policy; while from sniffer prospective, the packet leaves FGT1 through the tunnel interface.

 

FGT1 # dia de flow filter clear

FGT1 # dia de flow filter add 172.16.1.1

FGT1 # dia de flow filter proto 1

FGT1 # dia de flow show iprope enable

FGT1 # dia de flow show funct enable

FGT1 # dia de flow trace start 1

FGT1 # dia de en

 

FGT1 # id=65308 trace_id=2 func=print_pkt_detail line=5933 msg="vd-root:0 received a packet(proto=1, 192.168.1.1:10->172.16.1.1:2048) tun_id=0.0.0.0 from local. type=8, code=0, id=10, seq=0."

id=65308 trace_id=2 func=init_ip_session_common line=6133 msg="allocate a new session-00000560"

id=65308 trace_id=2 func=iprope_dnat_check line=5545 msg="in-[], out-[Site1]"

id=65308 trace_id=2 func=iprope_dnat_tree_check line=826 msg="len=0"

id=65308 trace_id=2 func=iprope_dnat_check line=5570 msg="result: skb_flags-00000000, vid-0, ret-no-match, act-accept, flag-00000000"

id=65308 trace_id=2 func=ip_session_confirm_final line=3137 msg="npu_state=0x0, hook=4"

id=65308 trace_id=2 func=ipsecdev_hard_start_xmit line=662 msg="enter IPSec interface Site1, tun_id=0.0.0.0"

id=65308 trace_id=2 func=_do_ipsecdev_hard_start_xmit line=222 msg="output to IPSec tunnel Site1, tun_id=10.10.10.2, vrf 0"

id=65308 trace_id=2 func=esp_output4 line=917 msg="IPsec encrypt/auth"

id=65308 trace_id=2 func=ipsec_output_finish line=646 msg="tunnel Site1 send to ike"

 

FGT1 # diag sniffer packet any "host 172.16.1.1 and icmp" 4 0 l

Using Original Sniffing Mode

interfaces=[any]

filters=[host 172.16.1.1 and icmp]

2024-10-30 10:40:47.864809 Site1 out 192.168.1.1 -> 172.16.1.1: icmp: echo request

2024-10-30 10:40:47.872813 Site1 in 172.16.1.1 -> 192.168.1.1: icmp: echo reply

 

The problem appears when NAT is involved and IPPools are presented. Select Firewall Policy, edit the correct policy, and under 'Firewall/Network Options', select and enable NAT with option Use Dynamic IP Pool.

 

IPPOOL.png


In the IP Pool section, select a subnet which will hide real internal IPs and present this range to the other side.


For this example, 20.20.20.1-20.20.20.254 is configured.


IPPOOL2.png

 

Firewall policy will display NAT and IPPool.


fW.png

 

After this change is made, traffic will stop working between 2 sites and the reason is msg="No matching IPsec selector, drop".

 

FGT1 # dia de flow filter add 192.168.1.2 172.16.1.1 and

FGT1 # dia de flow filter proto 1

FGT1 # dia de flow show iprope en

FGT1 # dia de flow show funct en

FGT1 # dia de flow trace start 5

FGT1 # dia de en

 

FGT1 # id=65308 trace_id=13 func=print_pkt_detail line=5933 msg="vd-root:0 received a packet(proto=1, 192.168.1.2:2->172.16.1.1:2048) tun_id=0.0.0.0 from port2. type=8, code=0, id=2, seq=1."
id=65308 trace_id=13 func=init_ip_session_common line=6133 msg="allocate a new session-00000926"
id=65308 trace_id=13 func=iprope_dnat_check line=5545 msg="in-[port2], out-[]"
id=65308 trace_id=13 func=iprope_dnat_tree_check line=826 msg="len=0"
id=65308 trace_id=13 func=iprope_dnat_check line=5570 msg="result: skb_flags-02000000, vid-0, ret-no-match, act-accept, flag-00000000"
id=65308 trace_id=13 func=__vf_ip_route_input_rcu line=2115 msg="find a route: flag=00000000 gw-10.10.10.2 via Site1"
id=65308 trace_id=13 func=__iprope_fwd_check line=820 msg="in-[port2], out-[Site1], skb_flags-02000000, vid-0, app_id: 0, url_cat_id: 0"
id=65308 trace_id=13 func=__iprope_tree_check line=524 msg="gnum-100004, use int hash, slot=56, len=2"
id=65308 trace_id=13 func=__iprope_check_one_policy line=2167 msg="checked gnum-100004 policy-1, ret-matched, act-accept"
id=65308 trace_id=13 func=__iprope_user_identity_check line=1930 msg="ret-matched"
id=65308 trace_id=13 func=__iprope_check line=2450 msg="gnum-4e20, check-ffffffffa002c9c7"
id=65308 trace_id=13 func=__iprope_check_one_policy line=2167 msg="checked gnum-4e20 policy-6, ret-no-match, act-accept"
id=65308 trace_id=13 func=__iprope_check_one_policy line=2167 msg="checked gnum-4e20 policy-6, ret-no-match, act-accept"
id=65308 trace_id=13 func=__iprope_check_one_policy line=2167 msg="checked gnum-4e20 policy-6, ret-no-match, act-accept"
id=65308 trace_id=13 func=__iprope_check line=2467 msg="gnum-4e20 check result: ret-no-match, act-accept, flag-00000000, flag2-00000000"
id=65308 trace_id=13 func=get_new_addr line=1297 msg="find SNAT: IP-20.20.20.181(from IPPOOL), port-5119"
id=65308 trace_id=13 func=__iprope_check_one_policy line=2420 msg="policy-1 is matched, act-accept"
id=65308 trace_id=13 func=__iprope_fwd_check line=857 msg="after iprope_captive_check(): is_captive-0, ret-matched, act-accept, idx-1"
id=65308 trace_id=13 func=iprope_fwd_auth_check line=886 msg="after iprope_captive_check(): is_captive-0, ret-matched, act-accept, idx-1"
id=65308 trace_id=13 func=iprope_reverse_dnat_check line=1377 msg="in-[port2], out-[Site1], skb_flags-02000000, vid-0"
id=65308 trace_id=13 func=iprope_reverse_dnat_tree_check line=918 msg="len=0"
id=65308 trace_id=13 func=fw_forward_handler line=1003 msg="Allowed by Policy-1: SNAT"
id=65308 trace_id=13 func=ip_session_confirm_final line=3137 msg="npu_state=0x100, hook=4"
id=65308 trace_id=13 func=__ip_session_run_tuple line=3458 msg="SNAT 192.168.1.2->20.20.20.181:5119"  --- IPPool will translate internal subnet 192.168.1.0 to a new subnet 20.20.20.0 which is not configured under phase2-interface on VPN Tunnel
id=65308 trace_id=13 func=ipsecdev_hard_start_xmit line=662 msg="enter IPSec interface Site1, tun_id=0.0.0.0"
id=65308 trace_id=13 func=_do_ipsecdev_hard_start_xmit line=222 msg="output to IPSec tunnel Site1, tun_id=10.10.10.2, vrf 0"
id=65308 trace_id=13 func=ipsec_common_output4 line=923 msg="No matching IPsec selector, drop"

 

To fix this issue VPN must be edited on both sites and include IP pools instead of real internal IPs.

Changes needed on FGT1:

 

 

  1. Phase2 Selectors

 

config vpn ipsec phase2-interface

edit "Site1"

set phase1name "Site1"
set proposal aes256-sha256
set dhgrp 14
set src-subnet 20.20.20.0 255.255.255.0  <- Changed from 'set src-subnet 192.168.1.0 255.255.255.0'.

set dst-subnet 172.16.1.0 255.255.255.0

next

end


Changes needed on FGT2:

 

  1. Phase2 Selectors:

 

config vpn ipsec phase2-interface

    edit "Site2"   

        set phase1name "Site2"
        set proposal aes256-sha256
        set dhgrp 14
        set src-subnet 172.16.1.0 255.255.255.0
        set dst-subnet 20.20.20.0 255.255.255.0   <- Changed from 'set dst-subnet 192.168.1.0'. 255.255.255.0'.

next

end

 

  1. Firewall policy:

config firewall policy

    edit 2
        set name "vpn_Site2_remote"
        set srcintf "Site2"
        set dstintf "port2"
        set action accept
        set srcaddr "20.20.20.0"    <- Changed from 'set srcaddr 192.168.1.0'.
        set dstaddr "172.16.1.0"
        set schedule "always"
        set service "ALL"
    next
end

 

 

  1. Static route to avoid RPF and packet drops on the destination (more info about RPF on this article: Reverse Path Forwarding (RPF) implementat... - Fortinet Community).

 

 

config router static

    edit 4
        set dst 20.20.20.0 255.255.255.0        <- Changed from 'set dst 192.168.1.0'.
        set device "Site2"
    next
    edit 5
        set dst 20.20.20.0 255.255.255.0         <- Changed from 'set dst 192.168.1.0'.
        set distance 254
        set blackhole enable
        set vrf 0
    next
end

 

After making all of the above changes, ping test will go through and debug flow will show all interesting outputs.

 

FGT1 # id=65308 trace_id=27 func=print_pkt_detail line=5933 msg="vd-root:0 received a packet(proto=1, 192.168.1.2:5->172.16.1.1:2048) tun_id=0.0.0.0 from port2. type=8, code=0, id=5, seq=1."
id=65308 trace_id=27 func=init_ip_session_common line=6133 msg="allocate a new session-000013d9"
id=65308 trace_id=27 func=iprope_dnat_check line=5545 msg="in-[port2], out-[]"
id=65308 trace_id=27 func=iprope_dnat_tree_check line=826 msg="len=0"
id=65308 trace_id=27 func=iprope_dnat_check line=5570 msg="result: skb_flags-02000000, vid-0, ret-no-match, act-accept, flag-00000000"
id=65308 trace_id=27 func=__vf_ip_route_input_rcu line=2115 msg="find a route: flag=00000000 gw-10.10.10.2 via Site1"
id=65308 trace_id=27 func=__iprope_fwd_check line=820 msg="in-[port2], out-[Site1], skb_flags-02000000, vid-0, app_id: 0, url_cat_id: 0"
id=65308 trace_id=27 func=__iprope_tree_check line=524 msg="gnum-100004, use int hash, slot=56, len=2"
id=65308 trace_id=27 func=__iprope_check_one_policy line=2167 msg="checked gnum-100004 policy-1, ret-matched, act-accept"
id=65308 trace_id=27 func=__iprope_user_identity_check line=1930 msg="ret-matched"
id=65308 trace_id=27 func=__iprope_check line=2450 msg="gnum-4e20, check-ffffffffa002c9c7"
id=65308 trace_id=27 func=__iprope_check_one_policy line=2167 msg="checked gnum-4e20 policy-6, ret-no-match, act-accept"
id=65308 trace_id=27 func=__iprope_check_one_policy line=2167 msg="checked gnum-4e20 policy-6, ret-no-match, act-accept"
id=65308 trace_id=27 func=__iprope_check_one_policy line=2167 msg="checked gnum-4e20 policy-6, ret-no-match, act-accept"
id=65308 trace_id=27 func=__iprope_check line=2467 msg="gnum-4e20 check result: ret-no-match, act-accept, flag-00000000, flag2-00000000"
id=65308 trace_id=27 func=get_new_addr line=1297 msg="find SNAT: IP-20.20.20.181(from IPPOOL), port-5122"
id=65308 trace_id=27 func=__iprope_check_one_policy line=2420 msg="policy-1 is matched, act-accept"
id=65308 trace_id=27 func=__iprope_fwd_check line=857 msg="after iprope_captive_check(): is_captive-0, ret-matched, act-accept, idx-1"
id=65308 trace_id=27 func=iprope_fwd_auth_check line=886 msg="after iprope_captive_check(): is_captive-0, ret-matched, act-accept, idx-1"
id=65308 trace_id=27 func=iprope_reverse_dnat_check line=1377 msg="in-[port2], out-[Site1], skb_flags-02000000, vid-0"
id=65308 trace_id=27 func=iprope_reverse_dnat_tree_check line=918 msg="len=0"
id=65308 trace_id=27 func=fw_forward_handler line=1003 msg="Allowed by Policy-1: SNAT"
id=65308 trace_id=27 func=ip_session_confirm_final line=3137 msg="npu_state=0x100, hook=4"
id=65308 trace_id=27 func=__ip_session_run_tuple line=3458 msg="SNAT 192.168.1.2->20.20.20.181:5122"
id=65308 trace_id=27 func=ipsecdev_hard_start_xmit line=662 msg="enter IPSec interface Site1, tun_id=0.0.0.0"
id=65308 trace_id=27 func=_do_ipsecdev_hard_start_xmit line=222 msg="output to IPSec tunnel Site1, tun_id=10.10.10.2, vrf 0"
id=65308 trace_id=27 func=esp_output4 line=917 msg="IPsec encrypt/auth"
id=65308 trace_id=27 func=ipsec_output_finish line=646 msg="tunnel Site1 send to ike"

 

"find SNAT: IP-20.20.20.181(from IPPOOL), port-5122"   <- NAT IPPool range is found.
msg="policy-1 is matched, act-accept"   <- Policy 1 is a match for this traffic.

msg="SNAT 192.168.1.2->20.20.20.181:5122"    <- NAT action has changed the IP.

msg="output to IPSec tunnel Site1, tun_id=10.10.10.2, vrf 0"   <- Packet output to tunnel interface.

msg="IPsec encrypt/auth"   <- Traffic is encrypted and sent over the tunnel.