NAT64 + DNS64 上网
NAT64 + DNS64 上网
网络需求
内网用户为 IPv6 网络,Internet 网络为 IPv4 网络,内部 IPv6 用户通过 NAT64 + DNS64 访问 IPv4 的 Internet 网络。
网络拓扑

- Client 侧为 IPv6,Server 侧为 IPv4,FortiGate 做 NAT64 + DNS64 转换,内部 IPv6 用户通过 NAT64 + DNS64 访问 IPv4 的 Internet 网络。
- 配置 IPv6 Client 的 IPv6 为 2100
1,FortiGate 内网口 lan 的 IPv6 为 2100::1/64。 - 配置 FortiGate 外网口 wan1 的 IP 为 10.10.12.2/24,默认路由指向 IPv4 Internet 10.10.12.1。
配置步骤
NAT64 配置
创建 VIP,选择类型为 IPv6,“外部 IP 地址/范围”填写 IPv6 VIP 地址,“映射到”选择 Use Embedded,这里填写的 IPv6 地址范围要写 96 位的 IPv6 前缀(注意不要配置和接口 IPv6 地址相同的网段),最后 32 位范围为 0.0.0.0~255.255.255.255 的 16 进制格式,用于映射所有的 IPv4 地址。

config firewall vip6 edit "NAT64_DNS64" set uuid f913176c-48aa-51ee-62dd-5d5b772dede2 set extip 2200::-2200::ffff:ffff set nat66 disable set nat64 enable set embedded-ipv4-address enable next end可以看默认存在一个 naf.root 接口,用于处理 NAT64 流量,创建 VIP 完成后,如果开启了 add-nat64-route(默认开启),针对 naf.root 接口生成去往 VIP IPv6 地址的路由,关闭 add-nat64-route 后,该路由会消失。


创建 IPv4 Pool,配置地址池范围,配置地址池范围,注意不要和 wan1 地址冲突,开启 NAT64 后,须填写为一个完整的 subnet(最小 32 位)的 IPv4 地址范围。

config firewall ippool edit "NAT64_DNS64" set startip 10.10.12.128 set endip 10.10.12.255 set nat64 enable set add-nat64-route enable next end创建完成后,如果开启了 add-nat64-route(默认开启),可以看到生成了 IPv4 的 kernel 路由,针对 naf.root 接口生成去往 IPPool IPv4 地址的路由,IPPool 关闭 NAT64 或关闭 add-nat64-route 后,该路由会消失。
FortiGate # get router info kernel | grep naf tab=254 vf=0 scope=0 type=1 proto=11 prio=0 0.0.0.0/0.0.0.0/0->10.10.12.128/25 pref=0.0.0.0 gwy=0.0.0.0 dev=37(naf.root)创建防火墙策略,,在源地址中引用 IPv6 的 all,然后在目标地址中引用 VIP,在 IP 池配置中引用 IPPool。

