Thread-Border-Router – Bidirektionale IPv6-Konnektivität und DNS-basierte Diensterkennung

1. Einführung

699d673d05a55535.png

Was ist ein Thread-Border-Router?

Thread ist ein IP-basiertes, energiesparendes drahtloses Mesh-Netzwerkprotokoll, das eine sichere Kommunikation zwischen Geräten und der Cloud ermöglicht. Thread-Netzwerke können sich an Topologieänderungen anpassen, um Single Point of Failure zu vermeiden.

Ein Thread-Border-Router verbindet ein Thread-Netzwerk mit anderen IP-basierten Netzwerken wie WLAN oder Ethernet. Ein Thread-Netzwerk benötigt einen Border Router, um eine Verbindung zu anderen Netzwerken herzustellen. Ein Thread-Border-Router unterstützt mindestens die folgenden Funktionen:

  • Bidirektionale IP-Verbindung zwischen Thread- und Wi-Fi-/Ethernet-Netzwerken.
  • Bidirektionale Diensterkennung über mDNS (bei Wi-Fi-/Ethernet-Link) und SRP (im Thread-Netzwerk).
  • Thread-over-Infrastruktur, die Thread-Partitionen über IP-basierte Links zusammenführt.
  • „External Thread Commissioning“ (z. B. ein Smartphone) zum Authentifizieren eines Thread-Geräts und zum Verbinden mit einem Thread-Netzwerk.

Der von Google veröffentlichte OpenThread Border Router (OTBR) ist eine Open-Source-Implementierung des Thread-Border-Routers.

Inhalt

In diesem Codelab richten Sie einen Thread-Border-Router ein und verbinden Ihr Smartphone über den Border-Router mit einem Thread-Endgerät.

Lerninhalte

  • OTBR einrichten
  • Thread-Netzwerk mit OTBR erstellen
  • So erstellen Sie ein OpenThread-CLI-Gerät mit der SRP-Funktion
  • So registrieren Sie einen Dienst bei SRP
  • Thread-Endgeräte finden und erreichen

Voraussetzungen

  • Ein Raspberry Pi 3/4-Gerät und eine SD-Karte mit mindestens 8 GB Speicherkapazität
  • 2 nRF52840-Entwicklungsboards von Nordic Semiconductor
  • Ein Wi-Fi AP ohne IPv6 Router Advertising Guard auf dem Router.
  • Ein iOS-Smartphone mit iOS 14 oder ein Android-Smartphone mit Android 8.1 oder höher.

2. OTBR einrichten

Raspberry Pi einrichten

Es ist ganz einfach, mit dem rpi-imager-Tool ein neues Raspberry Pi-Gerät einzurichten. Folgen Sie dazu der Anleitung unter raspberrypi.org. Statt das neueste Raspberry Pi OS im Tool zu verwenden, laden Sie 2021-05-07-raspios-buster-armhf-lite selbst herunter. Um die Schritte für Ihr Smartphone in diesem Codelab abzuschließen, müssen Sie den Raspberry Pi mit einem WLAN-Zugangspunkt verbinden. Folgen Sie dieser Anleitung, um eine WLAN-Verbindung einzurichten. Es ist praktisch, sich mit SSH auf dem Raspberry Pi anzumelden. Eine Anleitung dazu finden Sie hier.

OTBR-Code abrufen

Melden Sie sich bei Ihrem Raspberry Pi an und klonen Sie ot-br-posix von GitHub:

$ git clone https://github.com/openthread/ot-br-posix.git --depth 1

OTBR erstellen und installieren

OTBR hat zwei Skripts, die einen Bootstrapping des Thread-Border-Routers ausführen und ihn einrichten:

$ cd ot-br-posix
$ ./script/bootstrap
$ INFRA_IF_NAME=wlan0 ./script/setup

OTBR funktioniert sowohl mit einer Thread-Schnittstelle als auch einer Infrastruktur-Netzwerkschnittstelle (z.B. Wi-Fi/Ethernet), die mit INFRA_IF_NAME angegeben wird. Die Thread-Schnittstelle wird vom OTBR selbst erstellt und standardmäßig wpan0 genannt. Die Infrastrukturschnittstelle hat den Standardwert wlan0, wenn INFRA_IF_NAME nicht explizit angegeben ist. Wenn Ihr Raspberry Pi über ein Ethernetkabel verbunden ist, geben Sie den Namen der Ethernetschnittstelle an (z.B. eth0):

