Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.

Router de borde de Thread: Conectividad IPv6 bidireccional y descubrimiento de servicios basados en DNS

1. Introducción

699d673d05a55535.png

¿Qué es un router de borde de Thread?

Thread es un protocolo de red en malla inalámbrico de bajo consumo basado en IP que permite establecer comunicaciones seguras de un dispositivo a otro y de un dispositivo a la nube. Las redes de subprocesos pueden adaptarse a los cambios de topología para evitar un punto único de fallo.

Un router de borde de Thread conecta una red Thread a otras redes basadas en IP, como Wi-Fi o Ethernet. Una red Thread requiere un router de borde para conectarse a otras redes. Un router de borde de Thread admite, mínimamente, las siguientes funciones:

  • Conectividad de IP bidireccional entre Thread y redes Wi-Fi/Ethernet
  • Descubrimiento de servicios bidireccionales a través de mDNS (en vínculos Wi-Fi/Ethernet) y SRP (en redes Thread).
  • Thread-over-Infrastructure que combina particiones de Thread a través de vínculos basados en IP.
  • Comisión de Thread externa (por ejemplo, un teléfono celular) para autenticar y unir un dispositivo Thread a una red Thread.

El router de bordes de Thread (OTBR) que lanzó Google es una implementación de código abierto del router de borde de Thread.

Qué compilarás

En este codelab, configurarás un router de borde de Thread y conectarás tu teléfono móvil a un dispositivo de extremo de Thread a través del router de borde.

Qué aprenderás

  • Cómo configurar OTBR
  • Cómo formar una red Thread con OTBR
  • Cómo compilar un dispositivo de CLI de OpenThread con la función SRP
  • Cómo registrar un servicio con SRP
  • Cómo descubrir y llegar a un dispositivo final de Thread

Requisitos

  • Un dispositivo Raspberry Pi 3/4 y una tarjeta SD con al menos 8 GB de capacidad
  • 2 placas de desarrollo nórdicas semiconductoras nRF52840.
  • Un PA de Wi-Fi sin la protección de publicidad del router IPv6 habilitada en el router
  • Un teléfono iOS con al menos iOS 14 o Android que tenga, como mínimo, Android 8.1.

2. Configurar OTBR

Configura Raspberry Pi

Es fácil configurar un dispositivo Raspberry Pi nuevo con la herramienta rpi-imager. Para ello, sigue las instrucciones en raspberrypi.org (en lugar de usar el último SO Raspberry Pi en la herramienta, descarga 2021-05-07-raspios-buster-armhf-lite por tu cuenta). Para completar los pasos del teléfono móvil en este codelab, debes conectar la Raspberry Pi a un PA de Wi-Fi. Sigue esta guía para configurar la conectividad inalámbrica. Es conveniente acceder a la placa Raspberry Pi con SSH. Puedes encontrar las instrucciones aquí.

Obtener código OTBR

Accede a tu Raspberry Pi y clona ot-br-posix desde GitHub:

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

Compilación e instalación de OTBR

OTBR tiene dos secuencias de comandos que inician y configuran el router de borde de Thread:

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

OTBR funciona tanto en una interfaz de Thread como en una de red de infraestructura (p.ej., Wi-Fi o Ethernet), que se especifica con INFRA_IF_NAME. La interfaz de Thread es creada por OTBR con el nombre wpan0 de forma predeterminada, y la interfaz de infraestructura tiene un valor predeterminado de wlan0 si no se especifica INFRA_IF_NAME de manera explícita. Si la placa Raspberry Pi está conectada mediante un cable Ethernet, especifica el nombre de la interfaz Ethernet (p.ej., eth0):

$ INFRA_IF_NAME=eth0 ./script/setup

Verifica si OTBR se instaló correctamente:

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

Se espera que el servicio otbr-agent no esté activo, ya que requiere un chip RCP para ejecutarse.

Reinicia la placa Raspberry Pi para aplicar los cambios.

Cómo compilar e instalar firmware de RCP

OTBR admite un chip de radio de 15.4 en modo de coprocesador de radio (RCP). En este modo, la pila de OpenThread se ejecuta en el lado del host y transmite/recibe fotogramas a través del transmisor IEEE802.15.4.

Sigue el paso 4 del módulo Cómo compilar una red Thread con placas nRF52840 y OpenThread para compilar y escribir en la memoria flash un dispositivo RCP nRF52840:

$ script/build nrf52840 USB_trans

Iniciar OTBR y verificar el estado

Conecta la placa nRF52840 a tu Raspberry Pi y, luego, inicia el servicio otbr-agent:

$ sudo service otbr-agent restart

Verifica que el servicio otbr-agent esté activo:

$ 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. Crea una red Thread

Hay un comando ot-ctl que se puede usar para controlar el servicio otbr-agent. ot-ctl acepta todos los comandos de la CLI de OpenThread. Consulta la Guía de la CLI de OpenThread para obtener más detalles.

Forma una red 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

Espera unos segundos, deberíamos poder ver que OTBR actúa como un subproceso Thread leader y que hay un prefijo off-mesh-routable (OMR) en los datos de Thread Network:

$ 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 el dispositivo de cliente SRP

Crea e instala la CLI de OT

Sigue el paso 5 del panel Cómo crear una red Thread con placas nRF52840 y OpenThread para compilar e instalar un dispositivo final nRF52840 de la CLI.

Sin embargo, en lugar de tener habilitados OT_COMMISSIONER y OT_JOINER, el nodo de la CLI requiere las funciones OT_SRP_CLIENT y OT_ECDSA.

La invocación de compilación completa debería verse así:

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

Únete a la red OTBR

Para unir la red Thread que creó el servicio otbr-agent, debemos obtener el conjunto de datos operativo activo del dispositivo OTBR. Volvamos a la línea de comandos de otbr-agent y obtengamos el conjunto de datos activo:

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

Regresa a la sesión de pantalla de nodo de cliente de SRP y configura el conjunto de datos activo:

> dataset set active 0e080000000000010000000300001235060004001fffe002083d3818dc1c8db63f0708fda85ce9df1e662005101d81689e4c0a32f3b4aa112994d29692030f4f70656e5468726561642d35326532010252e204103f23f6b8875d4b05541eeb4f9718d2f40c0302a0ff
Done

Luego, inicia la interfaz de Thread:

> ifconfig up
Done
> thread start
Done

Espera unos segundos y verifica si la unión a la red Thread se realizó correctamente:

> 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

Asegúrate de que los datos de la red coincidan con la información impresa en OTBR. Ahora podemos hacer ping a la dirección OMR de 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. Publica el Servicio en el dispositivo final

mDNS se usa ampliamente para publicar el servicio de DNS-SD en vínculos locales. Sin embargo, los mensajes multidifusión consumen demasiado ancho de banda y agotarán rápidamente la batería de los dispositivos de baja energía. Thread usa el protocolo Unicast SRP para registrar sus servicios con el router de borde y depende del router de borde para anunciar los servicios en el vínculo de Wi-Fi o Ethernet.

Podemos registrar un servicio con el comando srp client.

Ve a la sesión de pantalla del nodo del cliente de SRP y, luego, inicia automáticamente el cliente de SRP:

> srp client autostart enable
Done

Establece el nombre de host que se anunciará en el vínculo de Wi-Fi o Ethernet:

> srp client host name ot-host
Done

Para que un dispositivo en el vínculo de Wi-Fi o Ethernet llegue a un dispositivo final de Thread, se debe anunciar la dirección OMR del dispositivo:

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

Al final, registra un servicio _ipps._tcp falso:

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

Espera unos segundos y podremos ver el servicio registrado:

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

Completamos todos los trabajos de configuración y el servicio _ipps._tcp debería haberse publicado en el vínculo de Wi-Fi o Ethernet. Ahora es el momento de descubrir y llegar al dispositivo final.

6. Descubre el Servicio

Descubre el servicio con un teléfono celular

54a136a8940897cc.png

Usamos la app del navegador de servicios para descubrir servicios mDNS con el teléfono Android. También se puede encontrar una app equivalente para dispositivos móviles iOS. Abre la app. El servicio _ipps._tcp debería aparecer.

Descubra el servicio con un host de Linux

Si deseas descubrir el servicio de otro host de Linux, puedes usar el comando avahi-browse.

Instala avahi-daemon y avahi-utils:

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

Resuelve el servicio:

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

Descubre el servicio con un host de macOS

Puedes usar dns-sd en macOS para resolver el servicio:

$ 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. Haz ping al dispositivo final

Cómo hacer ping desde un teléfono celular

