Configuring PCP port mapping with SNAT and DNAT
FortiOS supports the Port Control Protocol (PCP) by allowing the FortiGate to act as a PCP server, and dynamically manage network addresses and port translations for PCP clients. The PCP server must be enabled with a pool (config system pcp-server
). In the firewall policy, enable either pcp-outbound
or pcp-inbound
mode and assign the pool.
config system pcp-server set status {enable | disable} config pools edit <name> set client-subnet <ip_address/subnet> set ext-intf <string> set extip ip>[-<ip>] set extport <port>[-<port>] set minimal-lifetime <integer> set maximal-lifetime <integer> set client-mapping-limit <integer> set mapping-filter-limit <integer> set allow-opcode {map peer announce} set third-party {allow | disallow} set multicast-announcement {enable | disable} set announcement-count <integer> set intl-intf <string> set recycle-delay <integer> next end end
client-subnet <ip_address/subnet> |
Enter the IP address with subnet from which PCP requests are accepted. |
ext-intf <string> |
Enter the external interface name. |
extip <ip>[-<ip>] |
Enter the IP address or address range on the external interface to map to an address on the internal network. |
extport <port>[-<port>] |
Enter the incoming port number or port range to map to a port number on the internal network. |
minimal-lifetime <integer> |
Set the minimal lifetime of a PCP mapping, in seconds (60 - 300, default = 120). |
maximal-lifetime <integer> |
Set the maximal lifetime of a PCP mapping, in seconds (3600 - 604800, default = 86400). |
client-mapping-limit <integer> |
Mapping limit per client (0 - 65535, default = 0, 0 = unlimited). |
mapping-filter-limit <integer> |
Filter limit per mapping (0 - 5, default = 1). |
allow-opcode {map peer announce} |
Set the allowed PCP OpCode:
|
third-party {allow | disallow} |
Allow/disallow the third-party option. |
multicast-announcement {enable | disable} |
Enable/disable multicast announcements. |
announcement-count <integer> |
Set the number of multicast announcements (3 - 10, default = 3). |
intl-intf <string> |
Enter the internal interface name. |
recycle-delay <integer> |
Set the minimum delay the PCP server will wait before recycling mappings that have expired, in seconds (0 - 3600, default = 0). |
The following topology is used to demonstrate two use cases of PCP mapping: with SNAT and DNAT.
Example 1: PCP mapping with SNAT
This example demonstrates how PCP mapping works with SNAT. In the FortiGate PCP server settings, the pcp-pool1 pool is applied in the firewall policy with pcp-outbound
mode. A PCP request is sent from Client-1 to the FortiGate to create PCP outbound mapping. When traffic is sent from Client-1 to Client-2, SNAT is performed by the PCP outbound mapping.
To configure the FortiGate as a PCP server:
-
Configure the PCP server settings:
config system pcp-server set status enable config pools edit "pcp-pool1" set client-subnet "10.1.100.41/32" set ext-intf "wan1" set extip 172.16.200.231 set extport 50000-51000 set intl-intf "wan2" next end end
-
Configure the firewall policy:
config firewall policy edit 999 set name "Outbound-pcp-policy999" set srcintf "wan2" set dstintf "wan1" set action accept set srcaddr "all" set dstaddr "all" set srcaddr6 "all" set dstaddr6 "all" set schedule "always" set service "ALL" set logtraffic all set auto-asic-offload disable set nat enable set pcp-outbound enable set pcp-poolname "pcp-pool1" next end
To verify the configuration:
-
Generate a PCP peer request from Client-1 (10.1.100.41) to the FortiGate.
-
Verify the client's PCP request to the PCP server. In this example, an PCP client was installed on Ubuntu:
root@pc41:~# pcp -i 10.1.100.41:41111 -p 172.16.200.55:80 -s 10.1.100.8
-
On the FortiGate, verify the PCP outbound mappings list:
# diagnose firewall pcp-mapping list outbound PCP outbound mappings (vdom=root): pool:1 nonce:04307eb4037e0448317dc8b7 protocol:6 duration:8 lifetime:900 expiry:893 intl:10.1.100.41:41111 ext:172.16.200.231:50000 remote:172.16.200.55:80
-
Send HTTP traffic that passes through the FortiGate and access Client-2 (172.16.200.55:80) from Client-1.
-
On the FortiGate, verify the session list. The source IP address of Client-1 is translated to 172.16.200.231:50000, which follows the PCP outbound mapping:
# diagnose sys session list session info: proto=6 proto_state=01 duration=8 expire=3599 timeout=3600 flags=00000000 socktype=0 sockport=0 av_idx=0 use=3 origin-shaper= reply-shaper= per_ip_shaper= class_id=0 ha_id=0 policy_dir=0 tunnel=/ vlan_cos=0/255 state=log may_dirty f00 pcp_outbound statistic(bytes/packets/allow_err): org=1812/33/1 reply=124168/92/1 tuples=2 tx speed(Bps/kbps): 204/1 rx speed(Bps/kbps): 13998/111 orgin->sink: org pre->post, reply pre->post dev=8->7/7->8 gwy=172.16.200.55/10.1.100.41 hook=post dir=org act=snat 10.1.100.41:41111->172.16.200.55:80(172.16.200.231:50000) hook=pre dir=reply act=dnat 172.16.200.55:80->172.16.200.231:50000(10.1.100.41:41111) pos/(before,after) 0/(0,0), 0/(0,0) misc=0 policy_id=999 pol_uuid_idx=677 auth_info=0 chk_client_info=0 vd=0 serial=0000b4f8 tos=ff/ff app_list=0 app=0 url_cat=0 rpdb_link_id=00000000 ngfwid=n/a npu_state=0x4000001 no_offload no_ofld_reason: disabled-by-policy total session 1
-
Send HTTP traffic that passes through the FortiGate and access another server from Client-1.
-
On the FortiGate, verify the session list. This time, the source IP address of Client-1 is not translated to 172.16.200.231:50000, since the traffic does not match the existing PCP outbound mapping:
# diagnose sys session list session info: proto=6 proto_state=01 duration=6 expire=3596 timeout=3600 flags=00000000 socktype=0 sockport=0 av_idx=0 use=3 origin-shaper= reply-shaper= per_ip_shaper= class_id=0 ha_id=0 policy_dir=0 tunnel=/ vlan_cos=0/255 state=log may_dirty f00 statistic(bytes/packets/allow_err): org=1449/26/1 reply=98808/72/1 tuples=2 tx speed(Bps/kbps): 215/1 rx speed(Bps/kbps): 14703/117 orgin->sink: org pre->post, reply pre->post dev=8->7/7->8 gwy=172.16.200.155/10.1.100.41 hook=post dir=org act=snat 10.1.100.41:41111->172.16.200.155:80(172.16.200.8:41111) hook=pre dir=reply act=dnat 172.16.200.155:80->172.16.200.8:41111(10.1.100.41:41111) pos/(before,after) 0/(0,0), 0/(0,0) misc=0 policy_id=999 pol_uuid_idx=677 auth_info=0 chk_client_info=0 vd=0 serial=0000b596 tos=ff/ff app_list=0 app=0 url_cat=0 rpdb_link_id=00000000 ngfwid=n/a npu_state=0x4000001 no_offload no_ofld_reason: disabled-by-policy total session 1
Example 2: PCP mapping with DNAT
This example demonstrates how PCP mapping works with DNAT. In the FortiGate PCP server settings, the pcp-pool1 pool is applied in the firewall policy with pcp-inbound
mode. A PCP request is sent from Client-1 to the FortiGate to create PCP inbound mapping. When traffic is sent from Client-2 to access the external IP of Client-1 (172.16.200.231:50000), traffic passes by due to the PCP inbound mapping.
To configure the FortiGate as a PCP server:
-
Configure the PCP server settings:
config system pcp-server set status enable config pools edit "pcp-pool1" set client-subnet "10.1.100.41/32" set ext-intf "wan1" set extip 172.16.200.231 set extport 50000-51000 set intl-intf "wan2" next end end
-
Configure the firewall policy:
config firewall policy edit 998 set name "Inbound-pcp-policy998" set srcintf "wan1" set dstintf "wan2" set action accept set srcaddr "all" set dstaddr "all" set srcaddr6 "all" set dstaddr6 "all" set schedule "always" set service "ALL" set logtraffic all set auto-asic-offload disable set nat enable set pcp-inbound enable set pcp-poolname "pcp-pool1" next end
To verify the configuration:
-
Generate a PCP peer request from Client-1 (10.1.100.41) to the FortiGate.
-
Verify the client's PCP request to the PCP server. In this example, an PCP client was installed on Ubuntu:
root@pc41:~# pcp -i 10.1.100.41:80 -s 10.1.100.8
-
On the FortiGate, verify the PCP inbound mappings list:
# diagnose firewall pcp-mapping list inbound PCP inbound mappings (vdom=root): pool:1 nonce:35e2ff035b959f7a4e669791 protocol:6 duration:3 lifetime:900 expiry:900 intl:10.1.100.41:80 ext:172.16.200.231:50000
-
From Client-2 (172.16.200.55:80), send traffic that passes through the FortiGate and access the external IP of Client-1 (172.16.200.231:50000).
-
On the FortiGate, run a sniffer trace. The traffic is allowed through policy 998, and the destination IP:port is translated from 172.16.200.231:50000 to 10.1.100.41:80, which follows the PCP inbound mapping:
# diagnose sniffer packet any 'tcp and port 50000 or port 80' 4 interfaces=[any] filters=[tcp and port 50000 or port 80] 2.959915 wan1 in 172.16.200.55.43284 -> 172.16.200.231.50000: syn 3480016601 2.960051 wan2 out 10.1.100.8.43284 -> 10.1.100.41.80: syn 3480016601 2.960390 wan2 in 10.1.100.41.80 -> 10.1.100.8.43284: syn 2813145613 ack 3480016602 2.960447 wan1 out 172.16.200.231.50000 -> 172.16.200.55.43284: syn 2813145613 ack 3480016602 2.960644 wan1 in 172.16.200.55.43284 -> 172.16.200.231.50000: ack 2813145614 2.960664 wan2 out 10.1.100.8.43284 -> 10.1.100.41.80: ack 2813145614 2.961194 wan1 in 172.16.200.55.43284 -> 172.16.200.231.50000: psh 3480016602 ack 2813145614 2.961209 wan2 out 10.1.100.8.43284 -> 10.1.100.41.80: psh 3480016602 ack 2813145614 2.961516 wan2 in 10.1.100.41.80 -> 10.1.100.8.43284: ack 3480016686 2.961533 wan1 out 172.16.200.231.50000 -> 172.16.200.55.43284: ack 3480016686 2.993623 wan2 in 10.1.100.41.80 -> 10.1.100.8.43284: psh 2813145614 ack 3480016686 2.993637 wan1 out 172.16.200.231.50000 -> 172.16.200.55.43284: psh 2813145614 ack 3480016686 2.993947 wan1 in 172.16.200.55.43284 -> 172.16.200.231.50000: ack 2813145875 2.993962 wan2 out 10.1.100.8.43284 -> 10.1.100.41.80: ack 2813145875 2.995677 wan1 in 172.16.200.55.43284 -> 172.16.200.231.50000: fin 3480016686 ack 2813145875 2.995691 wan2 out 10.1.100.8.43284 -> 10.1.100.41.80: fin 3480016686 ack 2813145875 2.996059 wan2 in 10.1.100.41.80 -> 10.1.100.8.43284: fin 2813145875 ack 3480016687 2.996075 wan1 out 172.16.200.231.50000 -> 172.16.200.55.43284: fin 2813145875 ack 3480016687 2.996230 wan1 in 172.16.200.55.43284 -> 172.16.200.231.50000: ack 2813145876 2.996245 wan2 out 10.1.100.8.43284 -> 10.1.100.41.80: ack 2813145876
Only traffic matching the PCP inbound mapping will be forwarded by policy 998. Any other traffic is dropped.