$ INFRA_IF_NAME=eth0 ./script/setup

Prüfen Sie, ob OTBR erfolgreich installiert wurde:

$ sudo service otbr-agent status
● otbr-agent.service - Border Router Agent
   Loaded: loaded (/lib/systemd/system/otbr-agent.service; enabled; vendor preset: enabled)
   Active: activating (auto-restart) (Result: exit-code) since Mon 2021-03-01 05:43:38 GMT; 2s ago
  Process: 2444 ExecStart=/usr/sbin/otbr-agent $OTBR_AGENT_OPTS (code=exited, status=2)
 Main PID: 2444 (code=exited, status=2)

Es wird erwartet, dass der otbr-agent-Dienst nicht aktiv ist, da zum Ausführen ein RCP-Chip erforderlich ist.

Starten Sie den Raspberry Pi neu, damit die Änderungen wirksam werden.

Build- und Flash-RCP-Firmware

OTBR unterstützt einen 15.4-Radiochip im RCP-Modus (Radio Co-Processor). In diesem Modus wird der OpenThread-Stack auf der Hostseite ausgeführt und überträgt/empfangen Frames über den IEEE802.15.4-Transceiver.

Führen Sie Schritt 4 im Codelab zum Erstellen eines Thread-Netzwerks mit nRF52840-Boards und OpenThread aus, um ein nRF52840-RCP-Gerät zu erstellen und zu flashen:

$ script/build nrf52840 USB_trans

OTBR starten und Status prüfen

Verbinden Sie die nRF52840-Platine mit Ihrem Raspberry Pi und starten Sie den otbr-agent-Dienst:

$ sudo service otbr-agent restart

Prüfen Sie, ob der Dienst otbr-agent aktiv ist:

$ sudo service otbr-agent status
● otbr-agent.service - Border Router Agent
   Loaded: loaded (/lib/systemd/system/otbr-agent.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2021-03-01 05:46:26 GMT; 2s ago
 Main PID: 2997 (otbr-agent)
    Tasks: 1 (limit: 4915)
   CGroup: /system.slice/otbr-agent.service
           └─2997 /usr/sbin/otbr-agent -I wpan0 -B wlan0 spinel+hdlc+uart:///dev/ttyACM0

Mar 01 05:46:26 raspberrypi otbr-agent[2997]: Stop publishing service
Mar 01 05:46:26 raspberrypi otbr-agent[2997]: [adproxy] Stopped
Mar 01 05:46:26 raspberrypi otbr-agent[2997]: PSKc is not initialized
Mar 01 05:46:26 raspberrypi otbr-agent[2997]: Check if PSKc is initialized: OK
Mar 01 05:46:26 raspberrypi otbr-agent[2997]: Initialize OpenThread Border Router Agent: OK
Mar 01 05:46:26 raspberrypi otbr-agent[2997]: Border router agent started.
Mar 01 05:46:26 raspberrypi otbr-agent[2997]: [INFO]-CORE----: Notifier: StateChanged (0x00038200) [NetData PanId NetName ExtPanId]
Mar 01 05:46:26 raspberrypi otbr-agent[2997]: [INFO]-PLAT----: Host netif is down

3. Thread-Netzwerk bilden

Es gibt einen ot-ctl-Befehl, mit dem der otbr-agent-Dienst gesteuert werden kann. ot-ctl akzeptiert alle OpenThread-Befehlszeilenbefehle. Weitere Informationen finden Sie im Handbuch zur OpenThread-Befehlszeile.

Thread-Netzwerk mit OTBR erstellen:

$ sudo ot-ctl dataset init new
Done
$ sudo ot-ctl dataset commit active
Done
$ sudo ot-ctl ifconfig up
Done
$ sudo ot-ctl thread start
Done

Warten Sie ein paar Sekunden. OTBR fungiert als Thread-leader und die Thread-Netzwerkdaten enthalten das Präfix off-mesh-routable (OMR):

$ sudo ot-ctl state
leader
Done
$ 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

4. SRP-Client-Endgerät einrichten

OT-CLI erstellen und flashen

Führen Sie Schritt 5 im Codelab zum Erstellen eines Thread-Netzwerks mit nRF52840-Boards und OpenThread aus, um ein nRF52840-CLI-Endgerät zu erstellen und zu flashen.

Statt jedoch OT_COMMISSIONER und OT_JOINER zu aktivieren, benötigt der Befehlszeilenknoten die Funktionen OT_SRP_CLIENT und OT_ECDSA.

Der vollständige Build-Aufruf sollte also so aussehen:

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

Dem OTBR-Netzwerk beitreten

Um dem Thread-Netzwerk beizutreten, das vom Dienst otbr-agent erstellt wurde, müssen wir das aktive operative Dataset vom OTBR-Gerät abrufen. Kehren wir zur otbr-agent-Befehlszeile zurück und rufen Sie das aktive Dataset ab:

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

Kehren Sie zur Bildschirmsitzung des SRP-Clientknotens zurück und legen Sie das aktive Dataset fest:

> dataset set active 0e080000000000010000000300001235060004001fffe002083d3818dc1c8db63f0708fda85ce9df1e662005101d81689e4c0a32f3b4aa112994d29692030f4f70656e5468726561642d35326532010252e204103f23f6b8875d4b05541eeb4f9718d2f40c0302a0ff
Done

Starten Sie dann die Thread-Schnittstelle:

> ifconfig up
Done
> thread start
Done

Warten Sie einige Sekunden und prüfen Sie, ob der Beitritt zum Thread-Netzwerk erfolgreich war:

> 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

Achten Sie darauf, dass die Netzwerkdaten mit denen im OTBR übereinstimmen. Wir können die OMR-Adresse des OTBR jetzt anpingen:

> 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

5. Dienst auf dem Endgerät veröffentlichen

mDNS ist weit verbreitet, um einen DNS-SD-Dienst auf Link-Local zu veröffentlichen. Allerdings verbrauchen Multicast-Nachrichten zu viel Bandbreite und der Akku wird bei Geräten mit geringem Energieverbrauch schnell entladen. Thread registriert seine Dienste über das Unicast-SRP-Protokoll beim Border Router und nutzt den Border Router, um die Dienste über die WLAN- oder Ethernet-Verbindung zu bewerben.

Dienste können mit dem Befehl srp client registriert werden.

Rufen Sie die Bildschirmsitzung mit dem SRP-Clientknoten auf und starten Sie den SRP-Client automatisch:

> srp client autostart enable
Done

Legen Sie den Hostnamen fest, der über den WLAN-/Ethernet-Link beworben wird:

> srp client host name ot-host
Done

Damit ein Gerät über den WLAN-/Ethernet-Link ein Thread-Endgerät erreichen kann, muss die OMR-Adresse des Endgeräts angegeben werden:

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

Registrieren Sie am Ende einen gefälschten _ipps._tcp-Dienst:

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

Warten Sie einige Sekunden. Der Dienst sollte nun registriert sein:

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

Wir haben die Einrichtung abgeschlossen und für den _ipps._tcp-Dienst müsste über den WLAN-/Ethernet-Link geworben werden. Jetzt ist es an der Zeit, das Endgerät zu finden und zu erreichen!

6. Mehr erfahren

Den Dienst mit einem Smartphone entdecken

54a136a8940897cc.png

Wir verwenden die App Dienstbrowser, um mDNS-Dienste auf dem Android-Smartphone zu ermitteln. Für iOS-Mobilgeräte gibt es auch eine äquivalente App. Öffne die App. Der Dienst _ipps._tcp sollte jetzt angezeigt werden.

Dienst mit einem Linux-Host ermitteln

Wenn Sie den Dienst von einem anderen Linux-Host aus ermitteln möchten, können Sie den Befehl avahi-browse verwenden.

Installieren Sie avahi-daemon und avahi-utils:

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

Beheben Sie den Fehler:

$ 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 = []
...

Dienst mit einem macOS-Host entdecken

Sie können unter macOS dns-sd verwenden, um den Dienst aufzulösen:

$ 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     ""
...

7. Endgerät anpingen

Per Smartphone kontaktieren

Nehmen wir Pixel als Beispiel. Wir können die OMR-Adresse des zuvor registrierten Dienstes „ot-service“ ermitteln. auf der Detailseite der Dienstinstanz in der Dienstbrowser-App.

bb992962e68d250b.png 888daa1df1e1a9bf.png

Sie können die OMR-Adresse jetzt mit einer anderen Network Analyzer-App anpingen.

Leider unterstützt die Android-Version der Network Analyzer-App keine mDNS-Abfragen für das Ping-Dienstprogramm. Der Hostname ot-host.local kann nicht direkt angepingt werden. Wir können den Hostnamen mit der iOS-Version der App anpingen.

Von einem Linux-/macOS-Host aus pingen

Thread-Border-Router sendet ICMPv6-Router-Advertising, um Präfixe (über Prefix Information Option) und Routen (über Route Information Option) auf der WLAN-/Ethernet-Verbindung anzubieten.

Linux-Host vorbereiten

Achten Sie darauf, dass RA und RIO auf Ihrem Host aktiviert sind:

  1. net.ipv6.conf.wlan0.accept_ra sollte mindestens 1 sein, wenn die IP-Weiterleitung nicht aktiviert ist, andernfalls 2.
  2. net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen darf nicht kleiner als 64 sein.

accept_ra ist bei den meisten Verteilungen standardmäßig auf 1 gesetzt. Es gibt jedoch möglicherweise andere Netzwerk-Daemons, die diese Option überschreiben (z. B. überschreibt dhcpcd auf Raspberry Pi accept_ra mit 0). Sie können den accept_ra-Wert so prüfen:

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

Legen Sie den Wert auf 1 (oder 2, wenn die IP-Weiterleitung aktiviert ist) mit folgendem Befehl fest:

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

Die Option accept_ra_rt_info_max_plen ist bei den meisten Linux-Distributionen standardmäßig auf 0 festgelegt. Legen Sie Folgendes auf 64 fest:

$ 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

Die Änderung geht nach dem Neustart des Hosts verloren. Hängen Sie beispielsweise die folgenden Befehle an /etc/sysctl.conf an, um RIO dauerhaft zu aktivieren:

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

Es kann zu spät sein, diese Konfigurationen zu ändern, da das OTBR bereits RA-Meldungen gesendet hat und das Intervall zwischen zwei unerwünschten RA-Meldungen mehrere hundert Sekunden betragen kann. Eine Möglichkeit besteht darin, die Verbindung zum WLAN-ZP zu trennen und wieder zu verbinden, um die Router-Anfragenachrichten zu senden, damit das OTBR die angeforderten RAs antwortet. Eine weitere Möglichkeit besteht darin, die Border Routing-Funktion auf dem Border Router neu zu starten:

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

Wenn Sie die WLAN-Verbindung wiederherstellen oder die Ethernet-Schnittstelle neu starten möchten, achten Sie darauf, dass dhcpcd nicht zur Verwaltung Ihres WLAN-/Ethernet-IPv6-Netzwerks verwendet wird. Weil „dhcpcd“ die Option accept_ra bei jedem Neustart der Benutzeroberfläche überschreibt und Ihre accept_ra-Konfiguration verloren geht. Hängen Sie die Zeilen unten an die Konfigurationsdatei „dhcpcd“ an (z.B. /etc/dhcpcd.conf), um IPv6 in „dhcpcd“ explizit zu deaktivieren:

noipv6
noipv6rs

Du musst das Gerät neu starten, damit die Änderung wirksam wird.

macOS-Host vorbereiten

Beide accept_ra*-Optionen sind standardmäßig aktiviert, aber Sie müssen Ihr System mindestens auf macOS Big Sur aktualisieren.

Hostname oder IPv6-Adresse kontaktieren

Wir können den Hostnamen ot-host.local jetzt mit dem Befehl ping -6 (ping6 für macOS) anpingen:

$ 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
...

Dieser Befehl kann auf Linux-Hosts mit dem Fehler "Name or service not known" fehlschlagen. Das liegt daran, dass der Befehl ping den Namen ot-host.local. bei mDNS-Abfragen nicht auflöst. Öffnen Sie /etc/nsswitch.conf und fügen Sie mdns6_minimal der Zeile, die mit hosts beginnt, hinzu:

hosts:          files mdns4_minimal mdns6_minimal dns

Natürlich können Sie die IPv6-Adresse jederzeit direkt anpingen:

$ 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
...

8. Veröffentlichung des Dienstes auf dem Gerät beenden

So entfernen Sie die vom SRP-Clientknoten registrierte Adresse und den Dienst:

> srp client host remove
Done

Sie sollten den _ipps._tcp-Dienst jetzt nicht finden können.

9. Glückwunsch

Sie haben OTBR erfolgreich als Thread-Border-Router eingerichtet, um bidirektionale IP-Konnektivität und Diensterkennung für Thread-Endgeräte bereitzustellen.

Was liegt als Nächstes an?

Sehen Sie sich einige dieser Codelabs an...

Referenzdokumente