Thread 邊界路由器 - 雙向 IPv6 連線和 DNS 型服務探索

1. 簡介

699d673d05a55535.png

什麼是 Thread?

Thread 是一種 IP 架構的低耗電無線網狀網路通訊協定,可實現安全的裝置對裝置和裝置對雲端通訊。Thread 網路可因應拓撲結構變更,避免單點故障。

什麼是 OpenThread?

Google 發布的 OpenThread 是 Thread® 的開放原始碼實作項目。

什麼是 Thread 邊界路由器?

Thread 邊界路由器可將 Thread 網路連線至其他 IP 網路,例如 Wi-Fi 或乙太網路。Thread 網路需要邊界路由器才能連線至其他網路。Thread 邊界路由器至少支援下列功能:

  • Thread 和 Wi-Fi/乙太網路之間的雙向 IP 連線。
  • 透過 mDNS (在 Wi-Fi/乙太網路連結上) 和 SRP (在 Thread 網路上) 進行雙向服務探索。
  • 透過 IP 連結合併 Thread 分區的 Thread-over-infrastructure。
  • 外部 Thread 委派 (例如手機),用於驗證並將 Thread 裝置加入 Thread 網路。

Google 發布的 OpenThread Border Router (OTBR) 是 Thread 邊界路由器的開放原始碼實作項目。

建構項目

在本程式碼研究室中,您將設定 Thread 邊界路由器,並透過邊界路由器將手機連線至 Thread 端點裝置。

課程內容

  • 如何設定 OTBR
  • 如何使用 OTBR 建立 Thread 網路
  • 如何建構具備 SRP 功能的 OpenThread CLI 裝置
  • 如何透過 SRP 註冊服務
  • 如何探索及連線至 Thread 端點裝置

軟硬體需求

  • Linux 工作站,用於建構及刷新 Thread RCP、OpenThread CLI,以及測試 IPv6 多點傳送。
  • 用於 Thread 邊界路由器的 Raspberry Pi。
  • 2 個 Nordic Semiconductor nRF52840 USB 轉接器 (一個用於 RCP,另一個用於 Thread 端裝置)。
  • 搭載 iOS 14 以上版本的 iOS 手機,或搭載 Android 8.1 以上版本的 Android 手機。

2. 設定 OTBR

如要快速設定 OTBR,請按照OTBR 設定指南操作。

OTBR 設定完成後,請使用 ot-ctl 驗證 OTBR 是否以 Thread leader 的形式運作。

$ sudo ot-ctl state
leader
Done

另外,請確認 OTBR 是否已在 Thread 網路資料中自動設定 off-mesh-routable (OMR) 前置字串。

$ sudo ot-ctl netdata show
Prefixes:
Prefixes:
fd76:a5d1:fcb0:1707::/64 paos med 4000
Routes:
fd49:7770:7fc5:0::/64 s med 4000
Services:
44970 5d c000 s 4000
44970 01 9a04b000000e10 s 4000
Done
$ sudo ot-ctl ipaddr      
fda8:5ce9:df1e:6620:0:ff:fe00:fc11
fda8:5ce9:df1e:6620:0:0:0:fc38
fda8:5ce9:df1e:6620:0:ff:fe00:fc10
fd76:a5d1:fcb0:1707:f3c7:d88c:efd1:24a9
fda8:5ce9:df1e:6620:0:ff:fe00:fc00
fda8:5ce9:df1e:6620:0:ff:fe00:4000
fda8:5ce9:df1e:6620:3593:acfc:10db:1a8d
fe80:0:0:0:a6:301c:3e9f:2f5b
Done

3. 設定 SRP 用戶端終端裝置

建構及刷新 OT CLI

請按照使用 nRF52840 電路板和 OpenThread 建構 Thread 網路」程式碼研究室的步驟 5 建構並刷新 nRF52840 CLI 終端裝置。

不過,CLI 節點需要 OT_SRP_CLIENTOT_ECDSA 功能,而非啟用 OT_COMMISSIONEROT_JOINER

因此,完整的建構作業叫用應如下所示:

$ script/build nrf52840 USB_trans -DOT_SRP_CLIENT=ON -DOT_ECDSA=ON

加入 Thread 網路

如要加入 Thread 網路,我們需要從 OTBR 裝置取得 Active Operational Dataset。讓我們回到 ot-ctl,並取得有效的資料集:

$ sudo ot-ctl dataset active -x
0e080000000000010000000300001235060004001fffe002083d3818dc1c8db63f0708fda85ce9df1e662005101d81689e4c0a32f3b4aa112994d29692030f4f70656e5468726561642d35326532010252e204103f23f6b8875d4b05541eeb4f9718d2f40c0302a0ff
Done

返回 SRP 用戶端節點畫面工作階段,並設定有效資料集:

> dataset set active 0e080000000000010000000300001235060004001fffe002083d3818dc1c8db63f0708fda85ce9df1e662005101d81689e4c0a32f3b4aa112994d29692030f4f70656e5468726561642d35326532010252e204103f23f6b8875d4b05541eeb4f9718d2f40c0302a0ff
Done

然後啟動 Thread 介面:

> ifconfig up
Done
> thread start
Done

請稍候幾秒鐘,然後確認是否已成功加入 Thread 網路:

> state
child
Done
> netdata show
Prefixes:
fd76:a5d1:fcb0:1707::/64 paos med 4000
Routes:
fd49:7770:7fc5:0::/64 s med 4000
Services:
44970 5d c000 s 4000
44970 01 9a04b000000e10 s 4000
Done
> ipaddr
fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927
fda8:5ce9:df1e:6620:0:ff:fe00:4001
fda8:5ce9:df1e:6620:ed74:123:cc5d:74ba
fe80:0:0:0:d4a9:39a0:abce:b02e
Done

請確認網路資料與 OTBR 上列印的資料相符。我們現在可以對 OTBR 的 OMR 位址執行 ping 作業:

> ping fd76:a5d1:fcb0:1707:f3c7:d88c:efd1:24a9
Done
> 16 bytes from fd76:a5d1:fcb0:1707:f3c7:d88c:efd1:24a9: icmp_seq=1 hlim=64 time=49ms

4. 在終端裝置上發布服務

mDNS 已廣泛用於在連結區域中發布 DNS-SD 服務。但多播訊息會耗用過多頻寬,並且會快速耗盡低耗電裝置的電池。Thread 會使用單播 SRP 通訊協定,向邊界路由器註冊服務,並仰賴邊界路由器在 Wi-Fi 或乙太網路連結上宣傳服務。

我們可以使用 srp client 指令註冊服務。

前往 SRP 用戶端節點畫面工作階段,並自動啟動 SRP 用戶端:

> srp client autostart enable
Done

設定將在 Wi-Fi/乙太網路連結中宣傳的主機名稱:

> srp client host name ot-host
Done

如要讓 Wi-Fi/乙太網路連結中的裝置連上 Thread 終端裝置,就必須宣傳終端裝置的 OMR 位址:

> srp client host address fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927
Done

最後,請註冊虛擬 _ipps._tcp 服務:

> srp client service add ot-service _ipps._tcp 12345
Done

請稍候片刻,我們應該會看到已註冊的服務:

> srp client service
instance:"ot-service", name:"_ipps._tcp", state:Registered, port:12345, priority:0, weight:0
Done

我們已完成所有設定工作,_ipps._tcp 服務應已在 Wi-Fi/乙太網路連結上宣傳。是時候探索並接觸終端裝置了!

5. 探索服務

透過手機探索這項服務

54a136a8940897cc.png

我們使用 Service Browser 應用程式,透過 Android 手機找出 mDNS 服務。iOS 行動裝置也有同等應用程式。開啟應用程式,服務 _ipps._tcp 就會顯示。

透過 Linux 主機探索服務

如要從其他 Linux 主機探索服務,可以使用 avahi-browse 指令。

安裝 avahi-daemonavahi-utils

$ sudo apt-get install -y avahi-daemon avahi-utils

解析服務:

$ sudo service avahi-daemon start # Ensure the avahi daemon is started.
$ avahi-browse -r _ipps._tcp
+ wlan0 IPv6 ot-service                                    Secure Internet Printer local
= wlan0 IPv6 ot-service                                    Secure Internet Printer local
   hostname = [ot-host.local]
   address = [fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927]
   port = [12345]
   txt = []
...

透過 macOS 主機探索服務

您可以在 macOS 上使用 dns-sd 解決服務:

$ dns-sd -Z _ipps._tcp local.
Browsing for _ipps._tcp.local.
DATE: ---Sun 14 Mar 2021---
21:31:42.125  ...STARTING...

; To direct clients to browse a different domain, substitute that domain in place of '@'
lb._dns-sd._udp                                 PTR     @

; In the list of services below, the SRV records will typically reference dot-local Multicast DNS names.
; When transferring this zone file data to your unicast DNS server, you'll need to replace those dot-local
; names with the correct fully-qualified (unicast) domain name of the target host offering the service.

_ipps._tcp                                      PTR     ot-service._ipps._tcp
ot-service._ipps._tcp                           SRV     0 0 12345 ot-host.local. ; Replace with unicast FQDN of target host
ot-service._ipps._tcp                           TXT     ""
...

6. 連線偵測 (ping) 終端裝置

透過手機執行 Ping 命令

以 Pixel 手機為例,我們可以在「Service Browser」應用程式中,查看服務例項的詳細資料頁面,找出先前註冊的服務「ot-service」的 OMR 位址。

bb992962e68d250b.png 888daa1df1e1a9bf.png

我們現在可以使用其他 Network Analyzer 應用程式來 ping OMR 位址。

