Thread ボーダー ルーター - NAT64 経由でインターネット アクセスを提供

1. はじめに

7299534792dd9439.png

Thread とは何ですか?

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

OpenThread とは

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

OpenThread ボーダー ルーターとは

Google がリリースした OpenThread ボーダー ルーター(OTBR)は、Thread ボーダー ルーターのオープンソース実装です。

NAT64

NAT64 は、IPv6 専用ネットワーク内のホストが IPv4 ネットワーク内のリソースにアクセスできるようにするメカニズムです。NAT64 ゲートウェイは、IPv4 プロトコルと IPv6 プロトコルの間のトランスレータです。

OpenThread ボーダー ルーターの一部である NAT64 トランスレータは、TCP、UDP、ICMP(ICMPv6)プロトコルの変換をサポートしています。

作成するアプリの概要

この Codelab では、OpenThread ボーダー ルーターと Thread デバイスをセットアップし、Thread デバイスとインターネット上の IPv4 ホスト間の通信を OpenThread ボーダー ルーターを介して検証します。

学習内容

  • NAT64 機能を備えた OpenThread ボーダー ルーターの構築方法。
  • Thread エンドデバイスから IPv4 ホストと通信する方法

必要なもの

  • Thread NCP、OpenThread CLI のビルドとフラッシュ、IPv4 接続のテストを行うための Linux ワークステーション。
  • Thread ボーダー ルーター用に 4 GB RAM を搭載した Raspberry Pi 4。このデバイスから IPv4 経由で Linux ワークステーションにアクセスできる必要があります。
  • Nordic Semiconductor nRF52840 DK ボード 2 枚。

この Codelab のネットワーク トポロジ:

c3cd2e081bc052fd.png

2. OpenThread ボーダー ルーターを設定する

Thread ボーダー ルーターの設定 - 双方向 IPv6 接続と DNS ベースのサービス ディスカバリの Codelab に沿って OpenThread ボーダー ルーターをビルドしますが、以下の点を変更します。

[OTBR のビルドとインストール] で、環境変数 NAT641 に、NAT64_SERVICEopenthread に設定して、OpenThread で NAT64 トランスレータを有効にするようにスクリプトに指示します。ステップの前に次のコマンドを実行します。

$ export NAT64=1 NAT64_SERVICE=openthread

記述どおりに Thread ボーダー ルーター - 双方向 IPv6 接続と DNS ベースのサービス ディスカバリの Codelab に進みます。Thread ネットワークを形成した後、OpenThread CLI コマンドを使用して、ボーダー ルーターが NAT64 プレフィックスを公開していることを確認できます。

まず、ボーダー ルーターが稼働していて、ボーダー ルーターで NAT64 が有効になっていることを確認します。

$ sudo ot-ctl state
leader
Done
$ sudo ot-ctl nat64 enable
Done
$ sudo ot-ctl nat64 state
PrefixManager: Active
Translator: Active
Done

OTBR が Thread リーダーとして機能し、Thread ネットワーク データに NAT64 プレフィックス(この場合は fd4c:9574:3720:2:0:0::/96)があることがわかります。

$ sudo ot-ctl netdata show
Prefixes:
fd4c:9574:3720:1::/64 paos low 0800
Routes:
fd49:7770:7fc5:0::/64 s med 0800
fd4c:9574:3720:2:0:0::/96 sn low 0800
Services:
44970 01 41000500000e10 s 0800
44970 5d fdd20e532b87b93f50ad4eea0450f1bfd11f s 0800
Done

NAT64 接頭辞は、Thread デバイスが IPv4 ホストと通信する際に使用します。

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_JOINER=ON -DOT_COMMISSIONER=ON -DOT_DNS_CLIENT=ON -DOT_SRP_CLIENT=ON -DOT_ECDSA=ON

記載されているとおり、nRF52840 ボードと OpenThread Codelab で Thread ネットワークを構築するに進みます。エンドデバイスに CLI イメージが書き込まれたら、Thread ボーダー ルーター - 双方向 IPv6 接続と DNS ベースのサービス ディスカバリの手順に沿って Thread エンドデバイスをセットアップします。

