Roteador de borda do Thread: conectividade IPv6 bidirecional e descoberta de serviços baseada em DNS

1. Introdução

699d673d05a55535.png

O que é o Thread?

O Thread é um protocolo de rede mesh sem fio de baixo consumo energético baseado em IP que permite comunicações seguras entre dispositivos e entre dispositivos e a nuvem. As redes Thread podem se adaptar a mudanças de topologia para evitar falhas de ponto único.

O que é o OpenThread?

O OpenThread lançado pelo Google é uma implementação de código aberto do Thread®.

O que é um roteador de borda do Thread?

Um roteador de borda do Thread conecta uma rede Thread a outras redes baseadas em IP, como Wi-Fi ou Ethernet. Uma rede Thread requer um roteador de borda para se conectar a outras redes. Um roteador de borda do Thread oferece suporte mínimo às seguintes funções:

  • Conectividade IP bidirecional entre redes Thread e Wi-Fi/Ethernet.
  • Descoberta de serviços bidirecional por mDNS (em link Wi-Fi/Ethernet) e SRP (na rede Thread).
  • Thread-over-infrastructure que mescla partições de thread em links baseados em IP.
  • Comissionamento externo do Thread (por exemplo, um smartphone) para autenticar e conectar um dispositivo Thread a uma rede Thread.

O OpenThread Border Router (OTBR) lançado pelo Google é uma implementação de código aberto do Thread Border Router.

O que você vai criar

Neste codelab, você vai configurar um roteador de borda do Thread e conectar seu smartphone a um dispositivo final do Thread usando o roteador de borda.

O que você vai aprender

  • Como configurar o OTBR
  • Como formar uma rede Thread com o OTBR
  • Como criar um dispositivo de CLI do OpenThread com o recurso SRP
  • Como registrar um serviço com o SRP
  • Como descobrir e acessar um dispositivo final do Thread

O que é necessário

  • Uma estação de trabalho Linux para criar e atualizar um RCP de thread, a CLI do OpenThread e testar o multicast IPv6.
  • Um Raspberry Pi para o roteador de borda do Thread.
  • Dois dongles USB nRF52840 da Nordic Semiconductor (um para o RCP e outro para o dispositivo final da Thread).
  • Um smartphone iOS com pelo menos o iOS 14 ou um smartphone Android com pelo menos o Android 8.1.

2. Configurar o OTBR

A maneira mais rápida de configurar um OTBR é seguindo o guia de configuração do OTBR.

Depois que a configuração do OTBR for concluída, use ot-ctl para validar se o OTBR está agindo como um leader do Thread.

$ sudo ot-ctl state
leader
Done

Verifique também se o OTBR configurou automaticamente um prefixo off-mesh-routable (OMR) nos dados da rede Thread.

$ 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

3. Configurar o dispositivo final do cliente SRP

Criar e atualizar a OT CLI

Siga a etapa 5 do codelab Criar uma rede Thread com placas nRF52840 e OpenThread para criar e atualizar um dispositivo final de CLI nRF52840.

No entanto, em vez de ativar OT_COMMISSIONER e OT_JOINER, o nó da CLI exige os recursos OT_SRP_CLIENT e OT_ECDSA.

A invocação de build completa vai ficar assim:

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

Entrar na rede Thread

Para participar da rede Thread, precisamos receber o conjunto de dados operacionais ativo do dispositivo OTBR. Vamos voltar para ot-ctl e receber o conjunto de dados ativo:

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

Retorne à sessão da tela do nó do cliente SRP e defina o conjunto de dados ativo:

> dataset set active 0e080000000000010000000300001235060004001fffe002083d3818dc1c8db63f0708fda85ce9df1e662005101d81689e4c0a32f3b4aa112994d29692030f4f70656e5468726561642d35326532010252e204103f23f6b8875d4b05541eeb4f9718d2f40c0302a0ff
Done

Em seguida, inicie a interface da Thread:

> ifconfig up
Done
> thread start
Done

Aguarde alguns segundos e verifique se a conexão com a rede Thread foi bem-sucedida:

> 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

Verifique se os dados da rede correspondem aos impressos no OTBR. Agora podemos fazer um ping no endereço OMR do 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

4. Publicar o serviço no dispositivo final

O mDNS tem sido amplamente usado para publicar o serviço DNS-SD em link local. No entanto, as mensagens multicast consomem muita largura de banda e esgotam rapidamente a bateria de dispositivos de baixa potência. O Thread usa o protocolo unicast SRP para registrar os serviços no roteador de borda e depende dele para anunciar os serviços no link Wi-Fi ou Ethernet.

É possível registrar um serviço com o comando srp client.

Acesse a sessão da tela do nó do cliente SRP e inicie automaticamente o cliente SRP:

> srp client autostart enable
Done

Defina o nome do host que será anunciado no link Wi-Fi/Ethernet:

> srp client host name ot-host
Done

Para que um dispositivo no link Wi-Fi/Ethernet alcance um dispositivo final do Thread, o endereço OMR do dispositivo final precisa ser anunciado:

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

