线程边界路由器 - 通过 NAT64 提供互联网访问权限

1. 简介

7299534792dd9439.png

什么是 Thread?

Thread 是基于 IP 的低功耗无线网状网络协议,支持设备到设备和设备到云的安全通信。线程网络可以适应拓扑变化,以避免单点故障。

什么是 OpenThread?

Google 发布的 OpenThread 是 Thread® 的开源实现。

什么是 OpenThread 边界路由器?

Google 发布的 OpenThread Border Router (OTBR) 是 Thread Border Router 的开源实现。

NAT64

NAT64 是一种机制,可让纯 IPv6 网络中的主机访问 IPv4 网络中的资源。NAT64 网关是 IPv4 协议和 IPv6 协议之间的转换程序。

NAT64 转换工具作为 OpenThread 边界路由器的一部分,支持转换 TCP、UDP 和 ICMP (ICMPv6) 协议。

构建内容

在此 Codelab 中,您将设置 OpenThread 边界边界和 Thread 设备,然后通过 OpenThread 边界路由器启用并验证 Thread 设备与互联网上的 IPv4 主机之间的通信。

学习内容

  • 如何使用 NAT64 功能构建 OpenThread 边界路由器。
  • 如何从 Thread 终端设备与 IPv4 主机通信。

所需条件

  • 用于构建和刷写 Thread NCP、OpenThread CLI 和测试 IPv4 连接的 Linux 工作站。
  • 线程线程路由器的 RAM 为 4GB 的 Raspberry Pi 4。应可通过此设备访问 IPv4 的 Linux 工作站。
  • 2 款北欧半导体 nRF52840 DK 开发板。

此 Codelab 的网络拓扑:

c3cd2e081bc052fd.png

2. 设置 OpenThread 边界路由器

按照“线程边界路由器 - 双向 IPv6 连接和基于 DNS 的服务发现”Codelab 的“设置 OTBR”步骤构建 OpenThread 边界路由器,并做出以下更改:

构建和安装 OTBR 中,您需要将环境变量 NAT64 设置为 1,并将 NAT64_SERVICE 设置为 openthread,以指示脚本在 OpenThread 中启用 NAT64 转换器。在执行步骤之前运行以下命令:

$ export NAT64=1 NAT64_SERVICE=openthread

继续阅读线程边界路由器 - 双向 IPv6 连接和基于 DNS 的服务发现 Codelab。在形成线程网络后,您可以通过 OpenThread CLI 命令验证边界路由器是否发布了 NAT64 前缀。

首先,请确保边界路由器已启动并运行,并且边界路由器上启用了 NAT64:

$ sudo ot-ctl state
leader
Done
$ sudo ot-ctl nat64 enable
Done
$ sudo ot-ctl nat64 state
PrefixManager: Active
Translator: Active
Done

我们应该可以看到,OTBR 充当了线程主管,线程数据中有一个 NAT64 前缀(在本例中为 fd4c:9574:3720:2:0:0::/96):

$ sudo ot-ctl netdata show
Prefixes:
fd4c:9574:3720:1::/64 paos low 0800
Routes:
fd49:7770:7fc5:0::/64 s med 0800
fd4c:9574:3720:2:0:0::/96 sn low 0800
Services:
44970 01 41000500000e10 s 0800
44970 5d fdd20e532b87b93f50ad4eea0450f1bfd11f s 0800
Done

Thread 设备在与 IPv4 主机通信时将使用 NAT64 前缀。

3. 设置线程结束设备

按照使用 nRF52840 开发板和 OpenThread Codelab 设置 FTD 步骤构建并刷写 nRF52840 CLI 终端设备,同时更改后续步骤:

Build & flash 中,调用 script/build 时,必须将 -DOT_DNS_CLIENT=ON-DOT_SRP_CLIENT=ON-DOT_ECDSA=ON 附加到命令行:

$ cd ~/src/ot-nrf528xx
$ rm -rf build
$ script/build nrf52840 USB_trans -DOT_JOINER=ON -DOT_COMMISSIONER=ON -DOT_DNS_CLIENT=ON -DOT_SRP_CLIENT=ON -DOT_ECDSA=ON

继续阅读编写采用 nRF52840 开发板和 OpenThread 的 Thread 网络。使用 CLI 映像刷写最终用户后,请遵循线程边界路由器 - 双向 IPv6 连接和基于 DNS 的服务发现来设置 Thread 终端设备。

