스레드 보더 라우터 - 양방향 IPv6 연결 및 DNS 기반 서비스 검색

1. 소개

699d673d05a55535.png

스레드란 무엇인가요?

스레드는 기기 간 및 기기-클라우드 간 보안 통신을 지원하는 IP 기반 저전력 무선 메시 네트워킹 프로토콜입니다. 스레드 네트워크는 토폴로지 변경에 적응하여 단일 장애점을 방지할 수 있습니다.

OpenThread란 무엇인가요?

Google에서 출시한 OpenThread는 Thread®의 오픈소스 구현입니다.

스레드 보더 라우터란 무엇인가요?

스레드 보더 라우터는 스레드 네트워크를 Wi-Fi 또는 이더넷과 같은 다른 IP 기반 네트워크에 연결합니다. 스레드 네트워크는 다른 네트워크에 연결하려면 보더 라우터가 필요합니다. 스레드 보더 라우터는 최소한 다음 기능을 지원해야 합니다.

  • 스레드와 Wi-Fi/이더넷 네트워크 간의 양방향 IP 연결
  • mDNS (Wi-Fi/이더넷 링크) 및 SRP (스레드 네트워크)를 통한 양방향 서비스 검색
  • IP 기반 링크를 통해 스레드 파티션을 병합하는 인프라를 통한 스레드
  • 스레드 기기를 스레드 네트워크에 인증하고 가입시키기 위한 외부 스레드 커미셔닝 (예: 휴대전화)

Google에서 출시한 OpenThread Border Router (OTBR)는 스레드 보더 라우터의 오픈소스 구현입니다.

빌드할 항목

이 Codelab에서는 스레드 보더 라우터를 설정하고 보더 라우터를 통해 휴대전화를 스레드 엔드 기기에 연결합니다.

학습할 내용

  • OTBR 설정 방법
  • OTBR로 스레드 네트워크를 형성하는 방법
  • SRP 기능으로 OpenThread CLI 기기를 빌드하는 방법
  • SRP에 서비스를 등록하는 방법
  • 스레드 최종 기기를 검색하고 연결하는 방법

필요한 항목

  • 스레드 RCP와 OpenThread CLI를 빌드하고 플래시하며 IPv6 멀티캐스트를 테스트하는 데 사용되는 Linux 워크스테이션
  • 스레드 보더 라우터용 Raspberry Pi
  • Nordic Semiconductor nRF52840 USB 동글 2개 (RCP용 1개, 스레드 엔드 기기용 1개)
  • iOS 14 이상을 실행하는 iOS 휴대전화 또는 Android 8.1 이상을 실행하는 Android 휴대전화

2. OTBR 설정

OTBR을 설정하는 가장 빠른 방법은 OTBR 설정 가이드를 따르는 것입니다.

OTBR 설정이 완료되면 ot-ctl를 사용하여 OTBR이 스레드 leader로 작동하는지 확인합니다.

$ sudo ot-ctl state
leader
Done

또한 OTBR이 스레드 네트워크 데이터에서 off-mesh-routable (OMR) 접두사를 자동으로 구성했는지 확인합니다.

$ 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. SRP 클라이언트 최종 기기 설정

OT CLI 빌드 및 플래시

nRF52840 보드 및 OpenThread로 스레드 네트워크 빌드 Codelab의 5단계에 따라 nRF52840 CLI 엔드 기기를 빌드하고 플래시합니다.

하지만 OT_COMMISSIONEROT_JOINER가 사용 설정된 대신 CLI 노드에는 OT_SRP_CLIENTOT_ECDSA 기능이 필요합니다.

따라서 전체 빌드 호출은 다음과 같습니다.

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

스레드 네트워크에 참여

스레드 네트워크에 참여하려면 OTBR 기기에서 활성 운영 데이터 세트를 가져와야 합니다. ot-ctl로 돌아가 활성 데이터 세트를 가져옵니다.

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

