Router granic wątków – dwukierunkowe połączenia IPv6 i wykrywanie usług oparte na DNS

1. Wprowadzenie

699d673d05a55535.png

Czym jest Thread?

Thread to oparty na protokole IP bezprzewodowy protokół sieciowy o niskim poborze mocy, który umożliwia bezpieczną komunikację między urządzeniami i między urządzeniami a chmurą. Sieci Thread mogą dostosowywać się do zmian topologii, aby uniknąć awarii pojedynczego punktu.

Co to jest OpenThread?

OpenThread od Google to implementacja open source protokołu Thread®.

Czym jest router graniczny Thread?

Router graniczny Thread łączy sieć Thread z innymi sieciami opartymi na protokole IP, takimi jak Wi-Fi lub Ethernet. Sieć Thread wymaga routera granicznego, aby łączyć się z innymi sieciami. Router graniczny Thread obsługuje co najmniej te funkcje:

  • Dwukierunkowe połączenie IP między sieciami Thread i Wi-Fi/Ethernet.
  • Dwukierunkowe wykrywanie usług za pomocą mDNS (w przypadku połączenia Wi-Fi/Ethernet) i SRP (w przypadku sieci Thread).
  • Technologia Thread-over-infrastructure, która łączy partycje Thread za pomocą linków opartych na protokole IP.
  • zewnętrzne uruchamianie Thread (np. na telefonie komórkowym) w celu uwierzytelnienia urządzenia Thread i dołączenia go do sieci Thread;

OpenThread Border Router (OTBR) udostępniony przez Google to implementacja open source routera granicznego Thread.

Co utworzysz

W tym ćwiczeniu z programowania skonfigurujesz router brzegowy Thread i połączysz telefon komórkowy z urządzeniem końcowym Thread za pomocą routera brzegowego.

Czego się nauczysz

  • Jak skonfigurować OTBR
  • Jak utworzyć sieć Thread za pomocą OTBR
  • Tworzenie urządzenia z interfejsem wiersza poleceń OpenThread z funkcją SRP
  • Rejestrowanie usługi w SRP
  • Jak wykrywać i osiągać urządzenie końcowe Thread

Czego potrzebujesz

  • Stacja robocza z systemem Linux do tworzenia i flashowania RCP Thread, interfejsu wiersza poleceń OpenThread oraz testowania multiemisji IPv6.
  • Raspberry Pi do routera granicznego Thread.
  • 2 klucze USB Nordic Semiconductor nRF52840 (jeden dla RCP i jeden dla urządzenia końcowego Thread).
  • telefon z iOS 14 lub nowszym albo Androidem 8.1 lub nowszym;

2. Konfigurowanie OTBR

Najszybszym sposobem skonfigurowania OTBR jest skorzystanie z przewodnika po konfiguracji OTBR.

Po zakończeniu konfiguracji OTBR użyj ot-ctl, aby sprawdzić, czy OTBR działa jako router graniczny Thread leader.

$ sudo ot-ctl state
leader
Done

Sprawdź też, czy OTBR automatycznie skonfigurował prefiks off-mesh-routable (OMR) w danych sieci 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. Konfigurowanie urządzenia klienta SRP

Kompilowanie i flashowanie interfejsu wiersza poleceń OT

Wykonaj krok 5 z samouczka Tworzenie sieci Thread za pomocą płytek nRF52840 i OpenThread, aby utworzyć i flashować urządzenie końcowe CLI nRF52840.

Zamiast włączonych funkcji OT_COMMISSIONEROT_JOINER węzeł interfejsu wiersza poleceń wymaga funkcji OT_SRP_CLIENTOT_ECDSA.

Pełne wywołanie kompilacji powinno wyglądać tak:

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

Dołączanie do sieci Thread

Aby dołączyć do sieci Thread, musimy pobrać aktywny zestaw danych operacyjnych z urządzenia OTBR. Wróćmy do ot-ctl i pobierzmy aktywny zbiór danych:

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