No final, registre um serviço _ipps._tcp falso:

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

Aguarde alguns segundos para que o serviço registrado apareça:

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

Concluímos todo o trabalho de configuração, e o serviço _ipps._tcp foi anunciado no link Wi-Fi/Ethernet. É hora de descobrir e alcançar o dispositivo final.

5. Descobrir o serviço

Descobrir o serviço com um smartphone

54a136a8940897cc.png

Usamos o app Service Browser para descobrir serviços mDNS com o smartphone Android. Um app equivalente também pode ser encontrado para dispositivos móveis iOS. Abra o app e o serviço _ipps._tcp vai aparecer.

Descobrir o serviço com um host Linux

Se você quiser descobrir o serviço em outro host do Linux, use o comando avahi-browse.

Instale avahi-daemon e avahi-utils:

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

Resolva o serviço:

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

Descobrir o serviço com um host do macOS

Você pode usar dns-sd no macOS para resolver o serviço:

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

6. Fazer ping no dispositivo final

Ping de um smartphone

Tomando o smartphone Pixel como exemplo, podemos descobrir o endereço OMR do serviço "ot-service" registrado anteriormente na página de detalhes da instância do serviço no app do navegador de serviços.

bb992962e68d250b.png 888daa1df1e1a9bf.png

Agora podemos fazer ping no endereço OMR com outro app Network Analyzer.

Infelizmente, a versão do Android do Network Analyzer não oferece suporte a consultas mDNS para o utilitário de ping, e não é possível fazer ping no nome do host ot-host.local diretamente (é possível fazer ping no nome do host com a versão iOS do app).

Fazer ping de um host Linux/macOS

O Thread Border Router envia anúncios de roteador ICMPv6 (RA) para anunciar prefixos (pela opção de informações de prefixo) e rotas (pela opção de informações de rota) no link Wi-Fi/Ethernet.

Preparar o host Linux

É importante garantir que a RA e a RIO estejam ativadas no host:

  1. net.ipv6.conf.wlan0.accept_ra precisa ser pelo menos 1 se o encaminhamento de IP não estiver ativado e 2 caso contrário.
  2. net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen não pode ser menor que 64.

o accept_ra é definido como 1 por padrão na maioria das distribuições. No entanto, pode haver outros demônios de rede que vão substituir essa opção. Por exemplo, dhcpcd no Raspberry Pi vai substituir accept_ra por 0. Você pode verificar o valor de accept_ra com:

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

E defina o valor como 1 (ou 2 caso o encaminhamento de IP esteja ativado) com:

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

A opção accept_ra_rt_info_max_plen na maioria das distribuições Linux é 0 por padrão. Defina-a como 64 com:

$ 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

A mudança será perdida após a reinicialização do host. Por exemplo, adicione os comandos abaixo a /etc/sysctl.conf para ativar permanentemente o RIO:

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

Pode ser tarde demais para mudar essas configurações, porque o OTBR já está enviando mensagens de RA e o intervalo entre duas mensagens de RA não solicitadas pode ser de várias centenas de segundos. Uma maneira é desconectar e se reconectar ao AP Wi-Fi para enviar mensagens de solicitação de roteador para que o OTBR responda com RAs solicitados. Outra opção é reiniciar a função de roteamento de fronteira no roteador de fronteira:

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

Se você estiver tentando se reconectar ao Wi-Fi ou reiniciar a interface Ethernet, verifique se o dhcpcd não é usado para gerenciar a rede Wi-Fi/Ethernet IPv6. Porque o dhcpcd sempre substitui a opção accept_ra sempre que a interface é reiniciada, e a configuração de accept_ra é perdida. Anexe as linhas abaixo ao arquivo de configuração do dhcpcd (por exemplo, /etc/dhcpcd.conf) para desativar explicitamente o IPv6 no dhcpcd:

noipv6
noipv6rs

É necessário reiniciar para que a mudança entre em vigor.

Preparar o host do macOS

As duas opções accept_ra* são ativadas por padrão, mas você precisa fazer upgrade do sistema para pelo menos o macOS Big Sur.

Fazer ping do nome do host ou do endereço IPv6

Agora podemos fazer ping no nome do host ot-host.local com o comando ping -6 (ping6 no 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
...

Esse comando pode falhar em hosts Linux com o erro "Name or service not known". Isso ocorre porque o comando ping não está resolvendo o nome ot-host.local. com consultas mDNS. Abra /etc/nsswitch.conf e adicione mdns6_minimal à linha que começa com hosts:

hosts:          files mdns4_minimal mdns6_minimal dns

É claro que você sempre pode fazer ping no endereço IPv6 diretamente:

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

7. Despublicar o serviço no dispositivo final

Para remover o endereço e o serviço registrados do nó de cliente SRP:

> srp client host remove
Done

Não será possível descobrir o serviço _ipps._tcp agora.

8. Parabéns

Parabéns! Você configurou o OTBR como um roteador de borda do Thread para fornecer conectividade IP bidirecional e descoberta de serviços para dispositivos finais do Thread.

A seguir

Confira alguns destes codelabs:

Documentos de referência