Simplify NAT46 and NAT64 policy and routing configurations 7.0.1
Multiple NAT46 and NAT64 related objects are consolidated into regular objects. A new per-VDOM virtual interface, naf.<vdom>, is automatically added to process NAT46/NAT64 traffic. The new changes and additions include:
- Consolidate
vip46
andvip64
setting intovip
andvip6
configurations. - Consolidate
policy46
andpolicy64
settings intofirewall policy
settings. - Introduce
nat46
/nat64
infirewall policy
settings. - Extend
ippool
andippool6
to support NAT46 and NAT64 (when enabled, the IP pool should match a subnet). - Extend central SNAT to support NAT46 and NAT64.
- Remove
firewall vip46
/vip64
,vipgrp46
/vipgrp64
, andpolicy46
/policy64
settings and GUI pages. - Rename
system.nat64
tosystem.dns64
. - Add option for
add-nat46-route
inippool6
andadd-nat64-route
inippool
, which are enabled by default. The FortiGate will generate a static route that matches the IP range inippool6
orippool
for the naf tunnel interface.
Automatic processing of the naf tunnel interface is not supported in security policies. |
To configure NAT46/NAT64 translation, use the standard vip
/vip6
setting, apply it in a firewall policy, enable NAT46/NAT64, and enter the IP pool to complete the configuration.
The external IP address cannot be the same as the external interface IP address. |
Examples
IPv6 must be enabled to configure these examples. In the GUI, so go to System > Feature Visibility and enable IPv6. In the CLI, enter the following:
config system global set gui-ipv6 enable end
NAT46 policy
In this example, a client PC is using IPv4 and an IPv4 VIP to access a server that is using IPv6. The FortiGate uses NAT46 to translate the request from IPv4 to IPv6 using the virtual interface naf.root. An ippool6
is applied so that the request is SNATed to the ippool6
address (2000:172:16:101::1 - 2000:172:16:101::1).
To create a NAT46 policy in the GUI:
- Configure the VIP:
- Go to Policy & Objects > Virtual IPs and click Create New > VIP.
- Enter the following:
VIP type
IPv4
Name
test-vip46-1
Interface
To_vlan20
Type
Static NAT
External IP address/range
10.1.100.150
Map to IPv6 address/range
2000:172:16:200::156
- Click OK.
- Configure the IPv6 pool:
- Go to Policy & Objects > IP Pools and click Create New.
- Enter the following:
IP Pool Type
IPv6 Pool
Name
test-ippool6-1
External IP address/range
2000:172:16:101::1-2000:172:16:101::1
NAT46
Enable
- Click OK.
- Configure the firewall policy:
- Go to Policy & Objects > Firewall Policy and click Create New or edit an existing policy.
- Enter the following:
Name
policy46-1
Incoming Interface
To_vlan20
Outgoing Interface
To_vlan30
Source
all
Destination
test-vip46-1
Schedule
always
Service
ALL
Action
ACCEPT
NAT
NAT46
IP Pool Configuration
test-ippool6-1
- Configure the other settings as needed.
- Click OK.
To create a NAT46 policy in the CLI:
- Configure the VIP:
config firewall vip edit "test-vip46-1" set extip 10.1.100.150 set nat44 disable set nat46 enable set extintf "port24" set arp-reply enable set ipv6-mappedip 2000:172:16:200::156 next end
- Configure the IPv6 pool:
config firewall ippool6 edit "test-ippool6-1" set startip 2000:172:16:101::1 set endip 2000:172:16:101::1 set nat46 enable set add-nat46-route enable next end
- Configure the firewall policy:
config firewall policy edit 2 set name "policy46-1" set srcintf "port24" set dstintf "port17" set action accept set nat46 enable set srcaddr "all" set dstaddr "test-vip46-1" set srcaddr6 "all" set dstaddr6 "all" set schedule "always" set service "ALL" set logtraffic all set auto-asic-offload disable set ippool enable set poolname6 "test-ippool6-1" next end
To verify the traffic and session tables:
- Verify the traffic by the sniffer packets:
(root) # diagnose sniffer packet any 'icmp or icmp6' 4 interfaces=[any] filters=[icmp or icmp6] 2.593302 port24 in 10.1.100.41 -> 10.1.100.150: icmp: echo request 2.593344 naf.root out 10.1.100.41 -> 10.1.100.150: icmp: echo request 2.593347 naf.root in 2000:172:16:101::1 -> 2000:172:16:200::156: icmp6: echo request seq 1 2.593383 port17 out 2000:172:16:101::1 -> 2000:172:16:200::156: icmp6: echo request seq 1 2.593772 port17 in 2000:172:16:200::156 -> 2000:172:16:101::1: icmp6: echo reply seq 1 2.593788 naf.root out 2000:172:16:200::156 -> 2000:172:16:101::1: icmp6: echo reply seq 1 2.593790 naf.root in 10.1.100.150 -> 10.1.100.41: icmp: echo reply 2.593804 port24 out 10.1.100.150 -> 10.1.100.41: icmp: echo reply 11 packets received by filter 0 packets dropped by kernel
- Verify the session tables for IPv4 and IPv6:
(root) # diagnose sys session list session info: proto=1 proto_state=00 duration=2 expire=59 timeout=0 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 netflow-origin netflow-reply statistic(bytes/packets/allow_err): org=252/3/1 reply=252/3/1 tuples=2 tx speed(Bps/kbps): 106/0 rx speed(Bps/kbps): 106/0 orgin->sink: org pre->post, reply pre->post dev=24->53/53->24 gwy=10.1.100.150/10.1.100.41 hook=pre dir=org act=noop 10.1.100.41:29388->10.1.100.150:8(0.0.0.0:0) hook=post dir=reply act=noop 10.1.100.150:29388->10.1.100.41:0(0.0.0.0:0) peer=2000:172:16:101::1:29388->2000:172:16:200::156:128 naf=1 hook=pre dir=org act=noop 2000:172:16:101::1:29388->2000:172:16:200::156:128(:::0) hook=post dir=reply act=noop 2000:172:16:200::156:29388->2000:172:16:101::1:129(:::0) misc=0 policy_id=2 auth_info=0 chk_client_info=0 vd=0 serial=00012b77 tos=ff/ff app_list=0 app=0 url_cat=0 sdwan_mbr_seq=0 sdwan_service_id=0 rpdb_link_id=00000000 rpdb_svc_id=0 ngfwid=n/a npu_state=0x040001 no_offload no_ofld_reason: disabled-by-policy non-npu-intf total session 1
(root) # diagnose sys session6 list session6 info: proto=58 proto_state=00 duration=5 expire=56 timeout=0 flags=00000000 sockport=0 socktype=0 use=3 origin-shaper= reply-shaper= per_ip_shaper= class_id=0 ha_id=0 policy_dir=0 tunnel=/ vlan_cos=0/0 state=log may_dirty statistic(bytes/packets/allow_err): org=312/3/0 reply=312/3/0 tuples=2 tx speed(Bps/kbps): 0/0 rx speed(Bps/kbps): 0/0 orgin->sink: org pre->post, reply pre->post dev=53->17/17->53 hook=pre dir=org act=noop 2000:172:16:101::1:29388->2000:172:16:200::156:128(:::0) hook=post dir=reply act=noop 2000:172:16:200::156:29388->2000:172:16:101::1:129(:::0) peer=10.1.100.150:29388->10.1.100.41:0 naf=2 hook=pre dir=org act=noop 10.1.100.41:29388->10.1.100.150:8(0.0.0.0:0) hook=post dir=reply act=noop 10.1.100.150:29388->10.1.100.41:0(0.0.0.0:0) misc=0 policy_id=2 auth_info=0 chk_client_info=0 vd=0 serial=00001bbc tos=ff/ff ips_view=1024 app_list=0 app=0 url_cat=0 rpdb_link_id = 00000000 ngfwid=n/a npu_state=0x000001 no_offload no_ofld_reason: disabled-by-policy total session 1
The IPv4 session is between the incoming physical interface port24 and naf.root. The IPv6 session is between the naf.root and the outgoing physical interface port17.
NAT64 policy
In this example, a client PC is using IPv6 and an IPv6 VIP to access a server that is using IPv4. The FortiGate uses NAT64 to translate the request from IPv6 to IPv4 using the virtual interface naf.root. An ippool
is applied so that the request is SNATed to the ippool
address (172.16.101.2 - 172.16.101.3).
An embedded VIP64 object is used in this configuration so a specific IPv4 mapped IP does not need to be set. The lower 32 bits of the external IPv6 address are used to map to the IPv4 address. Only an IPv6 prefix is defined. In this example, the IPv6 prefix is 2001:10:1:100::, so the IPv6 address 2001:10:1:100::ac10:c89c will be translated to 172.16.200.156.
To create a NAT64 policy in the GUI:
- Configure the VIP:
- Go to Policy & Objects > Virtual IPs and click Create New > VIP.
- Enter the following:
VIP type
IPv6
Name
test-vip64-1
External IP address/range
2000:10:1:100::150
Map to IPv4 address/range
Specify: 172.16.200.156
- Click OK.
- Configure the VIP with the embedded IPv4 address enabled:
- Go to Policy & Objects > Virtual IPs and click Create New > VIP.
- Enter the following:
VIP type
IPv6
Name
test-vip64-2
External IP address/range
2001:10:1:100::-2001:10:1:100::ffff:ffff
Map to IPv4 address/range
Use Embedded
- Click OK.
- Configure the IP pool:
- Go to Policy & Objects > IP Pools and click Create New.
- Enter the following:
IP Pool Type
IPv4 Pool
Name
test-ippool4-1
Type
Overload
External IP address/range
172.16.101.2-172.16.101.3
NAT64
Enable
- Click OK.
- Configure the firewall policy:
- Go to Policy & Objects > Firewall Policy and click Create New or edit an existing policy.
- Enter the following:
Name
policy64-1
Incoming Interface
To_vlan20
Outgoing Interface
To_vlan30
Source
all
Destination
test-vip64-1
test-vip64-2
Schedule
always
Service
ALL
Action
ACCEPT
NAT
NAT64
IP Pool Configuration
test-ippool4-1
- Configure the other settings as needed.
- Click OK.
To create a NAT64 policy in the CLI:
- Configure the VIP:
config firewall vip6 edit "test-vip64-1" set extip 2000:10:1:100::150 set nat66 disable set nat64 enable set ipv4-mappedip 172.16.200.156 next end
- Configure the VIP with the embedded IPv4 address enabled:
config firewall vip6 edit "test-vip64-2" set extip 2001:10:1:100::-2001:10:1:100::ffff:ffff set nat66 disable set nat64 enable set embedded-ipv4-address enable next end
- Configure the IP pool:
config firewall ippool edit "test-ippool4-1" set startip 172.16.101.2 set endip 172.16.101.3 set nat64 enable set add-nat64-route enable next end
- Configure the firewall policy:
config firewall policy edit 1 set name "policy64-1" set srcintf "port24" set dstintf "port17" set action accept set nat64 enable set srcaddr "all" set dstaddr "all" set srcaddr6 "all" set dstaddr6 "test-vip64-1" "test-vip64-2" set schedule "always" set service "ALL" set logtraffic all set auto-asic-offload disable set ippool enable set poolname "test-ippool4-1" next end
To verify the traffic and session tables:
- Verify the VIP64 traffic by the sniffer packets:
(root) # diagnose sniffer packet any 'icmp or icmp6' 4 interfaces=[any] filters=[icmp or icmp6] 20.578417 port24 in 2000:10:1:100::41 -> 2000:10:1:100::150: icmp6: echo request seq 1 20.578495 naf.root out 2000:10:1:100::41 -> 2000:10:1:100::150: icmp6: echo request seq 1 20.578497 naf.root in 172.16.101.2 -> 172.16.200.156: icmp: echo request 20.578854 port17 out 172.16.101.2 -> 172.16.200.156: icmp: echo request 20.579083 port17 in 172.16.200.156 -> 172.16.101.2: icmp: echo reply 20.579093 naf.root out 172.16.200.156 -> 172.16.101.2: icmp: echo reply 20.579095 naf.root in 2000:10:1:100::150 -> 2000:10:1:100::41: icmp6: echo reply seq 1 20.579377 port24 out 2000:10:1:100::150 -> 2000:10:1:100::41: icmp6: echo reply seq 1 11 packets received by filter 0 packets dropped by kernel
- Verify the session tables for IPv6 and IPv4:
(root) # diagnose sys session6 list session6 info: proto=58 proto_state=00 duration=5 expire=56 timeout=0 flags=00000000 sockport=0 socktype=0 use=3 origin-shaper= reply-shaper= per_ip_shaper= class_id=0 ha_id=0 policy_dir=0 tunnel=/ vlan_cos=0/0 state=log may_dirty statistic(bytes/packets/allow_err): org=312/3/0 reply=312/3/0 tuples=2 tx speed(Bps/kbps): 55/0 rx speed(Bps/kbps): 55/0 orgin->sink: org pre->post, reply pre->post dev=24->53/53->24 hook=pre dir=org act=noop 2000:10:1:100::41:29949->2000:10:1:100::150:128(:::0) hook=post dir=reply act=noop 2000:10:1:100::150:29949->2000:10:1:100::41:129(:::0) peer=172.16.101.2:45392->172.16.200.156:8 naf=1 hook=pre dir=org act=noop 172.16.101.2:45392->172.16.200.156:8(0.0.0.0:0) hook=post dir=reply act=noop 172.16.200.156:45392->172.16.101.2:0(0.0.0.0:0) misc=0 policy_id=1 auth_info=0 chk_client_info=0 vd=0 serial=000021ec tos=ff/ff ips_view=1024 app_list=0 app=0 url_cat=0 rpdb_link_id = 00000000 ngfwid=n/a npu_state=0x040001 no_offload no_ofld_reason: disabled-by-policy non-npu-intf total session 1
(root) # diagnose sys session list session info: proto=1 proto_state=00 duration=7 expire=54 timeout=0 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=252/3/1 reply=252/3/1 tuples=2 tx speed(Bps/kbps): 0/0 rx speed(Bps/kbps): 0/0 orgin->sink: org pre->post, reply pre->post dev=53->17/17->53 gwy=172.16.200.156/172.16.101.2 hook=pre dir=org act=noop 172.16.101.2:45392->172.16.200.156:8(0.0.0.0:0) hook=post dir=reply act=noop 172.16.200.156:45392->172.16.101.2:0(0.0.0.0:0) peer=2000:10:1:100::150:29949->2000:10:1:100::41:129 naf=2 hook=pre dir=org act=noop 2000:10:1:100::41:29949->2000:10:1:100::150:128(:::0) hook=post dir=reply act=noop 2000:10:1:100::150:29949->2000:10:1:100::41:129(:::0) misc=0 policy_id=1 auth_info=0 chk_client_info=0 vd=0 serial=0001347f tos=ff/ff app_list=0 app=0 url_cat=0 sdwan_mbr_seq=0 sdwan_service_id=0 rpdb_link_id=00000000 rpdb_svc_id=0 ngfwid=n/a npu_state=0x000001 no_offload no_ofld_reason: disabled-by-policy total session 1
The IPv6 session is between the incoming physical interface port24 and naf.root. The IPv4 session is between the naf.root and the outgoing physical interface port17.
- Verify the embedded VIP64 traffic by the sniffer packets:
(root) # diagnose sniffer packet any 'icmp or icmp6' 4 interfaces=[any] filters=[icmp or icmp6] 7.696010 port24 in 2000:10:1:100::41 -> 2001:10:1:100::ac10:c89c: icmp6: echo request seq 1 7.696057 naf.root out 2000:10:1:100::41 -> 2001:10:1:100::ac10:c89c: icmp6: echo request seq 1 7.696060 naf.root in 172.16.101.2 -> 172.16.200.156: icmp: echo request 7.696544 port17 out 172.16.101.2 -> 172.16.200.156: icmp: echo request 7.696821 port17 in 172.16.200.156 -> 172.16.101.2: icmp: echo reply 7.696839 naf.root out 172.16.200.156 -> 172.16.101.2: icmp: echo reply 7.696841 naf.root in 2001:10:1:100::ac10:c89c -> 2000:10:1:100::41: icmp6: echo reply seq 1 7.697167 port24 out 2001:10:1:100::ac10:c89c -> 2000:10:1:100::41: icmp6: echo reply seq 1 11 packets received by filter 0 packets dropped by kernel