Thread Border Router - 通过 NAT64 提供互联网访问权限

关于此 Codelab
schedule23 分钟
subject上次更新时间:2025年4月28日
account_circleSong Guo, Jonathan Hui 编写

1. 简介

7299534792dd9439

什么是 Thread?

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

什么是 OpenThread?

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

什么是 OpenThread 边界路由器?

Google 发布的 OpenThread 边界路由器 (OTBR) 是线程边界路由器的开源实现。

NAT64

NAT64 是一种机制,使 IPv6 单栈网络中的主机能够访问 IPv4 网络中的资源。NAT64 网关是 IPv4 协议和 IPv6 协议之间的转换器。

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

构建内容

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

学习内容

  • 如何构建具有 NAT64 功能的 OpenThread 边界路由器。
  • 如何通过 Thread 终端设备与 IPv4 主机通信。

所需条件

  • Linux 工作站,用于构建和刷写 Thread RCP、OpenThread CLI,以及测试 IPv4 连接。
  • 用于 Thread 边界路由器的 Raspberry Pi。您的 Linux 工作站应该可以通过 IPv4 从此设备访问。
  • 2 台 Nordicor nRF52840 USB 加密狗(一个用于 RCP,一个用于 Thread 终端设备)。

此 Codelab 的网络拓扑:

c3cd2e081bc052fd.png

2. 设置 OpenThread 边界路由器

设置 OTBR 的最快方法是按照“带 Docker 的 OTBR”指南使用 Docker。

OTBR 设置完成后,使用 ot-ctl 验证边界路由器上是否已启用 NAT64 服务:

> nat64 state
PrefixManager: Active
Translator: Active
Done

Thread 边界路由器在 Thread 网络数据中发布 NAT64 前缀:

> netdata show
Prefixes:
fd16:a3d:e170:1::/64 paros low f800
Routes:
::/0 s med f800
fd16:a3d:e170:2:0:0::/96 sn low f800
Services:
44970 5d fd4db3e59738319339c4ee02ca9e2b1dd120 s f800 0
Contexts:
fd16:a3d:e170:1::/64 1 sc
Commissioning:
60365 - - -
Done

NAT64 前缀显示为带有 n 标志的路由条目。在上面的示例中,fd16:a3d:e170:2:0:0::/96 是 NAT64 前缀。

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

3. 设置 Thread 终端设备

按照“使用 nRF52840 开发板和 OpenThread”Codelab 设置 Thread 网络的 FTD 步骤构建并刷写 nRF52840 CLI 终端设备,并更改以下步骤:

构建和刷写中,调用 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_DNS_CLIENT=ON -DOT_SRP_CLIENT=ON -DOT_ECDSA=ON

继续完成“使用 nRF52840 开发板和 OpenThread 构建 Thread 网络”Codelab。当终端设备刷入 CLI 映像后,请按照将第二个节点加入 Thread 网络操作,将 Thread 设备添加到 Thread 网络。

设置 Thread 终端设备后,等待几秒钟,并验证加入 Thread 网络是否成功。如上所述,您可以在“线程网络数据”中查看已发布的 NAT64 前缀。

> netdata show
Prefixes:
fd16:a3d:e170:1::/64 paros low f800
Routes:
::/0 s med f800
fd16:a3d:e170:2:0:0::/96 sn low f800
Services:
44970 5d fd4db3e59738319339c4ee02ca9e2b1dd120 s f800 0
Contexts:
fd16:a3d:e170:1::/64 1 sc
Commissioning:
60365 - - -
Done

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

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

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

向 IPv4 主机发送 ICMP 回显请求

从 Thread 终端设备的 CLI 中:

> ping 8.8.8.8
Pinging synthesized IPv6 address: fd16:a3d:e170:2:0:0:808:808
16 bytes from fd16:a3d:e170:2:0:0:808:808: icmp_seq=1 hlim=109 time=28ms
1 packets transmitted, 1 packets received. Packet loss = 0.0%. Round-trip min/avg/max = 28/28.0/28 ms.
Done

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

> nat64 mappings
|                  | Address                                                     | Ports or ICMP Ids |        | 4 to 6                  | 6 to 4                  |
+------------------+-------------------------------------------------------------+-------------------+--------+-------------------------+-------------------------+
| ID               | IPv6                                     | IPv4             | v6      | v4      | Expiry | Pkts     | Bytes        | Pkts     | Bytes        |
+------------------+------------------------------------------+------------------+---------+---------+--------+----------+--------------+----------+--------------+
| 90b156e3cf609a23 |      fd16:a3d:e170:1:492d:bcdb:9f72:6297 |  192.168.255.254 |   N/A   |   N/A   |  7162s |        1 |           16 |        1 |           16 |
|                  |                                                                                      TCP |        0 |            0 |        0 |            0 |
|                  |                                                                                      UDP |        0 |            0 |        0 |            0 |
|                  |                                                                                     ICMP |        1 |           16 |        1 |           16 |
Done

