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 drahtloses Mesh-Netzwerkprotokoll mit geringem Stromverbrauch, das eine sichere Kommunikation zwischen Geräten und Clouds 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. Für ein Thread-Netzwerk ist ein Border-Router erforderlich, um eine Verbindung zu anderen Netzwerken herzustellen. Ein Thread-Border-Router unterstützt mindestens die folgenden Funktionen:

  • Bidirektionale IP-Verbindung zwischen Thread- und WLAN-/Ethernet-Netzwerken.
  • Bidirektionale Diensterkennung über mDNS (WLAN-/Ethernet-Link) und SRP (Thread-Netzwerk).
  • Thread-over-Infrastruktur, die Thread-Partitionen über IP-basierte Links verbindet.
  • Externe Thread-Inbetriebnahme (z. B. ein Smartphone), um sich zu authentifizieren und ein Thread-Gerät mit einem Thread-Netzwerk zu verbinden.

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

Entwicklung

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
  • So erstellen Sie ein Thread-Netzwerk mit OTBR
  • OpenThread CLI-Gerät mit dem SRP-Feature erstellen
  • Dienst bei SRP registrieren
  • Thread-Endgeräte finden und erreichen

Voraussetzungen

  • Ein Raspberry Pi 3/4-Gerät und eine SD-Karte mit mindestens 8 GB Kapazität.
  • 2 Nordic Semiconductor nRF52840 Entwicklerplatten.
  • Ein WLAN-ZP, bei dem IPv6 Router Advertising Guard nicht auf dem Router aktiviert ist.
  • Ein iOS-Smartphone mit iOS 14 oder Android 8.1 oder höher.

2. OTBR einrichten

Raspberry Pi einrichten

Mit dem rpi-imager-Tool können Sie ganz einfach ein neues Raspberry Pi-Gerät einrichten. Folgen Sie dazu der Anleitung auf 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 Mobilgeräte in diesem Codelab abzuschließen, müssen Sie den Raspberry Pi mit einem WLAN-AP verbinden. Folgen Sie dieser Anleitung, um eine drahtlose Verbindung einzurichten. Wir empfehlen Ihnen, sich mit SSH im Raspberry Pi anzumelden. Hier finden Sie die Anleitung.

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 verfügt über zwei Skripts, die den Thread-Border-Router überstrahlen und einrichten:

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

OTBR funktioniert sowohl mit einer Thread-Schnittstelle als auch mit einer Netzwerk-Netzwerkschnittstelle (z.B. WLAN/Ethernet), die mit INFRA_IF_NAME angegeben wird. Die Thread-Schnittstelle wird von OTBR selbst erstellt und standardmäßig mit wpan0 benannt. Die Infrastrukturschnittstelle hat den Standardwert wlan0, wenn INFRA_IF_NAME nicht ausdrücklich angegeben ist. Wenn der Raspberry Pi über ein Ethernetkabel verbunden ist, geben Sie den Ethernet-Schnittstellennamen 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 er einen RCP-Chip benötigt.

Starten Sie den Raspberry Pi neu, um die Änderungen zu übernehmen.

RCP-Firmware erstellen und Flash ausführen

OTBR unterstützt einen 15,4-Radio-Chip im Radio Co-Processor (RCP)-Modus. In diesem Modus wird der OpenThread-Stack auf der Hostseite ausgeführt und sendet/empfangen Frames über den IEEE802.15.4-Transceiver.

Führen Sie Schritt 4 des Builds eines Thread-Netzwerks mit nRF52840-Boards und OpenThread-Codelab aus, um ein nRF52840 RCP-Gerät zu erstellen und zu blinken:

$ script/build nrf52840 USB_trans

OTBR starten und Status prüfen

Verbinden Sie das nRF52840-Board mit Ihrem Raspberry Pi und starten Sie den Dienst otbr-agent:

$ sudo service otbr-agent restart

Prüfen Sie, ob der otbr-agent-Dienst 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 OpenCLI-Befehlszeilenbefehle. Weitere Informationen finden Sie im OpenThread CLI Guide.

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 einige Sekunden. Wir sollten sehen, dass OTBR als Thread leader fungiert und in den Thread-Netzwerkdaten das Präfix off-mesh-routable (OMR) steht:

$ 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 Flash ausführen

Führen Sie Schritt 5 des Builds eines Thread-Netzwerks mit nRF52840-Boards und OpenThread-Codelab aus, um ein nRF52840 CLI-Endgerät zu erstellen und zu blinken.

Anstatt OT_COMMISSIONER und OT_JOINER aktiviert zu sein, sind für den CLI-Knoten allerdings die Features OT_SRP_CLIENT und OT_ECDSA erforderlich.

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

Zur Verbindung mit dem vom Dienst otbr-agent erstellten Thread-Netzwerk muss das Active Operational Dataset vom OTBR-Gerät abgerufen werden. Kehren wir zurück zur Befehlszeile otbr-agent zurück, um das aktive Dataset abzurufen:

$ 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-Oberfläche:

> ifconfig up
Done
> thread start
Done

Warten Sie einige Sekunden und prüfen Sie, ob die Verbindung 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

Die Netzwerkdaten müssen mit den Netzwerkdaten übereinstimmen, die auf OTBR gedruckt werden. Wir können jetzt die OMR-Adresse von OTBR kontaktieren:

> 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 wird häufig zur Veröffentlichung von DNS-SD-Diensten auf Link-Local verwendet. Multicast-Nachrichten verbrauchen jedoch zu viel Bandbreite und verbrauchen den Akku für Geräte mit geringem Stromverbrauch schnell. Thread verwendet das Unicast-SRP-Protokoll, um die Dienste beim Border Router zu registrieren. Für die Werbung der Dienste über den WLAN- oder Ethernet-Link nutzt sie den Border-Router.

Mit dem Befehl srp client können wir einen Dienst registrieren.

Rufen Sie die Bildschirmsitzung für den 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 beworben werden:

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

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

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

Warten Sie einige Sekunden, damit der Dienst registriert werden kann:

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

Die Einrichtung war abgeschlossen und der _ipps._tcp-Dienst sollte über den WLAN-/Ethernet-Link beworben werden. Es ist Zeit, das Endgerät zu finden und zu erreichen.

6. Dienst ansehen

Den Dienst mit einem Smartphone entdecken

54a136a8940897cc

Wir verwenden die Service Browser App, um mDNS-Dienste mit dem Android-Smartphone zu erkennen. Eine äquivalente App kann auch für iOS-Mobilgeräte gefunden werden. Öffne die App. Dann sollte der Dienst _ipps._tcp angezeigt werden.

Dienst mit einem Linux-Host entdecken

Wenn Sie den Dienst von einem anderen Linux-Host herausfinden 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 Dienst:

$ 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 dns-sd unter macOS 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 pingen

Benachrichtigungen von einem Smartphone senden

Als Beispiel finden wir die OMR-Adresse des zuvor registrierten Dienstes „ot-service“ von Pixel in der Service Browser App auf der Detailseite der Dienstinstanz.

bb992962e68d250b.png. 888daa1df1e1a9bf.png

Wir können die OMR-Adresse jetzt mit einer anderen Network Analyzer-App kontaktieren.

Leider unterstützt die Android-Version der Network Analyzer App keine mDNS-Abfragen für das Ping-Dienstprogramm und wir können den Hostnamen ot-host.local nicht direkt anpingen. Wir können den Hostnamen jedoch mit der iOS-Version der App kontaktieren.

Ping von einem Linux-/macOS-Host

Der Thread-Border-Router sendet ICMPv6-Router-Anzeigen (RA) zum Bewerben von Präfixen (über die Option für Präfixinformationen) und Routen (über die Option für Routeninformationen) über den WLAN-/Ethernet-Link.

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 betragen, 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 für die meisten Distributionen auf 1 gesetzt. Möglicherweise gibt es aber andere Netzwerk-Daemons, die diese Option überschreiben (z. B. überschreiben dhcpcd auf Raspberry Pi accept_ra auf 0). Sie können den accept_ra-Wert mit folgendem Befehl prüfen:

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

Setzen Sie den Wert auf 1 (oder 2, wenn die IP-Weiterleitung aktiviert ist):

$ 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 eingestellt und muss auf 64 gesetzt werden:

$ 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. Fügen 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 ist möglicherweise zu spät, diese Konfigurationen zu ändern, da der OTBR bereits RA-Nachrichten gesendet hat und das Intervall zwischen zwei nicht angeforderten RA-Nachrichten mehrere hundert Sekunden betragen kann. Eine Möglichkeit besteht darin, die Verbindung zum Wi-Fi AP zu trennen und wieder zu verbinden, um Router-Anfragenachrichten zu senden, damit OTBR mit den angeforderten RAs antwortet. Sie können die Border Routing-Funktion auch auf dem Border-Router neu starten:

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

Wenn Sie versuchen, das WLAN wieder zu verbinden oder eine Ethernet-Schnittstelle neu zu starten, achten Sie darauf, dass dhcpcd nicht für die Verwaltung Ihres WLAN-/Ethernet-IPv6-Netzwerks verwendet wird. Da „dhcpcd“ jedes Mal die Option accept_ra überschreibt, wenn die Benutzeroberfläche neu gestartet wird und Ihre accept_ra-Konfiguration verloren geht. Hängen Sie die folgenden Zeilen an die dhcpcd-Konfigurationsdatei an (z.B. /etc/dhcpcd.conf), um IPv6 in dhcpcd explizit zu deaktivieren:

noipv6
noipv6rs

Sie müssen das Gerät neu starten, damit die Änderung wirksam wird.

macOS-Host vorbereiten

Beide accept_ra*-Optionen sind standardmäßig aktiviert. Du musst dein System aber auf mindestens macOS Big Sur aktualisieren.

Hostname oder IPv6-Adresse kontaktieren

Wir können jetzt den Hostnamen ot-host.local mit dem Befehl ping -6 (ping6 unter macOS) kontaktieren:

$ 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. nicht mit mDNS-Abfragen aufgelöst. Öffnen Sie /etc/nsswitch.conf und fügen Sie mdns6_minimal der Zeile hinzu, die mit hosts beginnt:

hosts:          files mdns4_minimal mdns6_minimal dns

Natürlich können Sie die IPv6-Adresse auch 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 Gerät beenden

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

> srp client host remove
Done

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

9. Glückwunsch

Glückwunsch. Sie haben OTBR als Thread-Border-Router eingerichtet, um bidirektionale IP-Verbindungen und Diensterkennung für Thread-Endgeräte bereitzustellen.

Was liegt als Nächstes an?

Sehen Sie sich einige dieser Codelabs an...

Referenzdokumente