设置 Thread 终端设备后,请等待几秒钟,然后验证能否成功加入 Thread 网络。您应该能够从网络数据中找到 NAT64 前缀(在本例中为 fd4c:9574:3720:2:0:0::/96):

> netdata show
Prefixes:
fd4c:9574:3720:1::/64 paos low 0800
Routes:
fd49:7770:7fc5:0::/64 s med 0800
fd4c:9574:3720:2:0:0::/96 sn low 0800
Services:
44970 01 41000500000e10 s 0800
44970 5d fdd20e532b87b93f50ad4eea0450f1bfd11f s 0800
Done

请确保网络数据与 OTBR 中的数据一致。

4. 从 Thread 终端设备与 IPv4 主机通信

您现在可以通过我们刚刚设置的终端设备与 IPv4 网络上的主机通信。

向 IPv4 主机发送 ICMP echo 请求

通过我们的 Thread 终端设备的 CLI:

> ping 8.8.8.8
Pinging synthesized IPv6 address: fd4c:9574:3720:2:0:0:808:808
16 bytes from fd4c:9574:3720:2:0:0:808:808: icmp_seq=15 hlim=119 time=48ms
1 packets transmitted, 1 packets received. Packet loss = 0.0%. Round-trip min/avg/max = 48/48.0/48 ms.
Done

边界路由器通过 nat64 mappings 命令为此设备创建 NAT64 映射项:

$ sudo ot-ctl nat64 mappings
|                  | Address                                                     |        | 4 to 6                  | 6 to 4                  |
+------------------+-------------------------------------------------------------+--------+-------------------------+-------------------------+
| ID               | IPv6                                     | IPv4             | Expiry | Pkts     | Bytes        | Pkts     | Bytes        |
+------------------+------------------------------------------+------------------+--------+----------+--------------+----------+--------------+
| 377ee63dd3127f1a |     fd4c:9574:3720:1:1d61:b4c1:494f:f975 |  192.168.255.254 |  7190s |        1 |           16 |        1 |           16 |
|                  |                                                                  TCP |        0 |            0 |        0 |            0 |
|                  |                                                                  UDP |        0 |            0 |        0 |            0 |
|                  |                                                                 ICMP |        1 |           16 |        1 |           16 |
Done

fd4c:9574:3720:1:1d61:b4c1:494f:f975 应该是您的 Thread 设备的 IPv6 地址。

您可随时在边界路由器上运行此命令,看看它会如何计算流量。

将 DNS 查询发送到 IPv4 DNS 服务器

使用 dns resolve4 解析 IPv4 网络上的主机名。DNS 服务器地址也可以是 IPv4 地址:

> dns resolve4 example.com 8.8.8.8
Synthesized IPv6 DNS server address: fd4c:9574:3720:2:0:0:808:808
DNS response for example.com. - fd4c:9574:3720:2:0:0:5db8:d822 TTL:20456 
Done

通过 TCP 进行通信

您可以在 IPv4 网络中的终端设备和主机之间建立 TCP 连接。

假设您的 Linux IPv4 主机的 IP 地址为 192.168.0.2

在 Linux IPv4 主机上,使用 nc 监听 TCP 连接:

$ nc -l 0.0.0.0 12345

在 Thread 终端设备上,建立 TCP 连接并向 Linux IPv4 主机发送消息:

> tcp init
Done
> tcp connect 192.168.0.2 12345
Connecting to synthesized IPv6 address: fd4c:9574:3720:2:0:0:c0a8:2
Done
> tcp send hello

您的 Linux IPv4 主机输出:

hello

您还可以从 Linux IPv4 主机向 Thread 终端设备发送消息。在运行“nc”的 Linux IPv4 主机上,输入“world”,然后按 Enter 键,线程会话设备输出如下:

TCP: Received 6 bytes: world

通过 UDP 进行通信

可以在 IPv4 网络中的线程设备和主机之间使用 UDP 通信。

假设您的 Linux IPv4 主机的 IP 地址为 192.168.0.2

使用 nc 监听 UDP 连接:

$ nc -u -l 0.0.0.0 12345

在 Thread 终端设备上,建立 UDP 连接并将消息发送到 Linux IPv4 主机:

> udp open
Done
> udp connect 192.168.0.2 12345
Connecting to synthesized IPv6 address: fd4c:9574:3720:2:0:0:c0a8:2
Done
> udp send hello
Done

您的 Linux IPv4 主机输出:

hello

您还可以从 Linux IPv4 主机向 Thread 终端设备发送消息。在运行“nc”的 Linux IPv4 主机上,输入“world”,然后按 Enter 键,线程会话设备输出如下:

6 bytes from fd4c:9574:3720:2:0:0:c0a8:2 12345 world

5. 在边界路由器上切换 NAT64

您可以随时启用或停用 NAT64。使用 nat64 disable 停用 NAT64。并使用 nat64 state 检查 NAT64 的状态。

$ sudo ot-ctl nat64 disable
Done
$ sudo ot-ctl nat64 state
PrefixManager: Disabled
Translator: Disabled
Done

停用后,设备将不再发布 NAT64 前缀:

$ sudo ot-ctl netdata show
Prefixes:
fd4c:9574:3720:1::/64 paos low 0800
Routes:
fd49:7770:7fc5:0::/64 s med 0800
Services:
44970 01 41000500000e10 s 0800
44970 5d fdd20e532b87b93f50ad4eea0450f1bfd11f s 0800
Done

此外,Thread 网络中的设备无法再通过此边界路由器访问 IPv4 主机。

通过我们的 Thread 终端设备的 CLI:

> ping 8.8.8.8
Error 13: InvalidState

使用 nat64 enable 启用 NAT64。前缀管理器可能需要一段时间才能开始通告 NAT64 前缀:

$ sudo ot-ctl nat64 enable
Done
$ sudo ot-ctl nat64 state
PrefixManager: Idle
Translator: NotWorking
Done

几秒钟后,NAT64 组件应该会启动并运行:

$ sudo ot-ctl nat64 state
PrefixManager: Active
Translator: Active
Done
$ sudo ot-ctl netdata show
Prefixes:
fd4c:9574:3720:1::/64 paos low 0800
Routes:
fd49:7770:7fc5:0::/64 s med 0800
fd4c:9574:3720:2:0:0::/96 sn low 0800
Services:
44970 01 41000500000e10 s 0800
44970 5d fdd20e532b87b93f50ad4eea0450f1bfd11f s 0800
Done

请注意,停用 NAT64 会清除映射表:

$ sudo ot-ctl nat64 mappings
|                  | Address                                                     |        | 4 to 6                  | 6 to 4                  |
+------------------+-------------------------------------------------------------+--------+-------------------------+-------------------------+
| ID               | IPv6                                     | IPv4             | Expiry | Pkts     | Bytes        | Pkts     | Bytes        |
+------------------+------------------------------------------+------------------+--------+----------+--------------+----------+--------------+
Done

6. 将 DNS 查询转发到上游 DNS 服务器

在边界路由器上启用 NAT64 后,OpenThread 会尝试将针对互联网网域的 DNS 查询转发到上游 DNS 服务器。

内部 DNS-SD 服务器支持此功能,因此您需要确保已启用 DNS-SD 服务器。

$ sudo ot-ctl srp server state
running
Done

如果不是 running,则启用它:

$ sudo ot-ctl srp server enable
Done

确保已启用上游 DNS 代理:

$ sudo ot-ctl dns server upstream
Enabled
Done

如果不是 Enabled,则启用它:

$ sudo ot-ctl dns server upstream enable
Done

在最终设备上,确保已启用 SRP 客户端,使其将 DNS 查询发送到边界路由器:

> srp client state
Enabled
Done

如果不是 Enabled,则启用它:

> srp client autostart enable
Done

在您的最终设备上,确保默认 DNS 服务器是边界路由器:

> dns config
Server: [fdd2:0e53:2b87:b93f:50ad:4eea:0450:f1bf]:53
ResponseTimeout: 6000 ms
MaxTxAttempts: 3
RecursionDesired: yes
Done

服务器 IPv6 地址(上例中的 fdd2:0e53:2b87:b93f:50ad:4eea:0450:f1bf)应为 OpenThread 边界路由器的地址之一。

现在,您可以从最终用户设备发送互联网网域的 DNS 查询:

> dns resolve example.com
DNS response for example.com. - 2606:2800:220:1:248:1893:25c8:1946 TTL:8720 
Done
> dns resolve4 example.com
DNS response for example.com. - fd4c:9574:3720:2:0:0:5db8:d822 TTL:20456 
Done

7. 恭喜

恭喜!您已成功设置支持 NAT64 的边界路由器,并使用它来通过 Thread 终端设备访问互联网!

深入阅读

参考文档