Thread エンドデバイスのセットアップ後数秒待ってから、Thread ネットワークへの参加に成功したかどうかを確認します。ネットワーク データから NAT64 プレフィックスを見つけます(この場合は fd4c:9574:3720:2:0:0::/96)。

> netdata show
Prefixes:
fd4c:9574:3720:1::/64 paos low 0800
Routes:
fd49:7770:7fc5:0::/64 s med 0800
fd4c:9574:3720:2:0:0::/96 sn low 0800
Services:
44970 01 41000500000e10 s 0800
44970 5d fdd20e532b87b93f50ad4eea0450f1bfd11f s 0800
Done

ネットワーク データが OTBR のデータと一致していることを確認します。

4. Thread エンドデバイスから IPv4 ホストと通信する

これで、先ほどセットアップしたエンドデバイスから IPv4 ネットワーク上のホストと通信できるようになりました。

IPv4 ホストに ICMP エコー リクエストを送信する

Thread エンドデバイスの CLI から:

> ping 8.8.8.8
Pinging synthesized IPv6 address: fd4c:9574:3720:2:0:0:808:808
16 bytes from fd4c:9574:3720:2:0:0:808:808: icmp_seq=15 hlim=119 time=48ms
1 packets transmitted, 1 packets received. Packet loss = 0.0%. Round-trip min/avg/max = 48/48.0/48 ms.
Done

ボーダー ルーターは、nat64 mappings コマンドによってこのデバイスの NAT64 マッピング アイテムを作成します。

$ sudo ot-ctl nat64 mappings
|                  | Address                                                     |        | 4 to 6                  | 6 to 4                  |
+------------------+-------------------------------------------------------------+--------+-------------------------+-------------------------+
| ID               | IPv6                                     | IPv4             | Expiry | Pkts     | Bytes        | Pkts     | Bytes        |
+------------------+------------------------------------------+------------------+--------+----------+--------------+----------+--------------+
| 377ee63dd3127f1a |     fd4c:9574:3720:1:1d61:b4c1:494f:f975 |  192.168.255.254 |  7190s |        1 |           16 |        1 |           16 |
|                  |                                                                  TCP |        0 |            0 |        0 |            0 |
|                  |                                                                  UDP |        0 |            0 |        0 |            0 |
|                  |                                                                 ICMP |        1 |           16 |        1 |           16 |
Done

fd4c:9574:3720:1:1d61:b4c1:494f:f975 は、Thread デバイスの IPv6 アドレスにする必要があります。

ボーダー ルーターでこのコマンドを実行して、トラフィックのカウント方法を確認してください。

DNS クエリを IPv4 DNS サーバーに送信する

IPv4 ネットワーク上のホスト名を解決するには、dns resolve4 を使用します。DNS サーバー アドレスは IPv4 アドレスにすることもできます。

> dns resolve4 example.com 8.8.8.8
Synthesized IPv6 DNS server address: fd4c:9574:3720:2:0:0:808:808
DNS response for example.com. - fd4c:9574:3720:2:0:0:5db8:d822 TTL:20456 
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: fd4c:9574:3720:2:0:0:c0a8:2
Done
> tcp send hello

Linux IPv4 ホストの出力:

hello

Linux IPv4 ホストから Thread エンドデバイスにメッセージを送信することもできます。「world」と入力します。nc を実行している Linux IPv4 ホストで Enter キーを押すと、Thread エンドデバイスの出力は次のようになります。

TCP: Received 6 bytes: world

UDP 経由の通信

Thread デバイスと IPv4 ネットワーク内のホスト間で 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: fd4c:9574:3720:2:0:0:c0a8:2
Done
> udp send hello
Done

Linux IPv4 ホストの出力:

hello

Linux IPv4 ホストから Thread エンドデバイスにメッセージを送信することもできます。「world」と入力します。nc を実行している Linux IPv4 ホストで Enter キーを押すと、Thread エンドデバイスの出力は次のようになります。

6 bytes from fd4c:9574:3720:2:0:0:c0a8:2 12345 world

5. ボーダー ルーターで NAT64 を切り替える

NAT64 はいつでも有効または無効にできます。NAT64 を無効にするには、nat64 disable を使用します。nat64 state を使用して NAT64 の状態を確認します。

