Routeur de bordure Thread – Connectivité IPv6 bidirectionnelle et détection de services DNS

1. Introduction

699d673d05a55535.png

Qu'est-ce qu'un routeur de bordure Thread ?

Thread est un protocole de réseau maillé sans fil basse consommation basé sur les adresses IP, qui permet une communication sécurisée d'appareil à appareil et de cloud à appareil. Les réseaux Thread peuvent s'adapter aux changements de topologie pour éviter un point de défaillance unique.

Un routeur de bordure Thread connecte un réseau Thread à d'autres réseaux IP, tels que le Wi-Fi ou Ethernet. Un réseau Thread nécessite un routeur de bordure pour se connecter à d'autres réseaux. Un routeur de bordure Thread n'accepte que les fonctions suivantes:

  • Connectivité IP bidirectionnelle entre Thread et les réseaux Wi-Fi/Ethernet.
  • Détection de services bidirectionnelle via mDNS (sur le réseau Wi-Fi/Ethernet) et SRP (sur le réseau Thread).
  • Thread sur une infrastructure qui fusionne des partitions Thread sur des liens basés sur l'adresse IP.
  • Mise en service de threads externes (par exemple, un téléphone mobile) pour authentifier et associer un appareil Thread à un réseau Thread.

Le routeur de bordure OpenThread (OTBR) publié par Google est une implémentation Open Source du routeur de bordure Thread.

Objectifs de l'atelier

Dans cet atelier de programmation, vous allez configurer un routeur de bordure Thread et connecter votre téléphone mobile à un appareil Thread End via le routeur de bordure.

Points abordés

  • Configurer le service de distribution par contournement
  • Créer un réseau Thread avec un service de distribution par contournement (OTBR, over-the-top)
  • Créer un appareil CLI OpenThread avec la fonctionnalité SRP
  • Enregistrer un service avec le SRP
  • Comment découvrir et toucher un appareil final Thread ?

Ce dont vous avez besoin

  • Un appareil Raspberry Pi 3/4 et une carte SD d'au moins 8 Go de capacité
  • 2 cartes de développement Nordn Semiconductor nRF52840.
  • Point d'accès Wi-Fi sans routeur d'annonces IPv6 activé sur le routeur.
  • Un téléphone iOS avec au moins iOS 14 ou un téléphone avec au moins Android 8.1.

2. Configurer le service de distribution par contournement

Configurer Raspberry Pi

Vous pouvez facilement configurer un nouvel appareil Raspberry Pi avec l'outil rpi-imager en suivant les instructions disponibles sur raspberrypi.org (au lieu d'utiliser la dernière version de Raspberry Pi OS dans l'outil, téléchargez 2021-05-07-raspios-buster-armhf-lite par vous-même. Pour suivre les étapes liées aux téléphones mobiles dans cet atelier de programmation, vous devez connecter Raspberry Pi à un point d'accès Wi-Fi. Suivez ce guide pour configurer la connectivité sans fil. Pour vous connecter facilement à Raspberry Pi avec SSH, consultez ces instructions.

Obtenir un code OTBR

Connectez-vous à votre Raspberry Pi et clonez ot-br-posix à partir de GitHub:

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

Compiler et installer un code OTBR

OTBR propose deux scripts qui amorcent et configurent le routeur de bordure Thread:

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

OTBR fonctionne à la fois sur une interface Thread et une interface réseau d'infrastructure (par exemple, Wi-Fi/Ethernet) spécifiée par INFRA_IF_NAME. L'interface Thread est créée par OTBR elle-même et nommée wpan0 par défaut. L'interface de l'infrastructure a la valeur par défaut wlan0 si INFRA_IF_NAME n'est pas spécifié explicitement. Si votre Raspberry Pi est connecté via un câble Ethernet, spécifiez le nom de l'interface Ethernet (par exemple, eth0):

$ INFRA_IF_NAME=eth0 ./script/setup

Vérifiez si l'OTBR est bien installé:

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

Le service otbr-agent n'est pas actif, car son exécution nécessite un chip RCP.

Redémarrez le Raspberry Pi pour appliquer les modifications.

Créer et flasher un micrologiciel RCP

OTBR est compatible avec une puce radio 15.4 en mode Coprocesseur de radio (RCP). Dans ce mode, la pile OpenThread s'exécute côté hôte et transmet/reçoit des trames via l'émetteur-récepteur IEEE802.15.4.

Suivez l'étape 4 de l'atelier de programmation Créer un réseau Thread avec des cartes nRF52840 et OpenThread pour créer et flasher un appareil RCP nRF52840:

$ script/build nrf52840 USB_trans

Lancer l'OTBR et vérifier l'état

Connectez la carte nRF52840 à votre Raspberry Pi et démarrez le service otbr-agent:

$ sudo service otbr-agent restart

Vérifiez que le service otbr-agent est actif:

$ 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. Créer un réseau Thread

Une commande ot-ctl permet de contrôler le service otbr-agent. ot-ctl accepte toutes les commandes de la CLI OpenThread. Pour en savoir plus, consultez le guide de la CLI OpenThread.

Créez un réseau Thread avec un service de distribution par contournement (OTBR, over-the-top) :

$ 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

Attendez quelques secondes, nous constatons que l'OTBR agit en tant que Thread leader et qu'il existe un préfixe off-mesh-routable (OMR) dans les données du réseau Thread:

$ 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. Configurer l'appareil de fin client SRP

Compiler et flasher la CLI OT

Suivez l'étape 5 de l'atelier de programmation Créer un réseau Thread avec des cartes nRF52840 et un thread OpenThread pour créer et flasher un appareil final de la CLI nRF52840.

Toutefois, au lieu d'avoir activé OT_COMMISSIONER et OT_JOINER, le nœud CLI requiert les fonctionnalités OT_SRP_CLIENT et OT_ECDSA.

L'appel de compilation complet doit donc se présenter comme suit:

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

Rejoindre le réseau OTBR

Pour rejoindre le réseau Thread créé par le service otbr-agent, nous devons obtenir l'ensemble de données opérationnel actif de l'appareil OTBR. Revenez à la ligne de commande otbr-agent et récupérez l'ensemble de données actif:

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

Revenez à la session d'écran du nœud client SRP et définissez l'ensemble de données actif:

> dataset set active 0e080000000000010000000300001235060004001fffe002083d3818dc1c8db63f0708fda85ce9df1e662005101d81689e4c0a32f3b4aa112994d29692030f4f70656e5468726561642d35326532010252e204103f23f6b8875d4b05541eeb4f9718d2f40c0302a0ff
Done

Ensuite, démarrez l'interface Thread:

> ifconfig up
Done
> thread start
Done

Attendez quelques secondes, puis vérifiez si la connexion au réseau Thread a réussi:

> 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

Assurez-vous que les données du réseau correspondent à celles affichées sur le service de distribution par contournement. Nous pouvons maintenant pinguer l'adresse OMR de l'OTBR:

> 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. Publier le service sur l'appareil final

mDNS a été largement utilisé pour publier le service DNS-SD sur link-local. Cependant, les messages en multidiffusion consomment trop de bande passante et épuisent rapidement la batterie des appareils à faible consommation d'énergie. Thread utilise le protocole SRP unicast pour enregistrer ses services auprès du routeur de bordure, et s'appuie sur ce routeur pour annoncer les services sur le lien Wi-Fi ou Ethernet.

Nous pouvons enregistrer un service avec la commande srp client.

Accédez à la session d'écran du nœud client SRP et démarrez automatiquement le client SRP:

> srp client autostart enable
Done

Définissez le nom d'hôte qui sera annoncé sur le lien Wi-Fi/Ethernet:

> srp client host name ot-host
Done

Pour qu'un appareil connecté au réseau Wi-Fi/Ethernet atteigne un appareil final Thread, l'adresse OMR de l'appareil final doit être annoncée:

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

À la fin, enregistrez un service _ipps._tcp fictif:

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

Patientez quelques secondes, le service devrait être enregistré:

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

Nous avons terminé toutes les configurations et le service _ipps._tcp aurait dû être annoncé via le lien Wi-Fi/Ethernet. C'est le moment de découvrir et d'atteindre l'appareil de fin !

6. Découvrir le service

Découvrir le service avec un téléphone mobile

54a136a8940897cc.png

Nous utilisons l'application Service Browser pour découvrir les services mDNS avec le téléphone Android. Une application équivalente est également disponible pour les appareils mobiles iOS. Ouvrez l'application. Le service _ipps._tcp devrait simplement s'afficher.

Découvrir le service avec un hôte Linux

Si vous souhaitez découvrir le service à partir d'un autre hôte Linux, vous pouvez utiliser la commande avahi-browse.

Installez avahi-daemon et avahi-utils :

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

Résolvez le service:

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

Découvrir le service avec un hôte macOS

Vous pouvez utiliser dns-sd sous macOS pour résoudre le service:

$ 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. Pinguer l'appareil final

Pinguer depuis un téléphone mobile

