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.
ojacinto
Staff
Staff
Article Id 321203
Description This article describes how Iprope VIP policies are matched.
Scope FortiGate v7.0.0 and later, v7.2.0 and later, v7.4.0 and later.
Solution

The Iprope table for VIP objects can be seen by the following command:


diagnose firewall iprope list 100000


Every VIP object that is defined (and after the correct firewall IPV4 policy associated with that VIP object is configured) will create an entry into the Iprope table that will be inspected from top to bottom.


Remember that once a packet makes it through all of the ingress steps, the FortiOS kernel performs the following checks to determine what happens to the packet next.

 

ScreenHunter_209 Jun. 18 19.10.jpg

 

The first kernel step is DNAT. Here, the kernel checks the NAT table and determines if the destination IP address for incoming traffic must be changed using DNAT.

 

For example, the following three VIP objects has been configured on the FortiGate:

 

config firewall vip
    edit "RDP_WEB"
            set extip 192.168.170.160
            set mappedip "172.16.32.21"
            set extintf "port1"
            set portforward enable
            set extport 3389
            set mappedport 3389
   next
   edit "LINUX_server"
           set extip 192.168.170.165
           set mappedip "172.16.32.25"
           set extintf "port1"
           set portforward enable
           set extport 2222
           set mappedport 22
    next
    edit "LINUX2"
           set extip 192.168.170.165
           set mappedip "172.16.32.24"
           set extintf "port1"
     next
end

 

After that, the IPV4 firewall policies have been configured for those objects. The Iprope VIP table will be populated in the following way:

 

FGVM04-HA01 (root) # diagnose firewall iprope list 100000

policy index=1 uuid_idx=15809 action=accept
flag (8000100): nat pol_stats
schedule()
cos_fwd=0 cos_rev=0
group=00100000 av=00000000 au=00000000 split=00000000
host=0 chk_client_info=0x0 app_list=0 ips_view=0
misc=0
zone(1): 0 -> zone(1): 0
source(1): 0.0.0.0-255.255.255.255, uuid_idx=0,
dest(1): 192.168.170.160-192.168.170.160, uuid_idx=15809,
service(1):
[6:0x0:0/(0,65535)->(3389,3389)] flags:0 helper:auto
nat(1): flag=0 base=192.168.170.160:3389 172.16.32.21-172.16.32.21(3389:3389) < ---

 

policy index=2 uuid_idx=15811 action=accept
flag (8000100): nat pol_stats
schedule()
cos_fwd=0 cos_rev=0
group=00100000 av=00000000 au=00000000 split=00000000
host=0 chk_client_info=0x0 app_list=0 ips_view=0
misc=0
zone(1): 0 -> zone(1): 0
source(1): 0.0.0.0-255.255.255.255, uuid_idx=0,
dest(1): 192.168.170.165-192.168.170.165, uuid_idx=15811,
service(1):
[6:0x0:0/(0,65535)->(2222,2222)] flags:0 helper:auto
nat(1): flag=0 base=192.168.170.165:2222 172.16.32.25-172.16.32.25(22:22) < ---

 

policy index=3 uuid_idx=15813 action=accept
flag (8000104): f_p nat pol_stats
schedule()
cos_fwd=0 cos_rev=0
group=00100000 av=00000000 au=00000000 split=00000000
host=0 chk_client_info=0x0 app_list=0 ips_view=0
misc=0
zone(1): 0 -> zone(1): 0
source(1): 0.0.0.0-255.255.255.255, uuid_idx=0,
dest(1): 192.168.170.165-192.168.170.165, uuid_idx=15813,
service(1):
[0:0x0:0/(0,0)->(0,0)] flags:0 helper:auto
nat(1): flag=0 base=192.168.170.165:0 172.16.32.24-172.16.32.24(0:0)  <---

 

policy index=4294967295 uuid_idx=0 action=drop
flag (0):
schedule()
cos_fwd=0 cos_rev=0
group=00100000 av=00000000 au=00000000 split=00000000
host=0 chk_client_info=0x0 app_list=0 ips_view=0
misc=0
zone(1): -1 -> zone(1): -1
source(1): 0.0.0.0-0.0.0.0, uuid_idx=0,
dest(1): 0.0.0.0-0.0.0.0, uuid_idx=0,
service(0):

 

If a user tries to access the VIP 192.168.170.165 on port 2222, the FortiGate debug flow will show the Iprope policy match ID 2 before matching the IPv4 firewall policy:

 

