1. はじめに

Thread とは何ですか?
Thread は、デバイス間およびデバイスとクラウド間の安全な通信を可能にする IP ベースの低消費電力ワイヤレス メッシュ ネットワーク プロトコルです。Thread ネットワークは、トポロジの変更に適応して単一障害点を回避できます。
OpenThread とは
Google がリリースした OpenThread は、Thread® のオープンソース実装です。
OpenThread ボーダー ルーターとは
Google がリリースした OpenThread Border Router(OTBR)は、Thread ボーダー ルーターのオープンソース実装です。
NAT64
NAT64 は、IPv6 専用ネットワーク内のホストが IPv4 ネットワーク内のリソースにアクセスできるようにするメカニズムです。NAT64 ゲートウェイは、IPv4 プロトコルと IPv6 プロトコル間の変換を行います。
NAT64 トランスレータは、OpenThread Border Router の一部として、TCP、UDP、ICMP(ICMPv6)プロトコルの変換をサポートしています。
作成するアプリの概要
この Codelab では、OpenThread ボーダー ルーター(OTBR)と Thread デバイスを設定し、OpenThread ボーダー ルーターを介して Thread デバイスとインターネット上の IPv4 ホスト間の通信を有効にして確認します。
学習内容
- NAT64 機能を備えた OpenThread ボーダー ルーターを構築する方法。
- Thread エンドデバイスから IPv4 ホストと通信する方法。
必要なもの
- Thread RCP と OpenThread CLI のビルドとフラッシュ、IPv4 接続のテストを行うための Linux ワークステーション。
- Thread ボーダー ルーター用の Raspberry Pi。このデバイスから Linux ワークステーションに IPv4 経由でアクセスできる必要があります。
- 2 個の Nordic Semiconductor nRF52840 USB ドングル(1 個は RCP 用、1 個は 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 プレフィックスです。
NAT64 プレフィックスは、IPv4 ホストと通信するときに Thread デバイスで使用されます。
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 イメージを書き込んだら、2 番目のノードを Thread ネットワークに参加させるに沿って、Thread デバイスを Thread ネットワークに追加します。
Thread エンドデバイスのセットアップ後、数秒待ってから、Thread ネットワークへの参加が成功したかどうかを確認します。上記のように、公開された NAT64 プレフィックスを Thread ネットワーク データで確認できます。
> 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 を無効にするには、nat64 disable を使用します。また、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 を有効にするには、nat64 enable を使用します。プレフィックス マネージャーが 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 Border Router のアドレスの 1 つである必要があります。
これで、エンドデバイスからインターネット ドメインの 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 プラットフォーム抽象化