SRP 클라이언트 노드 화면 세션으로 돌아가 활성 데이터 세트를 설정합니다.

> dataset set active 0e080000000000010000000300001235060004001fffe002083d3818dc1c8db63f0708fda85ce9df1e662005101d81689e4c0a32f3b4aa112994d29692030f4f70656e5468726561642d35326532010252e204103f23f6b8875d4b05541eeb4f9718d2f40c0302a0ff
Done

그런 다음 스레드 인터페이스를 시작합니다.

> ifconfig up
Done
> thread start
Done

몇 초 정도 기다린 후 스레드 네트워크 가입이 성공했는지 확인합니다.

> 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

네트워크 데이터가 OTBR에 인쇄된 데이터와 일치하는지 확인합니다. 이제 OTBR의 OMR 주소를 핑할 수 있습니다.

> 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. 최종 기기에 서비스 게시

mDNS는 링크 로컬에서 DNS-SD 서비스를 게시하는 데 널리 사용되었습니다. 하지만 멀티캐스트 메시지는 대역폭을 너무 많이 소비하고 저전력 기기의 배터리를 빠르게 소모합니다. 스레드는 유니캐스트 SRP 프로토콜을 사용하여 보더 라우터에 서비스를 등록하고 보더 라우터가 Wi-Fi 또는 이더넷 링크에서 서비스를 공지하도록 합니다.

srp client 명령어를 사용하여 서비스를 등록할 수 있습니다.

SRP 클라이언트 노드 화면 세션으로 이동하여 SRP 클라이언트를 자동 시작합니다.

> srp client autostart enable
Done

Wi-Fi/이더넷 링크에 광고될 호스트 이름을 설정합니다.

> srp client host name ot-host
Done

Wi-Fi/이더넷 링크에 있는 기기가 스레드 최종 기기에 도달하려면 최종 기기의 OMR 주소가 공지되어야 합니다.

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

마지막으로 가짜 _ipps._tcp 서비스를 등록합니다.

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

몇 초 정도 기다리면 등록된 서비스를 확인할 수 있습니다.

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

모든 설정 작업을 완료했으며 _ipps._tcp 서비스가 Wi-Fi/이더넷 링크에 광고되어야 합니다. 이제 엔드 기기를 검색하고 연결할 시간입니다.

5. 서비스 검색

휴대전화로 서비스 검색

54a136a8940897cc.png

Android 휴대전화로 mDNS 서비스를 검색하기 위해 서비스 브라우저 앱을 사용합니다. iOS 모바일 기기에서도 동일한 앱을 찾을 수 있습니다. 앱을 열면 서비스 _ipps._tcp가 표시됩니다.

Linux 호스트로 서비스 검색

다른 Linux 호스트에서 서비스를 검색하려면 avahi-browse 명령어를 사용하면 됩니다.

avahi-daemonavahi-utils를 설치합니다.

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

서비스를 해결합니다.

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

macOS 호스트로 서비스 검색

macOS에서 dns-sd를 사용하여 서비스를 확인할 수 있습니다.

$ 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. 엔드 기기 핑

휴대전화에서 핑

Pixel 휴대전화를 예로 들면 서비스 브라우저 앱의 서비스 인스턴스 세부정보 페이지에서 이전에 등록된 'ot-service'의 OMR 주소를 확인할 수 있습니다.

bb992962e68d250b.png 888daa1df1e1a9bf.png

이제 다른 네트워크 분석기 앱으로 OMR 주소를 핑할 수 있습니다.

안타깝게도 네트워크 분석기 앱의 Android 버전은 ping 유틸리티의 mDNS 쿼리를 지원하지 않으며 호스트 이름 ot-host.local을 직접 ping할 수 없습니다 (앱의 iOS 버전으로 호스트 이름을 ping할 수 있음).

Linux/macOS 호스트에서 핑

스레드 보더 라우터는 ICMPv6 라우터 공지 (RA)를 전송하여 Wi-Fi/이더넷 링크에서 프리픽스 (프리픽스 정보 옵션을 통해)와 경로 (경로 정보 옵션을 통해)를 공지합니다.