Wróć do sesji ekranu węzła klienta SRP i ustaw aktywny zbiór danych:

> dataset set active 0e080000000000010000000300001235060004001fffe002083d3818dc1c8db63f0708fda85ce9df1e662005101d81689e4c0a32f3b4aa112994d29692030f4f70656e5468726561642d35326532010252e204103f23f6b8875d4b05541eeb4f9718d2f40c0302a0ff
Done

Następnie uruchom interfejs Thread:

> ifconfig up
Done
> thread start
Done

Odczekaj kilka sekund i sprawdź, czy udało się dołączyć do sieci Thread:

> 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

Sprawdź, czy dane sieci są zgodne z danymi wydrukowanymi na OTBR. Możemy teraz wysłać ping na adres OMR 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. Opublikuj usługę na urządzeniu końcowym

mDNS jest powszechnie używany do publikowania usługi DNS-SD w sieci lokalnej. Wiadomości multicast zużywają jednak zbyt dużo przepustowości i szybko wyczerpują baterię urządzeń o niskim poborze mocy. Thread używa protokołu SRP typu unicast do rejestrowania usług w routerze brzegowym i polega na tym routerze w zakresie reklamowania usług w połączeniu Wi-Fi lub Ethernet.

Usługę możemy zarejestrować za pomocą polecenia srp client.

Przejdź do sesji ekranu węzła klienta SRP i automatycznie uruchom klienta SRP:

> srp client autostart enable
Done

Ustaw nazwę hosta, która będzie reklamowana w połączeniu Wi-Fi/Ethernet:

> srp client host name ot-host
Done

Aby urządzenie połączone przez Wi-Fi lub Ethernet mogło dotrzeć do urządzenia końcowego Thread, musi być reklamowany adres OMR urządzenia końcowego:

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

Na koniec zarejestruj fałszywą usługę _ipps._tcp:

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

Poczekaj kilka sekund, aż usługa zostanie zarejestrowana:

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

Zakończyliśmy wszystkie prace konfiguracyjne i _ipps._tcp powinna być reklamowana w połączeniu Wi-Fi/Ethernet. Czas odkryć urządzenie końcowe i się z nim połączyć.

5. Poznaj usługę

Odkrywanie usługi na telefonie komórkowym

54a136a8940897cc.png

Do wykrywania usług mDNS na telefonie z Androidem używamy aplikacji Service Browser. Odpowiednik tej aplikacji jest też dostępny na urządzenia mobilne z iOS. Otwórz aplikację, a usługa _ipps._tcp powinna się pojawić.

Odkrywanie usługi za pomocą hosta z systemem Linux

Jeśli chcesz wykryć usługę z innego hosta z systemem Linux, możesz użyć polecenia avahi-browse.

Zainstaluj avahi-daemonavahi-utils:

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

Rozwiąż problem z usługą:

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

Odkrywanie usługi za pomocą hosta macOS

Aby rozwiązać problem z usługą, możesz użyć klawisza dns-sd w systemie macOS:

$ 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. Pingowanie urządzenia końcowego

Pingowanie z telefonu komórkowego

Na przykład w telefonie Pixel na stronie z informacjami o instancji usługi „ot-service” w aplikacji Przeglądarka usług możemy znaleźć adres OMR wcześniej zarejestrowanej usługi.

bb992962e68d250b.png 888daa1df1e1a9bf.png

Możemy teraz wysłać ping na adres OMR za pomocą innej aplikacji Analizator sieci.

Niestety wersja aplikacji Analizator sieci na Androida nie obsługuje zapytań mDNS w przypadku narzędzia ping i nie możemy bezpośrednio pingować nazwy hosta ot-host.local (możemy to zrobić w wersji aplikacji na iOS).

Pingowanie z hosta z systemem Linux/macOS

Router graniczny Thread wysyła komunikaty ICMPv6 Router Advertisements (RA), aby reklamować prefiksy (za pomocą opcji informacji o prefiksie) i trasy (za pomocą opcji informacji o trasie) w połączeniu Wi-Fi/Ethernet.

