Thread ボーダー ルーター - 双方向 IPv6 接続と DNS ベースのサービス ディスカバリ

1. はじめに

699d673d05a55535.png

Thread とは何ですか?

Thread は、デバイス間およびデバイスとクラウド間の安全な通信を可能にする、IP ベースの低消費電力ワイヤレス メッシュ ネットワーキング プロトコルです。Thread ネットワークは、トポロジの変更に適応して単一障害点を回避できます。

OpenThread とは

Google がリリースした OpenThread は、Thread® のオープンソース実装です。

Thread ボーダー ルーターとは

Thread ボーダー ルーターは、Thread ネットワークを Wi-Fi やイーサネットなどの他の IP ベースのネットワークに接続します。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 ボーダー ルーターのオープンソース実装です。

作成するアプリの概要

この Codelab では、Thread ボーダー ルーターをセットアップし、ボーダー ルーターを介してスマートフォンを Thread エンドデバイスに接続します。

学習内容

  • OTBR の設定方法
  • OTBR で Thread ネットワークを形成する方法
  • SRP 機能を使用して OpenThread CLI デバイスをビルドする方法
  • SRP にサービスを登録する方法
  • Thread エンドデバイスを検出してアクセスする方法

必要なもの

  • Thread RCP、OpenThread CLI のビルドとフラッシュ、IPv6 マルチキャストのテストに使用する Linux ワークステーション。
  • Thread ボーダー ルーター用の Raspberry Pi。
  • 2 個の Nordic Semiconductor nRF52840 USB ドングル(1 個は RCP 用、1 個は 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 ネットワークを構築する Codelab のステップ 5 に沿って、nRF52840 CLI エンドデバイスをビルドしてフラッシュします。

ただし、CLI ノードでは OT_COMMISSIONEROT_JOINER を有効にするのではなく、OT_SRP_CLIENTOT_ECDSA の機能が必要です。

したがって、完全なビルド呼び出しは次のようになります。

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

Thread ネットワークに参加する

Thread ネットワークに参加するには、OTBR デバイスからアクティブなオペレーショナル データセットを取得する必要があります。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

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 スマートフォンを例に取ると、サービス ブラウザ アプリのサービス インスタンスの詳細ページで、以前に登録したサービス「ot-service」の OMR アドレスを確認できます。

bb992962e68d250b.png 888daa1df1e1a9bf.png

別の Network Analyzer アプリで OMR アドレスに ping を送信できるようになりました。

残念ながら、ネットワーク アナライザ アプリの Android 版では、ping ユーティリティの mDNS クエリがサポートされていません。そのため、ホスト名 ot-host.local に直接 ping を送信することはできません(アプリの iOS 版ではホスト名に ping を送信できます)。

Linux/macOS ホストから ping を実行する

Thread Border Router は、ICMPv6 ルーター アドバタイズ(RA)を送信して、Wi-Fi/イーサネット リンク上の接頭辞(接頭辞情報オプション経由)とルート(ルート情報オプション経由)をアドバタイズします。

Linux ホストを準備する

ホストで RA と RIO が有効になっていることを確認することが重要です。

  1. IP 転送が有効になっていない場合は net.ipv6.conf.wlan0.accept_ra1 以上、それ以外の場合は 2 以上にする必要があります。
  2. net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen64 より小さくしないでください。

ほとんどのディストリビューションでは、accept_ra はデフォルトで 1 に設定されています。ただし、このオプションをオーバーライドする他のネットワーク デーモンが存在する可能性があります(たとえば、Raspberry Pi の dhcpcdaccept_ra0 にオーバーライドします)。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 メッセージを送信しており、2 つの自発的 RA メッセージ間の間隔は数百秒になる可能性があるため、これらの構成を変更するには遅すぎる可能性があります。1 つの方法は、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 で IPv6 を明示的に無効にするには、次の行を dhcpcd 構成ファイル(/etc/dhcpcd.conf など)に追加します。

noipv6
noipv6rs

変更を有効にするには、再起動する必要があります。

macOS ホストを準備する

どちらの accept_ra* オプションもデフォルトで有効になっていますが、システムを macOS Big Sur 以降にアップグレードする必要があります。

ホスト名または IPv6 アドレスに ping を送信する

これで、コマンド ping -6(macOS の場合は ping6)を使用してホスト名 ot-host.local に ping を送信できます。

$ 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 接続とサービス検出を提供できるようになりました。

次のステップ

以下の Codelab をご覧ください。

リファレンス ドキュメント