Prenons l'exemple du téléphone Pixel. Nous pouvons trouver l'adresse OMR du service précédemment enregistré "ot-service" sur la page d'informations de l'instance de service dans l'application Service Browser.

bb992962e68d250b.png 888daa1df1e1a9bf.png

Nous pouvons maintenant pinguer l'adresse OMR avec une autre application Network Analyzer.

Malheureusement, la version Android de l'application Network Analyzer ne prend pas en charge les requêtes mDNS pour l'utilitaire ping et nous ne pouvons pas pinguer directement le nom d'hôte ot-host.local (nous pouvons pinguer le nom d'hôte avec la version iOS de l'application).

Ping d'un hôte Linux/macOS

Le routeur de bordure Thread envoie des annonces de routeur ICMPv6 (RA) pour annoncer les préfixes (via l'option d'informations sur le préfixe) et les routes (via l'option d'informations sur les routes) sur le lien Wi-Fi/Ethernet.

Préparer l'hôte Linux

Il est important de vous assurer que les CRA et les RIO sont activés sur votre hôte:

  1. net.ipv6.conf.wlan0.accept_ra doit être au moins égal à 1 si le transfert IP n'est pas activé, et à 2 dans le cas contraire.
  2. net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen ne doit pas être inférieur à 64.

accept_ra est défini par défaut sur 1 pour la plupart des distributions. Cependant, il est possible que d'autres daemons du réseau ignorent cette option (par exemple, dhcpcd sur Raspberry Pi remplace accept_ra par 0). Vous pouvez vérifier la valeur accept_ra avec:

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

Définissez la valeur sur 1 (ou 2 si le transfert IP est activé) avec:

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

Sur la plupart des distributions Linux, l'option accept_ra_rt_info_max_plen est définie par défaut sur 0. Définissez-la sur 64 avec:

$ 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

La modification sera perdue après le redémarrage de l'hôte. Par exemple, ajoutez les commandes ci-dessous à /etc/sysctl.conf pour activer définitivement RIO:

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

Il est peut-être trop tard pour modifier ces configurations, car l'OTBR a déjà envoyé des messages RA, et l'intervalle entre deux messages RA non sollicités peut être de plusieurs centaines de secondes. Une solution consiste à vous déconnecter et à vous reconnecter au point d'accès Wi-Fi pour envoyer des messages de sollicitation de routeur afin que le service OTBR réponde aux demandes des CRA. Une autre option consiste à redémarrer la fonction de routage de la bordure sur le routeur de bordure:

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

Si vous essayez de reconnecter le Wi-Fi ou de redémarrer l'interface Ethernet, assurez-vous que dhcpcd n'est pas utilisé pour gérer votre réseau IPv6 Wi-Fi/Ethernet. Étant donné que dhcpcd remplace toujours l'option accept_ra à chaque redémarrage de l'interface, votre configuration accept_ra est perdue. Ajoutez les lignes ci-dessous au fichier de configuration dhcpcd (par exemple, /etc/dhcpcd.conf) pour désactiver explicitement IPv6 dans dhcpcd:

noipv6
noipv6rs

Vous devez redémarrer pour appliquer les modifications.

Préparer l'hôte macOS

Les deux options accept_ra* sont activées par défaut, mais vous devez mettre à niveau votre système vers macOS Big Sur au minimum.

Pinguer le nom d'hôte ou l'adresse IPv6

Nous pouvons maintenant pinguer le nom d'hôte ot-host.local à l'aide de la commande ping -6 (ping6 pour macOS):

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

Cette commande peut échouer sur les hôtes Linux avec l'erreur "Name or service not known". Cela est dû au fait que la commande ping ne résout pas le nom ot-host.local. avec les requêtes mDNS. Ouvrez /etc/nsswitch.conf et ajoutez mdns6_minimal à la ligne commençant par hosts:

hosts:          files mdns4_minimal mdns6_minimal dns

Bien entendu, vous pouvez toujours pinguer l'adresse IPv6 directement:

$ 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. Annuler la publication du service sur l'appareil final

Pour supprimer l'adresse et le service enregistrés du nœud client SRP:

> srp client host remove
Done

Vous ne devriez pas avoir la possibilité de découvrir le service _ipps._tcp maintenant.

9. Félicitations

Félicitations, vous avez bien configuré l'OTBR en tant que routeur de bordure Thread pour fournir une connectivité IP bidirectionnelle et la détection de services sur les appareils Thread.

Et ensuite ?

Explorez ces ateliers de programmation :

Documents de référence