config firewall policy edit 9 set name "NAT64_DNS64" set srcintf "lan" set dstintf "wan1" set action accept set nat64 enable set srcaddr "all" set dstaddr "all" set srcaddr6 "all" set dstaddr6 "NAT64_DNS64" set schedule "always" set service "ALL" set ippool enable set poolname "NAT64_DNS64" next end
DNS64 配置
在 CLI 下开启 DNS64,配置 dns64-prefix 为 NAT64 VIP 的前 96 位 2200::/96,确认 always-synthesize-aaaa-record 为开启状态(默认开启)。
config system dns64 set status enable set dns64-prefix 2200::/96 set always-synthesize-aaaa-record enable end重要
- enable:默认配置,所有从 IPv6 客户端发送的 DNS AAAA Record 请求会被 FortiGate 无条件转换为 A Record 请求,通过 IPv4 DNS 发送至系统配置的 DNS 服务器(不会发送 AAAA 请求),IPv4 DNS 服务器返回 A Record 后,将 A Record 中的 IPv4 地址嵌入 dns64-prefix 的后 32 位中,然后封装为 IPv6 的 AAAA Record 回应,返回给 IPv6 客户端。
- disable:所有从 IPv6 客户端发送的 DNS AAAA Record 请求首先会被 FortiGate 封装在 IPv4 的 DNS 报文中发送至系统配置的 DNS 服务器:
- 如果 DNS 服务器返回了 AAAA Record,FortiGate 将此 AAAA Record 回应封装为 IPv6 DNS 返回给 IPv6 客户端(这里返回的 AAAA Record 为原服务器响应的 IPv6,FortiGate 不做任何修改)。
- 如果 DNS 服务器返回的 DNS 报文中没有 AAAA Record 的 IPv6 地址或没有响应 DNS 请求,FortiGate 会执行 always-synthesize-aaaa-record enable 时相同的操作,向 DNS 服务器发送 A Record 请求的 IPv4 DNS 报文,IPv4 DNS 服务器返回 A Record 后,将 A Record 中的 IPv4 地址嵌入 dns64-prefix 的后 32 位中,然后封装为 IPv6 的 AAAA Record 回应,返回给 IPv6 客户端。
- 当 always-synthesize-aaaa-record 配置为 disable 时,DNS 服务器返回的 AAAA Record 会被 FortiGate 不经修改直接返回给 IPv6 客户端,客户端访问此 IPv6 时,可能不在 NAT64 VIP 的 IPv6 地址范围中,导致被 FortiGate 丢弃,所以建议 always-synthesize-aaaa-record 的配置保持默认开启,不要关闭。
- 关于 always-synthesize-aaaa-record 的说明请参考官方文档:https://docs.fortinet.com/document/fortigate/7.99.99/administration-guide/443324/nat64-policy-and-dns64-dns-proxy 。
在 lan 口上开启 DNS 服务器,IPv6 网络侧用户发起 AAAA Record 查询,FortiGate 的 DNS64 代理请求 IPv4 网络中对应 FQDN 的 A Record,得到 A Record 响应后,DNS64 服务器将 A Record 响应中的 IPv4 地址嵌入 dns64-prefix 的后 32 位中,然后封装为 IPv6 的 AAAA Record 回应,返回给 IPv6 客户端。

config system dns-server edit "lan" next end为系统配置 IPv4 DNS 服务器(也可以使用默认服务器)。

config system dns set primary 223.5.5.5 end
结果验证
IPv6 Client 访问 IPv4 Internet 域名,抓包查看 DNS64 过程,客户端发出 IPv6 的 AAAA 请求,请求域名 www.fortinet.com 的 AAAA Record。

FortiGate 将此 AAAA Record 请求转换为 A Record 请求封装在 IPv4 DNS 中,发送给 DNS 服务器 223.5.5.5。

DNS 服务器使用 IPv4 DNS 返回该域名的 A Record IPv4 地址 52.220.222.172。

FortiGate 收到 DNS 返回的该域名的 A Record IPv4 地址 52.220.222.172 转换为 16 进制后将其嵌入 dns64-prefix 2100
34dc:deac,将其转换为 AAAA Record,并封装在 IPv6 DNS 报文中返回给 IPv6 Client。 
客户端收到 FortiGate 发送的 AAAA Record 回应后,解析到 www.fortinet.com 的 IPv6 IP 为 2200::34dc:deac,所以直接访问该 IPv6 地址,FortiGate 从 lan 口收到该 IPv6 请求包。

该 IPv6 请求包经由 FortiGate 的 naf 接口,执行 NAT64 转换。

经由 FortiGate 的 naf 接口进行 NAT64 后,转换为 IPv4 报文,源地址为 NAT64 的地址池中的 IPv4 地址,目标地址为原 IPv6 请求包目标 IPv6 地址 2200::34dc:deac 的最后 32 位转换为 10 进制后的 IPv4 地址 52.220.222.172。

最终由 wan1 接口发出送往 Internet 上的目的 IPv4 地址。

