1. はじめに
Thread とは何ですか?
Thread は、デバイス間通信とデバイスとクラウド間の通信を安全に行うことができる、IP ベースの低電力ワイヤレス メッシュ ネットワーク プロトコルです。Thread ネットワークは、トポロジの変更に適応して単一障害点を回避できます。
OpenThread とは
Google がリリースした OpenThread は、Thread® のオープンソース実装です。
OpenThread ボーダー ルーターとは
Google がリリースした OpenThread Border Router(OTBR)は、Thread Border Router のオープンソース実装です。
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 プレフィックスです。
NAT64 プレフィックスは、IPv4 ホストとの通信時に Thread デバイスによって使用されます。
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 を使用して 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 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 Border Router のアドレスのいずれかである必要があります。
これで、エンドデバイスからインターネット ドメインの 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 プラットフォーム抽象化