1. 简介
什么是 Thread?
Thread 是一种基于 IP 的低功耗无线网状网络协议,可实现安全的设备到设备通信和设备到云通信。线程网络可以适应拓扑变化,以避免单点故障。
什么是 OpenThread?
Google 发布的 OpenThread 是 Thread® 的开源实现。
什么是 OpenThread 边界路由器?
Google 发布的 OpenThread 边界路由器 (OTBR) 是 Thread 边界路由器的开源实现。
NAT64
NAT64 是一种机制,可让仅限 IPv6 的网络中的主机访问 IPv4 网络中的资源。NAT64 网关是 IPv4 协议和 IPv6 协议之间的转换器。
NAT64 转换器是 OpenThread 边界路由器的一部分,支持转换 TCP、UDP 和 ICMP (ICMPv6) 协议。
构建内容
在此 Codelab 中,您将设置 OpenThread 边界路由器 (OTBR) 和 Thread 设备,然后通过 OpenThread 边界路由器启用并验证 Thread 设备与互联网上的 IPv4 主机之间的通信。
学习内容
- 如何构建具有 NAT64 功能的 OpenThread 边界路由器。
- 如何通过 Thread 端设备与 IPv4 主机通信。
所需条件
- 一台 Linux 工作站,用于构建和刷写 Thread RCP、OpenThread CLI 以及测试 IPv4 连接。
- 用于 Thread 边界路由器的 Raspberry Pi。您应该能够通过 IPv4 从此设备访问 Linux 工作站。
- 2 个 Nordic Semiconductor nRF52840 USB 加密狗(一个用于 RCP,另一个用于 Thread 端设备)。
此 Codelab 的网络拓扑如下所示:
2. 设置 OpenThread 边界路由器
如需快速设置 OTBR,请按照 OTBR 设置指南中的说明操作。
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 构建 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 Codelab 构建 Thread 网络”中的说明继续操作。使用 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 地址。
您可以随时在边界路由器上运行此命令,了解它如何统计流量。
向 IPv4 DNS 服务器发送 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 进行通信
在 IPv4 网络中,Thread 设备和主机之间可以使用 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 端设备提供互联网访问权限!
深入阅读
- OpenThread 指南
- OpenThread CLI 参考文档
- 适用于 NAT64 的 OpenThread API 参考文档
- 上游 DNS 的 OpenThread API 参考文档
- 适用于 DNS 的 OpenThread 平台抽象