Fortinet black logo

Administration Guide

NAT46 and NAT64 policy and routing configurations

NAT46 and NAT64 policy and routing configurations

Multiple NAT46 and NAT64 related objects are consolidated into regular objects. A per-VDOM virtual interface, naf.<vdom>, is automatically added to process NAT46/NAT64 traffic. The features include:

  • vip46 and vip64 settings are consolidated in vip and vip6 configurations.
  • policy46 and policy64 settings are consolidated in firewall policy settings.
  • nat46/nat64 are included in firewall policy settings.
  • ippool and ippool6 support NAT46 and NAT64 (when enabled, the IP pool should match a subnet).
  • Central SNAT supports NAT46 and NAT64.
  • add-nat46-route in ippool6 and add-nat64-route in ippool are enabled by default. The FortiGate generates a static route that matches the IP range in ippool6 or ippool for the naf tunnel interface.
Note

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.

Note

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:
  1. Configure the VIP:
    1. Go to Policy & Objects > Virtual IPs and click Create New > VIP.
    2. 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

    3. Click OK.
  2. Configure the IPv6 pool:
    1. Go to Policy & Objects > IP Pools and click Create New.
    2. 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

    3. Click OK.
  3. Configure the firewall policy:
    1. Go to Policy & Objects > Firewall Policy and click Create New or edit an existing policy.
    2. 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

    3. Configure the other settings as needed.

    4. Click OK.
To create a NAT46 policy in the CLI:
  1. 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
  2. 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
  3. 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:
  1. 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
  2. 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:
  1. Configure the VIP:
    1. Go to Policy & Objects > Virtual IPs and click Create New > VIP.
    2. 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

    3. Click OK.
  2. Configure the VIP with the embedded IPv4 address enabled:
    1. Go to Policy & Objects > Virtual IPs and click Create New > VIP.
    2. 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

    3. Click OK.
  3. Configure the IP pool:
    1. Go to Policy & Objects > IP Pools and click Create New.
    2. 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

    3. Click OK.
  4. Configure the firewall policy:
    1. Go to Policy & Objects > Firewall Policy and click Create New or edit an existing policy.
    2. Enter the following:
    3. 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

    4. Configure the other settings as needed.

    5. Click OK.
To create a NAT64 policy in the CLI:
  1. 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
  2. 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
  3. 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
  4. 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:
  1. 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
  2. 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.

  3. 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

NAT46 and NAT64 policy and routing configurations

Multiple NAT46 and NAT64 related objects are consolidated into regular objects. A per-VDOM virtual interface, naf.<vdom>, is automatically added to process NAT46/NAT64 traffic. The features include:

  • vip46 and vip64 settings are consolidated in vip and vip6 configurations.
  • policy46 and policy64 settings are consolidated in firewall policy settings.
  • nat46/nat64 are included in firewall policy settings.
  • ippool and ippool6 support NAT46 and NAT64 (when enabled, the IP pool should match a subnet).
  • Central SNAT supports NAT46 and NAT64.
  • add-nat46-route in ippool6 and add-nat64-route in ippool are enabled by default. The FortiGate generates a static route that matches the IP range in ippool6 or ippool for the naf tunnel interface.
Note

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.

Note

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:
  1. Configure the VIP:
    1. Go to Policy & Objects > Virtual IPs and click Create New > VIP.
    2. 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

    3. Click OK.
  2. Configure the IPv6 pool:
    1. Go to Policy & Objects > IP Pools and click Create New.
    2. 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

    3. Click OK.
  3. Configure the firewall policy:
    1. Go to Policy & Objects > Firewall Policy and click Create New or edit an existing policy.
    2. 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

    3. Configure the other settings as needed.

    4. Click OK.
To create a NAT46 policy in the CLI:
  1. 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
  2. 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
  3. 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:
  1. 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
  2. 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:
  1. Configure the VIP:
    1. Go to Policy & Objects > Virtual IPs and click Create New > VIP.
    2. 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

    3. Click OK.
  2. Configure the VIP with the embedded IPv4 address enabled:
    1. Go to Policy & Objects > Virtual IPs and click Create New > VIP.
    2. 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

    3. Click OK.
  3. Configure the IP pool:
    1. Go to Policy & Objects > IP Pools and click Create New.
    2. 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

    3. Click OK.
  4. Configure the firewall policy:
    1. Go to Policy & Objects > Firewall Policy and click Create New or edit an existing policy.
    2. Enter the following:
    3. 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

    4. Configure the other settings as needed.

    5. Click OK.
To create a NAT64 policy in the CLI:
  1. 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
  2. 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
  3. 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
  4. 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:
  1. 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
  2. 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.

  3. 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