Router di confine Thread - Connettività IPv6 bidirezionale e scoperta dei servizi basati su DNS

1. Introduzione

699d673d05a55535.png

Cos'è un router di confine Thread?

Thread è un protocollo di rete mesh wireless a basso consumo basato su IP che consente comunicazioni sicure tra dispositivi e cloud. Le reti Thread possono adattarsi alle modifiche della topologia per evitare il single point of failure.

Un router di confine Thread connette una rete Thread ad altre reti basate su IP, come Wi-Fi o Ethernet. Una rete Thread richiede un router di confine per connettersi ad altre reti. Un router di confine Thread supporta minimamente le seguenti funzioni:

  • Connettività IP bidirezionale tra reti Thread e Wi-Fi/Ethernet.
  • Rilevamento bidirezionale dei servizi tramite mDNS (su collegamento Wi-Fi/Ethernet) e SRP (sulla rete Thread).
  • Thread-over-infrastruttura che unisce le partizioni Thread su link basati su IP.
  • Messa in servizio Thread esterna (ad esempio, un cellulare) per autenticare e unire un dispositivo Thread a una rete Thread.

Il router di confine OpenThread (OTBR) rilasciato da Google è un'implementazione open source del router di confine Thread.

Cosa creerai

In questo codelab, configurerai un router di confine Thread e connetterai il tuo cellulare a un dispositivo finale Thread tramite il router di confine.

Obiettivi didattici

  • Come configurare OTBR
  • Come formare una rete Thread con OTBR
  • Come creare un dispositivo con interfaccia a riga di comando OpenThread con la funzionalità SRP
  • Come registrare un servizio con SRP
  • Come trovare e raggiungere un dispositivo finale Thread.

Che cosa ti serve

  • Un dispositivo Raspberry Pi 3/4 e una scheda SD con almeno 8 GB di capacità.
  • 2 schede di sviluppo nRF52840 di Nordic Semiconductor.
  • Un punto di accesso Wi-Fi senza IPv6 Router Pubblicità Guard abilitato sul router.
  • Un telefono iOS con almeno iOS 14 o uno smartphone Android con Android 8.1 o versioni successive

2. Configura OTBR

Configura Raspberry Pi