Linux 호스트 준비

호스트에서 RA와 RIO가 사용 설정되어 있는지 확인하는 것이 중요합니다.

  1. IP 전달이 사용 설정되지 않은 경우 net.ipv6.conf.wlan0.accept_ra1 이상이어야 하고, 그렇지 않은 경우 2 이상이어야 합니다.
  2. net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen64보다 작지 않아야 합니다.

accept_ra는 대부분의 배포에서 1로 기본 설정됩니다. 하지만 이 옵션을 재정의하는 다른 네트워크 데몬이 있을 수 있습니다 (예: Raspberry Pi의 dhcpcdaccept_ra0로 재정의). 다음을 사용하여 accept_ra 값을 확인할 수 있습니다.

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

다음과 같이 값을 1 (IP 전달이 사용 설정된 경우 2)로 설정합니다.

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

대부분의 Linux 배포판에서 accept_ra_rt_info_max_plen 옵션은 기본적으로 0로 설정되어 있습니다. 다음을 사용하여 64로 설정하세요.

$ 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

호스트를 재부팅하면 변경사항이 손실됩니다. 예를 들어 다음 명령어를 /etc/sysctl.conf에 추가하여 RIO를 영구적으로 사용 설정합니다.

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

OTBR이 이미 RA 메시지를 전송하고 있고 요청되지 않은 두 RA 메시지 간 간격이 수백 초일 수 있으므로 이러한 구성을 변경하기에는 너무 늦을 수 있습니다. 한 가지 방법은 OTBR이 요청된 RA로 응답하도록 라우터 요청 메시지를 전송하기 위해 Wi-Fi AP를 연결 해제했다가 다시 연결하는 것입니다. 보더 라우터에서 보더 라우팅 기능을 다시 시작하는 방법도 있습니다.

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

Wi-Fi를 다시 연결하거나 이더넷 인터페이스를 다시 시작하려는 경우 dhcpcd가 Wi-Fi/이더넷 IPv6 네트워크 관리에 사용되지 않는지 확인하세요. 인터페이스가 다시 시작될 때마다 dhcpcd가 항상 accept_ra 옵션을 재정의하므로 accept_ra 구성이 손실됩니다. dhcpcd 구성 파일 (예: /etc/dhcpcd.conf)에 아래 줄을 추가하여 dhcpcd에서 IPv6를 명시적으로 사용 중지합니다.

noipv6
noipv6rs

변경사항을 적용하려면 재부팅해야 합니다.

macOS 호스트 준비

accept_ra* 옵션은 기본적으로 사용 설정되어 있지만 시스템을 macOS Big Sur 이상으로 업그레이드해야 합니다.

호스트 이름 또는 IPv6 주소 핑

이제 ping -6 명령어 (macOS의 경우 ping6)를 사용하여 호스트 이름 ot-host.local를 핑할 수 있습니다.

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

이 명령어는 Linux 호스트에서 "Name or service not known" 오류와 함께 실패할 수 있습니다. 이는 ping 명령어가 mDNS 쿼리로 ot-host.local. 이름을 확인하지 않기 때문입니다. /etc/nsswitch.conf을 열고 hosts로 시작하는 줄에 mdns6_minimal을 추가합니다.

hosts:          files mdns4_minimal mdns6_minimal dns

물론 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. 기기에서 서비스 게시 종료

SRP 클라이언트 노드에서 등록된 주소와 서비스를 삭제하려면 다음을 실행하세요.

> srp client host remove
Done

이제 _ipps._tcp 서비스를 검색할 수 없어야 합니다.

8. 축하합니다

축하합니다. OTBR을 스레드 보더 라우터로 설정하여 스레드 엔드 기기에 양방향 IP 연결 및 서비스 검색을 제공했습니다.

다음 단계

다음 Codelab을 확인하세요.

참조 문서