1. 简介
什么是 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 边界路由器和 Thread 设备,然后通过 OpenThread 边界路由器启用并验证 Thread 设备和互联网上的 IPv4 主机之间的通信。
学习内容
- 如何构建具有 NAT64 功能的 OpenThread 边界路由器。
- 如何通过 Thread 终端设备与 IPv4 主机通信。
所需条件
- Linux 工作站,用于构建和刷写 Thread NCP、OpenThread CLI,以及测试 IPv4 连接。
- 一个具有 4GB RAM 的 Raspberry Pi 4,用于 Thread 边界路由器。您的 Linux 工作站应该可以通过 IPv4 从此设备访问。
- 2 块北欧半导体 nRF52840 DK 开发板。
此 Codelab 的网络拓扑:
2. 设置 OpenThread 边界路由器
按照“线程边界路由器 - 双向 IPv6 连接和基于 DNS 的服务发现”Codelab 的“设置 OTBR”步骤中的说明构建 OpenThread 边界路由器,并做出以下更改:
在构建和安装 OTBR 中,您需要指示脚本在 OpenThread 中启用 NAT64 转换器,方法是将环境变量 NAT64
设置为 1
,将 NAT64_SERVICE
设置为 openthread
。在执行此步骤之前运行以下命令:
$ export NAT64=1 NAT64_SERVICE=openthread
继续学习线程边界路由器 - 双向 IPv6 连接和基于 DNS 的服务发现 Codelab。形成 Thread 网络后,您可以通过 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 充当 Thread 主节点,并且 Thread 网络数据中有 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. 设置 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_JOINER=ON -DOT_COMMISSIONER=ON -DOT_DNS_CLIENT=ON -DOT_SRP_CLIENT=ON -DOT_ECDSA=ON
继续完成“使用 nRF52840 开发板和 OpenThread 构建 Thread 网络”Codelab。在为终端设备刷入 CLI 映像后,按照 Thread Border Router - 双向 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 回显请求
从 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 主机上按 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: fd4c:9574:3720:2:0:0:c0a8:2 Done > udp send hello Done
您的 Linux IPv4 主机输出以下内容:
hello
您也可以从 Linux IPv4 主机向 Thread 终端设备发送消息。输入“世界”然后在运行 nc
的 Linux IPv4 主机上按 Enter 键,然后 Thread 终端设备会输出:
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 终端设备提供互联网访问权限!
深入阅读
- OpenThread 指南
- OpenThread CLI 参考文档
- 适用于 NAT64 的 OpenThread API 参考文档
- 适用于上游 DNS 的 OpenThread API 参考文档
- 适用于 DNS 的 OpenThread 平台抽象