Tomemos como ejemplo el teléfono Pixel. Encontraremos la dirección de OMR del servicio registrado previamente en la página de detalles de la instancia del servicio en la app del navegador de servicios.

bb992962e68d250b.png 888daa1df1e1a9bf.png

Ahora podemos hacer ping a la dirección OMR con otra app de Network Analyzer.

Lamentablemente, la versión de Android de la app de Network Analyzer no admite consultas de mDNS para la utilidad de ping y no podemos hacer ping directamente al nombre de host ot-host.local (podemos hacer ping al nombre de host con la versión de iOS de la app).

Haz ping desde un host de Linux o macOS

El router de borde de Thread envía anuncios ICMPv6 del router (RA) para anunciar prefijos (mediante la opción de información de prefijos) y rutas (mediante la opción de información de ruta) en el vínculo de Wi-Fi/Ethernet.

Prepara el host de Linux

Es importante asegurarse de que la RA y el RIO estén habilitados en su host:

  1. net.ipv6.conf.wlan0.accept_ra debe ser al menos 1 si el reenvío de IP no está habilitado y, en caso contrario, 2.
  2. net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen no debe ser inferior a 64.

El valor predeterminado de accept_ra es 1 para la mayoría de las distribuciones. Sin embargo, es posible que haya otros daemons de red que anulen esta opción (por ejemplo, dhcpcd en Raspberry Pi anulará accept_ra en 0). Puedes verificar el valor accept_ra con lo siguiente:

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

Establezca el valor en 1 (o 2 en caso de que el reenvío de IP esté habilitado) con lo siguiente:

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

La opción accept_ra_rt_info_max_plen en la mayoría de las distribuciones de Linux es la opción predeterminada 0, configurada en 64 con lo siguiente:

$ 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

El cambio se perderá después de reiniciar el host. Por ejemplo, agrega los siguientes comandos a /etc/sysctl.conf para habilitar de forma permanente RIO:

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

Puede ser demasiado tarde para cambiar esas configuraciones porque el OTBR ya ha estado enviando mensajes de RA y el intervalo entre dos mensajes de RA no solicitados podría ser de varios cientos de segundos. Una forma de hacerlo es desconectarte y volver a conectarte a la red PA de Wi-Fi para enviar mensajes de solicitudes de router a fin de que OTBR responda con las cuentas adquiridas recientemente. Otra opción es reiniciar la función de enrutamiento de borde en el router de borde:

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

Si intentas volver a conectar Wi-Fi o reiniciar la interfaz Ethernet, asegúrate de que no se use dhcpcd para administrar la red IPv6/Wi-Fi IPv6. Dado que dhcpcd siempre anula la opción accept_ra cada vez que se reinicia la interfaz y se pierde la configuración de accept_ra. Adjunta las siguientes líneas al archivo de configuración de dhcpcd (p.ej., /etc/dhcpcd.conf) para inhabilitar explícitamente IPv6 en dhcpcd:

noipv6
noipv6rs

Debes reiniciar para que el cambio entre en vigencia.

Prepara el host de macOS

Ambas accept_ra* opciones están habilitadas de forma predeterminada, pero debes actualizar tu sistema a, al menos, macOS Big Sur.

Haga ping al nombre de host o dirección IPv6

Ahora podemos hacer ping al nombre de host ot-host.local con el comando ping -6 (ping6 para 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
...

Este comando puede fallar en hosts de Linux con el error "Name or service not known". Eso se debe a que el comando ping no resuelve el nombre ot-host.local. con las consultas mDNS. Abre /etc/nsswitch.conf y agrega mdns6_minimal a la línea que comienza con hosts:

hosts:          files mdns4_minimal mdns6_minimal dns

Por supuesto, siempre puedes hacer ping directamente a la dirección 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. Anular la publicación del servicio en el dispositivo final

Para quitar la dirección y el servicio registrados en el nodo cliente de SRP, sigue estos pasos:

> srp client host remove
Done

No deberías poder descubrir el servicio de _ipps._tcp ahora.

9. Felicitaciones

Felicitaciones, configuraste correctamente OTBR como un router de borde de Thread a fin de proporcionar conectividad IP bidireccional y descubrimiento de servicios para dispositivos finales de Thread.

¿Qué sigue?

Consulta algunos de estos Codelabs…

Documentos de referencia