Przygotowywanie hosta z systemem Linux

Ważne jest, aby upewnić się, że na hoście włączone są RA i RIO:

  1. Wartość net.ipv6.conf.wlan0.accept_ra powinna wynosić co najmniej 1, jeśli przekazywanie IP nie jest włączone, a w przeciwnym razie – 2.
  2. Wartość w polu net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen nie powinna być mniejsza niż 64.

W przypadku większości dystrybucji domyślnie ustawiona jest wartość 1.accept_ra Mogą jednak istnieć inne demony sieci, które zastąpią tę opcję (np. dhcpcd na Raspberry Pi zastąpi accept_ra wartością 0). Wartość accept_ra możesz sprawdzić za pomocą tego polecenia:

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

Ustaw wartość na 1 (lub 2, jeśli przekierowywanie adresu IP jest włączone):

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

Większość dystrybucji Linuxa ma domyślnie ustawioną opcję accept_ra_rt_info_max_plen na 0. Aby ustawić ją na 64, wpisz:

$ 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

Zmiana zostanie utracona po ponownym uruchomieniu hosta. Aby na stałe włączyć RIO, dodaj na przykład te polecenia do pliku /etc/sysctl.conf:

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

Może być już za późno na zmianę tych konfiguracji, ponieważ OTBR wysyła już wiadomości RA, a interwał między dwoma niechcianymi wiadomościami RA może wynosić kilkaset sekund. Jednym ze sposobów jest odłączenie się od punktu dostępu Wi-Fi i ponowne połączenie z nim w celu wysłania wiadomości Router Solicitation, aby OTBR odpowiedział na nie żądanymi komunikatami RA. Możesz też ponownie uruchomić funkcję routingu granicznego na routerze brzegowym:

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

Jeśli próbujesz ponownie połączyć się z Wi-Fi lub ponownie uruchomić interfejs Ethernet, upewnij się, że do zarządzania siecią IPv6 Wi-Fi/Ethernet nie jest używane narzędzie dhcpcd. Dzieje się tak, ponieważ dhcpcd zawsze zastępuje opcję accept_ra przy każdym ponownym uruchomieniu interfejsu, a konfiguracja accept_ra zostanie utracona. Dodaj poniższe wiersze do pliku konfiguracji dhcpcd (np. /etc/dhcpcd.conf), aby jawnie wyłączyć IPv6 w dhcpcd:

noipv6
noipv6rs

Aby zastosować zmianę, musisz ponownie uruchomić urządzenie.

Przygotowywanie hosta macOS

Obie accept_ra* opcje są domyślnie włączone, ale musisz zaktualizować system do co najmniej macOS Big Sur.

Pingowanie nazwy hosta lub adresu IPv6

Możemy teraz wysłać ping do nazwy hosta ot-host.local za pomocą polecenia ping -6 (ping6 w systemie 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
...

To polecenie może się nie powieść na hostach z Linuksem i wyświetlić błąd "Name or service not known". Dzieje się tak, ponieważ polecenie ping nie rozpoznaje nazwy ot-host.local. za pomocą zapytań mDNS. Otwórz /etc/nsswitch.conf i dodaj mdns6_minimal do wiersza zaczynającego się od hosts:

hosts:          files mdns4_minimal mdns6_minimal dns

Oczywiście możesz bezpośrednio wysłać ping na adres 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. Cofanie publikacji usługi przez urządzenie końcowe

Aby usunąć adres i usługę zarejestrowane na węźle klienta SRP:

> srp client host remove
Done

Nie powinna być teraz widoczna usługa _ipps._tcp.

8. Gratulacje

Gratulacje. Udało Ci się skonfigurować OTBR jako router graniczny Thread, który zapewnia dwukierunkową łączność IP i odkrywanie usług dla urządzeń końcowych Thread.

Co dalej?

Sprawdź te ćwiczenia z programowania:

Dokumentacja