fd16:a3d:e170:1:492d:bcdb:9f72:6297 应该是 Thread 设备的 IPv6 地址。

随时在边界路由器上运行此命令,了解其如何计算流量。

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

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

> dns resolve4 example.com 8.8.8.8
Synthesized IPv6 DNS server address: fd16:a3d:e170:2:0:0:808:808
DNS response for example.com. - fd16:a3d:e170:2:0:0:17c0:e454 TTL:295 fd16:a3d:e170:2:0:0:17d7:88 TTL:295 fd16:a3d:e170:2:0:0:17d7:8a TTL:295 fd16:a3d:e170:2:0:0:6007:80af TTL:295 fd16:a3d:e170:2:0:0:6007:80c6 TTL:295 fd16:a3d:e170:2:0:0:17c0:e450 TTL:295 
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: fd16:a3d:e170:2:0:0:c0a8:2
Done
> tcp send hello

您的 Linux IPv4 主机输出以下内容:

hello

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

TCP: Received 6 bytes: world

通过 UDP 通信

Thread 设备和 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: fd16:a3d:e170:2:0:0:c0a8:2
Done
> udp send hello
Done

您的 Linux IPv4 主机输出以下内容:

hello

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

6 bytes from fd16:a3d:e170:2:0:0:c0a8:2 12345 world

5. 在边界路由器上开启 NAT64

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

> nat64 disable
Done
> nat64 state
PrefixManager: Disabled
Translator: Disabled
Done

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

> netdata show
Prefixes:
fd16:a3d:e170:1::/64 paros low f800
Routes:
::/0 s med f800
Services:
44970 5d fd4db3e59738319339c4ee02ca9e2b1dd120 s f800 0
Contexts:
fd16:a3d:e170:1::/64 1 sc
Commissioning:
60365 - - -
Done

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

从 Thread 终端设备的 CLI 中:

> ping 8.8.8.8
Error 13: InvalidState

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

> nat64 enable
Done
> nat64 state
PrefixManager: Idle
Translator: NotWorking
Done

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

> nat64 state
PrefixManager: Active
Translator: Active
Done
> netdata show
Prefixes:
fd16:a3d:e170:1::/64 paros low f800
Routes:
::/0 s med f800
fd16:a3d:e170:2:0:0::/96 sn low f800
Services:
44970 5d fd4db3e59738319339c4ee02ca9e2b1dd120 s f800 0
Contexts:
fd16:a3d:e170:1::/64 1 sc
Commissioning:
60365 - - -
Done

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

> nat64 mappings
|                  | Address                                                     | Ports or ICMP Ids |        | 4 to 6                  | 6 to 4                  |
+------------------+-------------------------------------------------------------+-------------------+--------+-------------------------+-------------------------+
| ID               | IPv6                                     | IPv4             | v6      | v4      | Expiry | Pkts     | Bytes        | Pkts     | Bytes        |
+------------------+------------------------------------------+------------------+---------+---------+--------+----------+--------------+----------+--------------+
Done

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

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

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

> dns config
Server: [fd4d:b3e5:9738:3193:39c4:ee02:ca9e:2b1d]:53
ResponseTimeout: 6000 ms
MaxTxAttempts: 3
RecursionDesired: yes
ServiceMode: srv_txt_opt
Nat64Mode: allow
Done

服务器 IPv6 地址(上述示例中的 fd4d:b3e5:9738:3193:39c4:ee02:ca9e:2b1d)应该是 OpenThread 边界路由器的地址之一。

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

> dns resolve example.com
DNS response for example.com. - 2600:1406:3a00:21:0:0:173e:2e65 TTL:161 2600:1406:3a00:21:0:0:173e:2e66 TTL:161 2600:1406:bc00:53:0:0:b81e:94c8 TTL:161 2600:1406:bc00:53:0:0:b81e:94ce TTL:161 2600:1408:ec00:36:0:0:1736:7f24 TTL:161 2600:1408:ec00:36:0:0:1736:7f31 TTL:161 
Done
> dns resolve4 example.com
DNS response for example.com. - fd16:a3d:e170:2:0:0:6007:80af TTL:300 fd16:a3d:e170:2:0:0:6007:80c6 TTL:300 fd16:a3d:e170:2:0:0:17c0:e450 TTL:300 fd16:a3d:e170:2:0:0:17c0:e454 TTL:300 fd16:a3d:e170:2:0:0:17d7:88 TTL:300 fd16:a3d:e170:2:0:0:17d7:8a TTL:300 
Done

7. 恭喜

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

深入阅读

参考文档