服务器 Reply 的 IPv4 报文从 FortiGate 的 wan1 收到,经由 naf 接口做 NAT64 还原后,从 lan 口返回 IPv6 Client。

查看 IPv6 会话,如下所示,会话没有被 NP 加速,流量均经过 naf 接口处理,naf 标记为 1。
FortiGate # diagnose sys session6 list
session6 info: proto=58 proto_state=00 duration=110 expire=59 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=may_dirty npu npd
statistic(bytes/packets/allow_err): org=6160/110/0 reply=6160/110/0 tuples=2
tx speed(Bps/kbps): 54/0 rx speed(Bps/kbps): 56/0
orgin->sink: org pre->post, reply pre->post dev=45->37/37->45
hook=pre dir=org act=noop 2100::2:33956->2200::34dc:deac:128(:::0)
hook=post dir=reply act=noop 2200::34dc:deac:33956->2100::2:129(:::0)
peer=10.10.12.130:30184->52.220.222.172:8 naf=1
hook=pre dir=org act=noop 10.10.12.130:30184->52.220.222.172:8(0.0.0.0:0)
hook=post dir=reply act=noop 52.220.222.172:30184->10.10.12.130:0(0.0.0.0:0)
src_mac=0c:37:96:06:d7:5d
misc=0 policy_id=9 pol_uuid_idx=587 auth_info=0 chk_client_info=0 vd=0
serial=0000a1d7 tos=ff/ff ips_view=0 app_list=0 app=0 url_cat=0
rpdb_link_id=00000000 ngfwid=n/a
npu_state=0x4040000
npu info: flag=0x81/0x00, offload=0/0, ips_offload=0/0, epid=0/0, ipid=95/0, vlan=0x0000/0x0000
vlifid=0/0, vtag_in=0x0000/0x0000 in_npu=0/0, out_npu=0/0, fwd_en=0/0, qid=0/0
no_ofld_reason: offload-denied
FortiGate # diagnose netlink interface list | grep naf
if=naf.root family=00 type=65535 index=37 mtu=1500 link=0 master=0查看 IPv4 会话,如下所示,会话没有被 NP 加速,流量均经过 naf 接口处理,naf 标记为 2。
FortiGate # diagnose sys session list session info: proto=1 proto_state=00 duration=1 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=may_dirty npu statistic(bytes/packets/allow_err): org=72/2/1 reply=72/2/1 tuples=2 tx speed(Bps/kbps): 57/0 rx speed(Bps/kbps): 57/0 orgin->sink: org pre->post, reply pre->post dev=37->7/7->37 gwy=10.10.12.1/10.10.12.130 hook=pre dir=org act=noop 10.10.12.130:30184->52.220.222.172:8(0.0.0.0:0) hook=post dir=reply act=noop 52.220.222.172:30184->10.10.12.130:0(0.0.0.0:0) peer=2200::34dc:deac:33956->2100::2:129 naf=2 hook=pre dir=org act=noop 2100::2:33956->2200::34dc:deac:128(:::0) hook=post dir=reply act=noop 2200::34dc:deac:33956->2100::2:129(:::0) misc=0 policy_id=9 pol_uuid_idx=587 auth_info=0 chk_client_info=0 vd=0 serial=000ecb4f tos=ff/ff app_list=0 app=0 url_cat=0 rpdb_link_id=00000000 ngfwid=n/a npu_state=0x4040000 npu info: flag=0x00/0x00, offload=0/0, ips_offload=0/0, epid=0/0, ipid=0/0, vlan=0x0000/0x0000 vlifid=0/0, vtag_in=0x0000/0x0000 in_npu=0/0, out_npu=0/0, fwd_en=0/0, qid=0/0 no_ofld_reason: FortiGate # diagnose netlink interface list | grep naf if=naf.root family=00 type=65535 index=37 mtu=1500 link=0 master=0IPv6 客户端可以正常访问 IPv6 的服务器。


附件
附 NAT64 + DNS64 过程抓取的报文:dns64.pcapng。