FGVM04-HA01 (root) # 2024-06-13 04:34:05 id=65308 trace_id=1010 func=print_pkt_detail line=5894 msg="vd-root:0 received a packet(proto=6, 192.168.170.14:32917->192.168.170.165:2222) tun_id=0.0.0.0 from port1. flag [S], seq 3457834386, ack 0, win 64240"
2024-06-13 04:34:05 id=65308 trace_id=1010 func=init_ip_session_common line=6080 msg="allocate a new session-000883f6, tun_id=0.0.0.0"
2024-06-13 04:34:05 id=65308 trace_id=1010 func=iprope_dnat_check line=5281 msg="in-[port1], out-[]"
2024-06-13 04:34:05 id=65308 trace_id=1010 func=iprope_dnat_tree_check line=824 msg="len=2"
2024-06-13 04:34:05 id=65308 trace_id=1010 func=__iprope_check_one_dnat_policy line=5146 msg="checking gnum-100000 policy-2"
2024-06-13 04:34:05 id=65308 trace_id=1010 func=get_new_addr line=1213 msg="find DNAT: IP-172.16.32.25, port-22"
2024-06-13 04:34:05 id=65308 trace_id=1010 func=__iprope_check_one_dnat_policy line=5236 msg="matched policy-2, act=accept, vip=2, flag=100, sflag=2000000"
2024-06-13 04:34:05 id=65308 trace_id=1010 func=iprope_dnat_check line=5293 msg="result: skb_flags-02000000, vid-2, ret-matched, act-accept, flag-00000100"
2024-06-13 04:34:05 id=65308 trace_id=1010 func=fw_pre_route_handler line=184 msg="VIP-172.16.32.25:22, outdev-port1"
2024-06-13 04:34:05 id=65308 trace_id=1010 func=__ip_session_run_tuple line=3471 msg="DNAT 192.168.170.165:2222->172.16.32.25:22"
2024-06-13 04:34:05 id=65308 trace_id=1010 func=__vf_ip_route_input_rcu line=1990 msg="find a route: flag=00000000 gw-0.0.0.0 via port6"
2024-06-13 04:34:05 id=65308 trace_id=1010 func=iprope_fwd_check line=768 msg="in-[port1], out-[port6], skb_flags-020000c0, vid-2, app_id: 0, url_cat_id: 0"
2024-06-13 04:34:05 id=65308 trace_id=1010 func=__iprope_tree_check line=535 msg="gnum-100004, use addr/intf hash, len=5"
2024-06-13 04:34:05 id=65308 trace_id=1010 func=__iprope_check_one_policy line=2033 msg="checked gnum-100004 policy-1, ret-no-match, act-accept"
2024-06-13 04:34:05 id=65308 trace_id=1010 func=__iprope_check_one_policy line=2033 msg="checked gnum-100004 policy-2, ret-no-match, act-accept"
2024-06-13 04:34:05 id=65308 trace_id=1010 func=__iprope_check_one_policy line=2033 msg="checked gnum-100004 policy-4, ret-matched, act-accept"
2024-06-13 04:34:05 id=65308 trace_id=1010 func=__iprope_user_identity_check line=1807 msg="ret-matched"
2024-06-13 04:34:05 id=65308 trace_id=1010 func=__iprope_check line=2281 msg="gnum-4e22, check-00000000b3331723"
2024-06-13 04:34:05 id=65308 trace_id=1010 func=__iprope_check_one_policy line=2033 msg="checked gnum-4e22 policy-6, ret-no-match, act-accept"
2024-06-13 04:34:05 id=65308 trace_id=1010 func=__iprope_check_one_policy line=2033 msg="checked gnum-4e22 policy-6, ret-no-match, act-accept"
2024-06-13 04:34:05 id=65308 trace_id=1010 func=__iprope_check_one_policy line=2033 msg="checked gnum-4e22 policy-6, ret-no-match, act-accept"
2024-06-13 04:34:05 id=65308 trace_id=1010 func=__iprope_check line=2298 msg="gnum-4e22 check result: ret-no-match, act-accept, flag-00000000, flag2-00000000"
2024-06-13 04:34:05 id=65308 trace_id=1010 func=__iprope_check_one_policy line=2251 msg="policy-4 is matched, act-accept"
2024-06-13 04:34:05 id=65308 trace_id=1010 func=iprope_fwd_check line=805 msg="after iprope_captive_check(): is_captive-0, ret-matched, act-accept, idx-4"
2024-06-13 04:34:05 id=65308 trace_id=1010 func=iprope_fwd_auth_check line=824 msg="after iprope_captive_check(): is_captive-0, ret-matched, act-accept, idx-4"
2024-06-13 04:34:05 id=65308 trace_id=1010 func=fw_forward_handler line=989 msg="Allowed by Policy-4:"

 

On the debug, the Iprope list 100000 for VIP objects is first checked, and then, the Iprope list 100004 for the IPv4 firewall policies.

The like Iprope is read from top to bottom. it is necessary to place the most specific policies on the top and the most general policies on bottom.

 

In this example, if the VIP order is changed:

 

   edit "LINUX2"
        set extip 192.168.170.165
        set mappedip "172.16.32.24"
        set extintf "port1"
    next
    
edit "LINUX_server_BK"
        set extip 192.168.170.165
        set mappedip "172.16.32.25"
        set extintf "port1"
        set portforward enable
        set extport 2222
       set mappedport 22
     next