È facile configurare un nuovo dispositivo Raspberry Pi con lo strumento rpi-imager seguendo le istruzioni su raspberrypi.org (anziché utilizzare l'ultimo sistema operativo Raspberry Pi nello strumento, scarica autonomamente 2021-05-07-raspios-buster-armhf-lite). Per completare i passaggi sul cellulare in questo codelab, devi connettere Raspberry Pi a un punto di accesso Wi-Fi. Segui questa guida per configurare la connettività wireless. Puoi accedere al Raspberry Pi tramite SSH e puoi trovare le istruzioni qui.

Richiedi codice OTBR

Accedi a Raspberry Pi e clona ot-br-posix da GitHub:

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

Creare e installare OTBR

OTBR ha due script che eseguono il bootstrap e configurano il router di confine Thread:

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

OTBR funziona sia su un'interfaccia Thread sia su un'interfaccia di rete dell'infrastruttura (ad es. Wi-Fi/Ethernet), specificata con INFRA_IF_NAME. L'interfaccia Thread viene creata da OTBR e denominata wpan0 per impostazione predefinita e l'interfaccia dell'infrastruttura ha il valore predefinito wlan0 se INFRA_IF_NAME non è specificato esplicitamente. Se il tuo Raspberry Pi è collegato tramite un cavo Ethernet, specifica il nome dell'interfaccia Ethernet (ad esempio, eth0):

$ INFRA_IF_NAME=eth0 ./script/setup

Controlla se OTBR è stato installato correttamente:

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

Il servizio otbr-agent non è attivo perché l'esecuzione richiede un chip RCP.

Riavvia il Raspberry Pi per applicare le modifiche.

Crea e esegui il flashing del firmware RCP

OTBR supporta un chip radio 15.4 in modalità Radio Co-Processor (RCP). In questa modalità, lo stack OpenThread è in esecuzione sul lato host e trasmette/riceve frame sul ricetrasmettitore IEEE802.15.4.

Segui il passaggio 4 del codelab Creare una rete Thread con schede nRF52840 e OpenThread per creare e eseguire il flashing di un dispositivo RCP nRF52840:

$ script/build nrf52840 USB_trans

Avvia OTBR e verifica lo stato

Collega la scheda nRF52840 al tuo Raspberry Pi e avvia il servizio otbr-agent:

$ sudo service otbr-agent restart

Verifica che il servizio otbr-agent sia attivo:

$ 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. Creare una rete Thread

È disponibile un comando ot-ctl che può essere utilizzato per controllare il servizio otbr-agent. ot-ctl accetta tutti i comandi dell'interfaccia a riga di comando OpenThread. Per ulteriori dettagli, consulta la guida dell'interfaccia a riga di comando OpenThread.

Crea una rete Thread con OTBR:

$ 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

Attendi qualche secondo, dovremmo riuscire a vedere che OTBR funziona come un leader di Thread e che è presente un prefisso off-mesh-routable (OMR) nei dati di rete del 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. Configura dispositivo finale client SRP

Creazione e flash dell'interfaccia a riga di comando OT

Segui il passaggio 5 del codelab Creazione di una rete Thread con schede nRF52840 e OpenThread per creare e eseguire il flashing di un dispositivo finale dell'interfaccia a riga di comando nRF52840.

Ma invece di avere OT_COMMISSIONER e OT_JOINER abilitati, il nodo dell'interfaccia a riga di comando richiede le funzionalità OT_SRP_CLIENT e OT_ECDSA.

Di conseguenza, la chiamata alla build completa dovrebbe avere il seguente aspetto:

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

Connettiti alla rete OTBR

Per unirti alla rete Thread creata dal servizio otbr-agent, dobbiamo recuperare il set di dati operativo attivo dal dispositivo OTBR. Torniamo alla riga di comando otbr-agent e recuperiamo il set di dati attivo:

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

Torna alla sessione della schermata del nodo client SRP e imposta il set di dati attivo:

> dataset set active 0e080000000000010000000300001235060004001fffe002083d3818dc1c8db63f0708fda85ce9df1e662005101d81689e4c0a32f3b4aa112994d29692030f4f70656e5468726561642d35326532010252e204103f23f6b8875d4b05541eeb4f9718d2f40c0302a0ff
Done

Quindi, avvia l'interfaccia di Thread:

> ifconfig up
Done
> thread start
Done

Attendi qualche secondo e verifica se l'accesso alla rete Thread è riuscito:

> 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

Assicurati che i dati di rete corrispondano a quelli stampati su OTBR. Ora possiamo inviare un ping all'indirizzo OMR di 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. Pubblica il Servizio sul Dispositivo finale

mDNS è stato ampiamente usato per pubblicare il servizio DNS-SD su link-local. Tuttavia, i messaggi multicast consumano troppa larghezza di banda e consumano rapidamente la batteria dei dispositivi a bassa potenza. Thread utilizza il protocollo unicast SRP per registrare i propri servizi sul router di confine e si affida al router di confine per pubblicizzare i servizi sul link Wi-Fi o Ethernet.

Possiamo registrare un servizio con il comando srp client.

Vai alla sessione della schermata del nodo client SRP e avvia automaticamente il client SRP:

> srp client autostart enable
Done

Imposta il nome host che verrà pubblicizzato sul link Wi-Fi/Ethernet:

> srp client host name ot-host
Done

Affinché un dispositivo sul link Wi-Fi/Ethernet raggiunga un dispositivo finale Thread, è necessario pubblicizzare l'indirizzo OMR del dispositivo finale:

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

Al termine, registra un servizio _ipps._tcp falso:

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

Attendi qualche secondo, dovresti riuscire a vedere il servizio registrato:

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

Abbiamo completato tutti i passaggi di configurazione e il servizio _ipps._tcp dovrebbe essere stato pubblicizzato sul link Wi-Fi/Ethernet. È il momento di scoprire e raggiungere il dispositivo finale.

6. Scopri il servizio

Scopri il servizio con un cellulare

54a136a8940897cc.png

Utilizziamo l'app Browser dei servizi per rilevare i servizi mDNS con il telefono Android; è disponibile un'app equivalente anche per i dispositivi mobili iOS. Apri l'app e dovrebbe comparire il servizio _ipps._tcp.

Scopri il servizio con un host Linux

Se vuoi trovare il servizio da un altro host Linux, puoi utilizzare il comando avahi-browse.

Installa avahi-daemon e avahi-utils:

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

Risolvi il servizio:

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

Scopri il servizio con un host macOS

Puoi utilizzare dns-sd su macOS per risolvere il servizio:

$ 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. Invia un ping al dispositivo finale

Inviare un ping da un cellulare

Prendiamo come esempio lo smartphone Pixel: possiamo trovare l'indirizzo OMR del servizio "ot-service" precedentemente registrato nella pagina dei dettagli dell'istanza di servizio nell'app Service Browser.

bb992962e68d250b.png 888daa1df1e1a9bf.png

Ora possiamo inviare un ping all'indirizzo OMR con un'altra app di Network Analyzer.

Purtroppo la versione per Android dell'app Network Analyzer non supporta le query mDNS per l'utilità ping e non possiamo inviare direttamente il nome host ot-host.local (possiamo inviare un ping al nome host con la versione per iOS dell'app).

Ping da un host Linux/macOS

Il router di confine Thread invia gli annunci del router ICMPv6 (RA) per pubblicizzare prefissi (tramite l'opzione informazioni prefisso) e le route (tramite l'opzione informazioni di percorso) sul collegamento Wi-Fi/Ethernet.

Prepara l'host Linux

È importante assicurarsi che RA e RIO siano abilitati sull'host:

  1. net.ipv6.conf.wlan0.accept_ra deve essere almeno 1 se l'IP forwarding non è abilitato e 2 in caso contrario.
  2. net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen non deve essere inferiore a 64.

il valore predefinito di accept_ra è 1 per la maggior parte delle distribuzioni. Tuttavia, potrebbero esserci altri daemon di rete che sostituiranno questa opzione (ad esempio, dhcpcd su Raspberry Pi sostituirà accept_ra in 0). Puoi controllare il valore accept_ra con:

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

Imposta il valore su 1 (o 2 nel caso in cui l'IP forwarding sia abilitato) con:

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

L'opzione accept_ra_rt_info_max_plen nella maggior parte delle distribuzioni Linux è 0, impostala su 64 con:

$ 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 modifica andrà persa dopo il riavvio dell'host. Ad esempio, aggiungi i comandi seguenti a /etc/sysctl.conf per abilitare definitivamente RIO:

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

Potrebbe essere troppo tardi per modificare queste configurazioni perché l'OTBR ha già inviato messaggi RA e l'intervallo tra due messaggi RA non richiesti potrebbe essere di diverse centinaia di secondi. Un modo è disconnettersi e riconnettersi al punto di accesso Wi-Fi per inviare messaggi di Router Richieste in modo che OTBR risponda con le RA richieste. Un'altra opzione è riavviare la funzione Border Routing sul router di confine:

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

Se stai tentando di ricollegare la rete Wi-Fi o di riavviare l'interfaccia Ethernet, assicurati che dhcpcd non sia utilizzato per gestire la tua rete IPv6 Wi-Fi/Ethernet. Perché dhcpcd sostituisce sempre l'opzione accept_ra ogni volta che viene riavviata l'interfaccia e la configurazione di accept_ra andrà persa. Aggiungi le righe di seguito al file di configurazione dhcpcd (ad es. /etc/dhcpcd.conf) per disattivare esplicitamente IPv6 in dhcpcd:

noipv6
noipv6rs

Per applicare la modifica, è necessario riavviare il dispositivo.

Preparare l'host macOS

Entrambe le opzioni di accept_ra* sono attive per impostazione predefinita, ma devi eseguire l'upgrade del sistema almeno a macOS Big Sur.

Inviare un ping al nome host o all'indirizzo IPv6

Ora possiamo inviare un ping al nome host ot-host.local con il comando ping -6 (ping6 per 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
...

Questo comando potrebbe non riuscire sugli host Linux con l'errore "Name or service not known". Il motivo è che il comando ping non risolve il nome ot-host.local. con query mDNS. Apri /etc/nsswitch.conf e aggiungi mdns6_minimal alla riga che inizia con hosts:

hosts:          files mdns4_minimal mdns6_minimal dns

Ovviamente, puoi sempre inviare un ping direttamente all'indirizzo IPv6:

$ 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. Annullamento della pubblicazione del Servizio sul dispositivo finale

Per rimuovere l'indirizzo e il servizio registrati dal nodo client SRP:

> srp client host remove
Done

Al momento non dovresti essere in grado di trovare il servizio _ipps._tcp.

9. Complimenti

Congratulazioni, hai configurato OTBR come router di confine Thread per fornire connettività IP bidirezionale e Service Discovery per i dispositivi finali Thread.

Passaggi successivi

Dai un'occhiata ad alcuni di questi codelab...

Documenti di riferimento