$ sudo ot-ctl nat64 disable
Done
$ sudo ot-ctl nat64 state
PrefixManager: Disabled
Translator: Disabled
Done

無効にすると、デバイスは NAT64 プレフィックスを公開しなくなります。

$ sudo ot-ctl netdata show
Prefixes:
fd4c:9574:3720:1::/64 paos low 0800
Routes:
fd49:7770:7fc5:0::/64 s med 0800
Services:
44970 01 41000500000e10 s 0800
44970 5d fdd20e532b87b93f50ad4eea0450f1bfd11f s 0800
Done

また、Thread ネットワーク内のデバイスは、このボーダー ルーター経由で IPv4 ホストにアクセスできなくなります。

Thread エンドデバイスの CLI から:

> ping 8.8.8.8
Error 13: InvalidState

NAT64 を有効にするには、nat64 enable を使用します。プレフィックス マネージャーが NAT64 プレフィックスのアドバタイズを開始するまでに、しばらく時間がかかることがあります。

$ sudo ot-ctl nat64 enable
Done
$ sudo ot-ctl nat64 state
PrefixManager: Idle
Translator: NotWorking
Done

数秒後、NAT64 コンポーネントが稼働している状態になります。

$ sudo ot-ctl nat64 state
PrefixManager: Active
Translator: Active
Done
$ sudo ot-ctl netdata show
Prefixes:
fd4c:9574:3720:1::/64 paos low 0800
Routes:
fd49:7770:7fc5:0::/64 s med 0800
fd4c:9574:3720:2:0:0::/96 sn low 0800
Services:
44970 01 41000500000e10 s 0800
44970 5d fdd20e532b87b93f50ad4eea0450f1bfd11f s 0800
Done

NAT64 を無効にするとマッピング テーブルがクリアされることに注意してください。

$ sudo ot-ctl nat64 mappings
|                  | Address                                                     |        | 4 to 6                  | 6 to 4                  |
+------------------+-------------------------------------------------------------+--------+-------------------------+-------------------------+
| ID               | IPv6                                     | IPv4             | Expiry | Pkts     | Bytes        | Pkts     | Bytes        |
+------------------+------------------------------------------+------------------+--------+----------+--------------+----------+--------------+
Done

6. DNS クエリをアップストリーム DNS サーバーに転送する

ボーダー ルーターで NAT64 が有効になると、OpenThread はインターネット ドメインの DNS クエリを上流の DNS サーバーに転送しようとします。

この機能は内部 DNS-SD サーバーでサポートされているため、DNS-SD サーバーが有効になっていることを確認する必要があります。

$ sudo ot-ctl srp server state
running
Done

running でない場合は有効にします。

$ sudo ot-ctl srp server enable
Done

アップストリーム DNS プロキシが有効になっていることを確認します。

$ sudo ot-ctl dns server upstream
Enabled
Done

Enabled でない場合は有効にします。

$ sudo ot-ctl dns server upstream enable
Done

エンドデバイスでは、SRP クライアントを有効にして、DNS クエリがボーダー ルーターに送信されるようにします。

> srp client state
Enabled
Done

Enabled でない場合は有効にします。

> srp client autostart enable
Done

エンドデバイスで、デフォルトの DNS サーバーがボーダー ルーターであることを確認します。

> dns config
Server: [fdd2:0e53:2b87:b93f:50ad:4eea:0450:f1bf]:53
ResponseTimeout: 6000 ms
MaxTxAttempts: 3
RecursionDesired: yes
Done

サーバーの IPv6 アドレス(上記の例では fdd2:0e53:2b87:b93f:50ad:4eea:0450:f1bf)は、OpenThread ボーダー ルーターのいずれかのアドレスである必要があります。

これで、エンドデバイスからインターネット ドメインの DNS クエリを送信できるようになりました。

> dns resolve example.com
DNS response for example.com. - 2606:2800:220:1:248:1893:25c8:1946 TTL:8720 
Done
> dns resolve4 example.com
DNS response for example.com. - fd4c:9574:3720:2:0:0:5db8:d822 TTL:20456 
Done

7. 完了

これで、NAT64 をサポートするボーダー ルーターを正しくセットアップし、Thread エンドデバイスにインターネット アクセスを提供することができました。

関連情報

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