end

 

The Iprope list 100000 order will change and traffic destinated to the VIP 192.168.170.165 port 2222 will match the VIP 'LINUX2' ( VIP policy ID 3) because they are using the same external IP but the first one does not have any port forwarding:

 

FGVM04-HA01 (root) # diagnose firewall iprope list 100000

policy index=1 uuid_idx=15809 action=accept
flag (8000100): nat pol_stats
schedule()
cos_fwd=0 cos_rev=0
group=00100000 av=00000000 au=00000000 split=00000000
host=0 chk_client_info=0x0 app_list=0 ips_view=0
misc=0
zone(1): 0 -> zone(1): 0
source(1): 0.0.0.0-255.255.255.255, uuid_idx=0,
dest(1): 192.168.170.160-192.168.170.160, uuid_idx=15809,
service(1):
[6:0x0:0/(0,65535)->(3389,3389)] flags:0 helper:auto
nat(1): flag=0 base=192.168.170.160:3389 172.16.32.21-172.16.32.21(3389:3389)

 

policy index=3 uuid_idx=15813 action=accept   < --- 
flag (8000104): f_p nat pol_stats
schedule()
cos_fwd=0 cos_rev=0
group=00100000 av=00000000 au=00000000 split=00000000
host=0 chk_client_info=0x0 app_list=0 ips_view=0
misc=0
zone(1): 0 -> zone(1): 0
source(1): 0.0.0.0-255.255.255.255, uuid_idx=0,
dest(1): 192.168.170.165-192.168.170.165, uuid_idx=15813,
service(1):
[0:0x0:0/(0,0)->(0,0)] flags:0 helper:auto
nat(1): flag=0 base=192.168.170.165:0 172.16.32.24-172.16.32.24(0:0) <--- No portforwading is configured, traffic will match here

 

policy index=4 uuid_idx=15816 action=accept
flag (8000100): nat pol_stats
schedule()
cos_fwd=0 cos_rev=0
group=00100000 av=00000000 au=00000000 split=00000000
host=0 chk_client_info=0x0 app_list=0 ips_view=0
misc=0
zone(1): 0 -> zone(1): 0
source(1): 0.0.0.0-255.255.255.255, uuid_idx=0,
dest(1): 192.168.170.165-192.168.170.165, uuid_idx=15816,
service(1):
[6:0x0:0/(0,65535)->(2222,2222)] flags:0 helper:auto
nat(1): flag=0 base=192.168.170.165:2222 172.16.32.25-172.16.32.25(22:22)

 

policy index=4294967295 uuid_idx=0 action=drop
flag (0):
schedule()
cos_fwd=0 cos_rev=0
group=00100000 av=00000000 au=00000000 split=00000000
host=0 chk_client_info=0x0 app_list=0 ips_view=0
misc=0
zone(1): -1 -> zone(1): -1
source(1): 0.0.0.0-0.0.0.0, uuid_idx=0,
dest(1): 0.0.0.0-0.0.0.0, uuid_idx=0,
service(0):

 

FGVM04-HA01 (root) # 2024-06-13 05:13:24 id=65308 trace_id=1015 func=print_pkt_detail line=5894 msg="vd-root:0 received a packet(proto=6, 192.168.170.14:37735->192.168.170.165:2222) tun_id=0.0.0.0 from port1. flag [S], seq 6641251, ack 0, win 64240"
2024-06-13 05:13:24 id=65308 trace_id=1015 func=init_ip_session_common line=6080 msg="allocate a new session-0008a81b, tun_id=0.0.0.0"
2024-06-13 05:13:24 id=65308 trace_id=1015 func=iprope_dnat_check line=5281 msg="in-[port1], out-[]"
2024-06-13 05:13:24 id=65308 trace_id=1015 func=iprope_dnat_tree_check line=824 msg="len=2"
2024-06-13 05:13:24 id=65308 trace_id=1015 func=__iprope_check_one_dnat_policy line=5146 msg="checking gnum-100000 policy-3"
2024-06-13 05:13:24 id=65308 trace_id=1015 func=get_new_addr line=1213 msg="find DNAT: IP-172.16.32.24, port-0(fixed port)"
2024-06-13 05:13:24 id=65308 trace_id=1015 func=__iprope_check_one_dnat_policy line=5236 msg="matched policy-3, act=accept, vip=3, flag=104, sflag=2000000"
2024-06-13 05:13:24 id=65308 trace_id=1015 func=iprope_dnat_check line=5293 msg="result: skb_flags-02000000, vid-3, ret-matched, act-accept, flag-00000104"
2024-06-13 05:13:24 id=65308 trace_id=1015 func=fw_pre_route_handler line=184 msg="VIP-172.16.32.24:2222, outdev-port1"
2024-06-13 05:13:24 id=65308 trace_id=1015 func=__ip_session_run_tuple line=3471 msg="DNAT 192.168.170.165:2222->172.16.32.24:2222"

Contributors