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 na topologia para evitar falhas em um único ponto.

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 Thread conecta uma rede Thread a outras redes baseadas em IP, como Wi-Fi ou Ethernet. Uma rede Thread precisa de 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 via mDNS (em link Wi-Fi/Ethernet) e SRP (em rede Thread).
  • Thread sobre infraestrutura que mescla partições do 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 roteador de borda OpenThread (OTBR, na sigla em inglês) lançado pelo Google é uma implementação de código aberto do roteador de borda Thread.

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 CLI OpenThread com o recurso SRP
  • Como registrar um serviço com o SRP
  • Como descobrir e alcançar um dispositivo final Thread

O que é necessário

  • Uma estação de trabalho Linux para criar e atualizar um RCP Thread, a CLI OpenThread e testar o multicast IPv6.
  • Um Raspberry Pi para o roteador de borda do Thread.
  • 2 dongles USB Nordic Semiconductor nRF52840 (um para o RCP e um para o dispositivo final 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á atuando como um leader do Thread.

$ sudo ot-ctl state
leader
Done

Valide 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 CLI OT

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

Em vez de ter OT_COMMISSIONER e OT_JOINER ativados, o nó da CLI requer os recursos OT_SRP_CLIENT e OT_ECDSA.

Portanto, 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 entrar na rede Thread, precisamos receber o conjunto de dados operacionais ativos do dispositivo OTBR. Vamos voltar ao ot-ctl e receber o conjunto de dados ativo:

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

Volte para a 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 de encadeamento:

> 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 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 é amplamente usado para publicar serviços 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 com o roteador de borda e depende dele para anunciar os serviços na conexão Wi-Fi ou Ethernet.

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

Acesse a sessão de tela do nó cliente do SRP e inicie automaticamente o cliente do 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 na conexão 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 e confira se o serviço foi registrado:

> 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 deveria ter sido 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. O serviço _ipps._tcp vai aparecer.

Descobrir o serviço com um host Linux

Se quiser descobrir o serviço de outro host 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 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

Por exemplo, no smartphone Pixel, é possível 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 Service Browser.

bb992962e68d250b.png 888daa1df1e1a9bf.png

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

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

Ping de um host Linux/macOS

O roteador de borda do Thread envia anúncios de roteador (RA, na sigla em inglês) ICMPv6 para anunciar prefixos (pela opção de informações de prefixo) e rotas (pela opção de informações de rota) na conexão Wi-Fi/Ethernet.

Preparar o host Linux

É importante verificar se a RA e o RIO estão ativados 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 daemons de rede que substituem essa opção. Por exemplo, dhcpcd no Raspberry Pi substitui accept_ra por 0. Você pode verificar o valor de accept_ra com:

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

Defina o valor como 1 (ou 2 se o encaminhamento de IP estiver 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 é definida como 0 por padrão. Defina 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 o RIO permanentemente:

$ 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 RA, e o intervalo entre duas mensagens RA não solicitadas pode ser de várias centenas de segundos. Uma maneira é desconectar e reconectar ao ponto de acesso Wi-Fi para enviar mensagens de solicitação de roteador para que o OTBR responda com anúncios de roteador solicitados. Outra opção é reiniciar a função de roteamento de borda no roteador de borda:

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

Se você estiver tentando reconectar o Wi-Fi ou reiniciar a interface Ethernet, verifique se o dhcpcd não está sendo usado para gerenciar sua rede IPv6 Wi-Fi/Ethernet. Porque o dhcpcd sempre substitui a opção accept_ra toda vez que a interface é reiniciada, e sua configuração accept_ra será perdida. Adicione 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 macOS

As duas opções accept_ra* estão ativadas por padrão, mas é necessário fazer upgrade do sistema para pelo menos o macOS Big Sur.

Pingue o nome do host ou o endereço IPv6

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

Esse comando pode falhar em hosts Linux com o erro "Name or service not known". Isso acontece 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 diretamente no endereço 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
...

7. End Device Unpublish the Service

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

> srp client host remove
Done

Agora você não deve conseguir descobrir o serviço _ipps._tcp.

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