很抱歉,Android 版 Network Analyzer 應用程式不支援 ping 公用程式的 mDNS 查詢,因此我們無法直接對主機名稱 ot-host.local 執行 ping 作業 (我們可以使用 iOS 版應用程式對主機名稱執行 ping 作業)。

從 Linux/macOS 主機執行 Ping

Thread Border Router 會傳送 ICMPv6 Router Advertisements (RA),在 Wi-Fi/乙太網路連線上宣傳前置字元 (透過「Prefix Information」選項) 和路徑 (透過「Route Information」選項)。

準備 Linux 主機

請務必確認主機已啟用 RA 和 RIO:

  1. 如果未啟用 IP 轉送,net.ipv6.conf.wlan0.accept_ra 應至少為 1;如果已啟用,則應為 2
  2. net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen 不得小於 64

在大多數發行版本中,accept_ra 的預設值為 1。但可能會有其他網路守護程序會覆寫這個選項 (例如,Raspberry Pi 上的 dhcpcd 會將 accept_ra 覆寫為 0)。您可以使用下列方法檢查 accept_ra 值:

$ sudo sysctl -n net.ipv6.conf.wlan0.accept_ra
0

並將值設為 1 (如果啟用 IP 轉送,則為 2),如下所示:

$ sudo sysctl -w net.ipv6.conf.wlan0.accept_ra=1
Net.ipv6.conf.wlan0.accept_ra = 1

大多數 Linux 發行版本的 accept_ra_rt_info_max_plen 選項預設為 0,請使用以下指令將其設為 64

$ sudo sysctl -w net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen=64
net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen = 64

重新啟動主機後,變更內容就會遺失。舉例來說,您可以將下列指令附加至 /etc/sysctl.conf,永久啟用 RIO:

$ net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen = 64

由於 OTBR 已傳送 RA 訊息,且兩次非自願 RA 訊息之間的間隔可能長達數百秒,因此可能已太晚變更這些設定。其中一種方法是斷開並重新連線至 Wi-Fi AP,以便傳送路由器要求訊息,讓 OTBR 回覆要求的 RA。另一個選項是在邊界路由器上重新啟動邊界路由功能:

$ sudo ot-ctl br disable
Done
$ sudo ot-ctl br enable
Done

如果您要重新連線至 Wi-Fi 或重新啟動乙太網路介面,請確認 dhcpcd 未用於管理 Wi-Fi/乙太網路 IPv6 網路。因為 dhcpcd 每次重新啟動介面時,都會覆寫 accept_ra 選項,因此 accept_ra 設定會遺失。將下列行附加至 dhcpcd 設定檔 (例如 /etc/dhcpcd.conf),即可明確停用 dhcpcd 中的 IPv6:

noipv6
noipv6rs

您必須重新啟動裝置,變更才會生效。

準備 macOS 主機

系統預設會啟用這兩個 accept_ra* 選項,但您必須將系統升級至至少 macOS Big Sur。

對主機名稱或 IPv6 位址執行連線偵測 (ping)

我們現在可以使用 ping -6 指令 (ping6 適用於 macOS) 來 ping 主機名稱 ot-host.local

$ ping -6 ot-host.local.
PING ot-host.local.(fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927)) 56 data bytes
64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927): icmp_seq=1 ttl=63 time=170 ms
64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927): icmp_seq=2 ttl=63 time=64.2 ms
64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927): icmp_seq=3 ttl=63 time=22.8 ms
64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927): icmp_seq=4 ttl=63 time=37.7 ms
64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927): icmp_seq=5 ttl=63 time=28.7 ms
...

這個指令在 Linux 主機上執行時,可能會發生 "Name or service not known" 錯誤。這是因為 ping 指令並未使用 mDNS 查詢來解析 ot-host.local. 名稱。開啟 /etc/nsswitch.conf,並在以 hosts 開頭的行中新增 mdns6_minimal

hosts:          files mdns4_minimal mdns6_minimal dns

當然,您也可以直接對 IPv6 位址執行 ping 作業:

$ ping -6 fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927
PING fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927(fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927) 56 data bytes
64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927: icmp_seq=1 ttl=63 time=32.9 ms
64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927: icmp_seq=2 ttl=63 time=27.8 ms
64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927: icmp_seq=3 ttl=63 time=29.9 ms
64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927: icmp_seq=4 ttl=63 time=73.5 ms
64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927: icmp_seq=5 ttl=63 time=26.4 ms
...

7. 結束裝置取消發布服務

如要從 SRP 用戶端節點移除已註冊的地址和服務,請按照下列步驟操作:

> srp client host remove
Done

您現在「不應」能夠探索 _ipps._tcp 服務。

8. 恭喜

恭喜,你已成功將 OTBR 設為 Thread 邊界路由器,為 Thread 終端裝置提供雙向 IP 連線和服務探索功能。

後續步驟

查看一些程式碼研究室…

參考文件