1. 소개
스레드 경계 라우터란 무엇인가요?
스레드는 안전한 기기 간 통신과 기기와 클라우드 간 통신을 가능하게 하는 IP 기반 저전력 무선 메시 네트워킹 프로토콜입니다. 스레드 네트워크는 단일 장애점을 방지하기 위해 토폴로지 변경사항에 적응할 수 있습니다.
스레드 경계 라우터는 Wi-Fi 또는 이더넷과 같은 다른 IP 기반 네트워크에 스레드 네트워크를 연결합니다. 스레드 네트워크를 사용하려면 다른 네트워크에 연결하려면 경계 라우터가 필요합니다. 스레드 경계 라우터는 최소한 다음 기능을 지원합니다.
- 스레드와 Wi-Fi/이더넷 네트워크 간의 양방향 IP 연결
- Wi-Fi/이더넷 링크의 mDNS 및 스레드 네트워크의 SRP를 통한 양방향 서비스 검색
- IP 기반 링크를 통해 스레드 파티션을 병합하는 스레드 오버 인프라
- 스레드 기기를 인증하고 스레드 네트워크에 조인하기 위한 외부 스레드 수수료 (예: 휴대전화).
Google에서 출시한 OpenThread Border Router (OTBR)는 스레드 경계 라우터의 오픈소스 구현입니다.
빌드할 항목
이 Codelab에서는 Thread Border Router를 설정하고 Border Router를 통해 휴대전화를 스레드 종료 기기에 연결합니다.
실습 내용
- OTBR 설정 방법
- OTBR을 사용하여 스레드 네트워크 형성 방법
- SRP 기능을 사용하여 OpenThread CLI 기기를 빌드하는 방법
- SRP에 서비스를 등록하는 방법
- 스레드 종료 기기를 찾고 연결하는 방법
준비물
- Raspberry Pi 3/4 기기 및 최소 8GB 이상의 SD 카드.
- 북유럽 반도체 nRF52840 개발 보드 2개
- 라우터에서 IPv6 Router Advertisement Guard가 사용 설정되지 않은 Wi-Fi AP.
- iOS 14 이상을 실행하는 iOS 휴대전화 또는 Android 8.1 이상을 실행하는 Android 휴대전화
2 OTBR 설정
Raspberry Pi 설정
raspberrypi.org의 안내에 따라 rpi-imager
도구를 사용하여 새 Raspberry Pi 기기를 설정하는 것이 간단합니다. 도구에서 최신 Raspberry Pi OS를 사용하는 대신 2021년 5월 7일-raspios-buster-armhf-lite 참조). 이 Codelab의 휴대전화 단계를 완료하려면 Raspberry Pi를 Wi-Fi AP에 연결해야 합니다. 이 가이드에 따라 무선 연결을 설정합니다. SSH로 Raspberry Pi에 로그인하는 것이 편리합니다. 여기에서 안내를 확인하세요.
OTBR 코드 받기
Raspberry Pi에 로그인하고 GitHub에서 ot-br-posix
를 클론합니다.
$ git clone https://github.com/openthread/ot-br-posix.git --depth 1
OTBR 빌드 및 설치
OTBR에는 스레드 경계 라우터를 부트스트랩하고 설정하는 두 가지 스크립트가 있습니다.
$ cd ot-br-posix $ ./script/bootstrap $ INFRA_IF_NAME=wlan0 ./script/setup
OTBR은 스레드 인터페이스와 INFRA_IF_NAME
으로 지정된 인프라 네트워크 인터페이스 (예: Wi-Fi/이더넷) 모두에서 작동합니다. 스레드 인터페이스는 OTBR 자체로 생성되며, 이름이 wpan0
이며 인프라 인터페이스의 기본값은 INFRA_IF_NAME
이 명시적으로 지정되지 않은 경우 wlan0
입니다. Raspberry Pi가 이더넷 케이블로 연결되어 있는 경우 이더넷 인터페이스 이름 (예: eth0
)을 지정합니다.
$ INFRA_IF_NAME=eth0 ./script/setup
OTBR이 제대로 설치되었는지 확인합니다.
$ 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)
실행하려면 otbr-agent
서비스가 활성화되어 있지 않아야 합니다. RCP
칩을 실행해야 하기 때문입니다.
Raspberry Pi를 재부팅하여 변경사항을 적용합니다.
RCP 펌웨어 빌드 및 플래시하기
OTBR은 라디오 공동 프로세서 (RCP) 모드에서 15.4 라디오 칩을 지원합니다. 이 모드에서는 OpenThread 스택이 호스트 측에서 실행되며 IEEE802.15.4 트랜시버를 통해 프레임을 전송/수신합니다.
nRF52840 보드 및 OpenThread가 포함된 스레드 네트워크 빌드 Codelab의 4단계를 따라 nRF52840 RCP 기기를 빌드하고 플래시합니다.
$ script/build nrf52840 USB_trans
OTBR 시작 및 상태 확인
nRF52840 보드를 Raspberry Pi에 연결하고 otbr-agent
서비스를 시작합니다.
$ sudo service otbr-agent restart
otbr-agent
서비스가 활성 상태인지 확인합니다.
$ 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. 스레드 네트워크 구성
otbr-agent
서비스를 제어하는 데 사용할 수 있는 ot-ctl
명령어가 있습니다. ot-ctl
은 모든 OpenThread CLI 명령어를 허용합니다. 자세한 내용은 OpenThread CLI 가이드를 참조하세요.
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
몇 초 동안 기다리면 OTBR이 스레드 leader
의 역할을 하고 있고 스레드 네트워크 데이터에 off-mesh-routable
(OMR) 접두사가 있음을 알 수 있습니다.
$ 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. SRP 클라이언트 최종 기기 설정
OT CLI 빌드 및 플래시
nRF52840 보드 및 OpenThread가 포함된 스레드 네트워크 빌드 Codelab의 5단계에 따라 nRF52840 CLI 최종 기기를 빌드하고 플래시합니다.
하지만 CLI 노드에 OT_COMMISSIONER
및 OT_JOINER
를 사용 설정하는 대신 OT_SRP_CLIENT
및 OT_ECDSA
기능이 필요합니다.
따라서 전체 빌드 호출은 다음과 같아야 합니다.
$ script/build nrf52840 USB_trans -DOT_SRP_CLIENT=ON -DOT_ECDSA=ON
OTBR 네트워크에 연결
otbr-agent
서비스로 만든 스레드 네트워크를 조인하려면 OTBR 기기에서 Active Operational Dataset를 가져와야 합니다. otbr-agent
명령줄로 돌아가 활성 데이터 세트를 가져옵니다.
$ 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
5 최종 기기에 서비스 게시
mDNS는 link-local에 DNS-SD 서비스를 게시하는 데 널리 사용되고 있습니다. 하지만 멀티캐스트 메시지는 너무 많은 대역폭을 소비하며 저전력 기기의 배터리가 빠르게 소모됩니다. 스레드는 유니캐스트 SRP 프로토콜을 사용하여 Border Router에 서비스를 등록하며, Border Router를 사용하여 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
설정 작업이 모두 완료되었습니다. Wi-Fi/이더넷 링크에서 _ipps._tcp
서비스를 광고해야 합니다. 이제 최종 기기를 찾아서 연결할 차례입니다.
6. 서비스 살펴보기
휴대전화로 서비스 찾기
Google에서는 서비스 브라우저 앱을 사용하여 Android 휴대전화로 mDNS 서비스를 검색합니다. iOS 휴대기기에서 해당 앱도 찾을 수 있습니다. 앱을 열면 _ipps._tcp
서비스가 표시됩니다.
Linux 호스트로 서비스 탐색
다른 Linux 호스트에서 서비스를 검색하려면 avahi-browse
명령어를 사용하면 됩니다.
avahi-daemon
와 avahi-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 "" ...
7 최종 기기 핑
휴대전화에서 핑하기
Pixel 스마트폰을 예로 들어 보겠습니다. 서비스 브라우저 앱의 서비스 인스턴스 세부정보 페이지에서 이전에 등록한 서비스인 'ot-service'의 OMR 주소를 확인할 수 있습니다.
이제 다른 네트워크 분석기 앱으로 OMR 주소를 핑할 수 있습니다.
Android 버전의 네트워크 분석 앱은 핑 유틸리티에 대한 mDNS 쿼리를 지원하지 않으므로 호스트 이름 ot-host.local
을 직접 핑할 수 없습니다 (호스트 버전의 앱을 사용하여 호스트 이름을 핑할 수 있음).
Linux/macOS 호스트에서 핑
스레드 경계 라우터는 ICMPv6 라우터 광고 (RA)를 전송하여 Wi-Fi/이더넷 링크의 프리픽스 (프리픽스 정보 옵션 사용) 및 경로 (경로 정보 옵션을 통해)를 알립니다.
Linux 호스트 준비
RA 및 RIO가 호스트에 사용 설정되어 있는지 확인하는 것이 중요합니다.
net.ipv6.conf.wlan0.accept_ra
는 IP 전달이 사용 설정되지 않은 경우1
, 그렇지 않은 경우2
이어야 합니다.net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen
는64
이상이어야 합니다.
대부분의 배포판에서 accept_ra
의 기본값은 1
입니다. 그러나 이 옵션을 재정의하는 다른 네트워크 데몬이 있을 수도 있습니다. 예를 들어, Raspberry Pi의 dhcpcd
이 accept_ra
을 0
으로 재정의합니다. 다음을 사용하여 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 메시지 사이의 간격이 수백 초일 수 있기 때문에 이러한 구성을 변경하는 것은 너무 늦을 수 있습니다. 한 가지 방법은 Wi-Fi AP의 연결을 해제하고 다시 연결하여 라우터 요청 메시지를 보내는 것입니다. 그래야 OTBR에서 요청받은 RA로 응답합니다. 또 다른 옵션은 경계 라우터에서 경계 라우팅 함수를 다시 시작하는 것입니다.
$ sudo ot-ctl br disable Done $ sudo ot-ctl br enable Done
Wi-Fi에 다시 연결하거나 이더넷 인터페이스를 다시 시작하려면 Wi-Fi/이더넷 IPv6 네트워크를 관리하는 데 dhcpcd가 사용되지 않는지 확인하세요. dhcpcd는 인터페이스가 다시 시작될 때마다 항상 accept_ra
옵션을 재정의하므로 accept_ra
구성이 손실됩니다. dhcpcd에서 IPv6를 명시적으로 사용 중지하려면 dhcpcd 구성 파일 (예: /etc/dhcpcd.conf
)에 다음 행을 추가하세요.
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
을 열고 mdns6_minimal
를 hosts
로 시작하는 행에 추가합니다.
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 ...
8 최종 기기 서비스 게시 취소
SRP 클라이언트 노드에서 등록된 주소 및 서비스를 삭제하려면 다음 안내를 따르세요.
> srp client host remove Done
지금은 _ipps._tcp
서비스를 찾을 수 없습니다.
9. 축하합니다
축하합니다. OTBR을 스레드 경계 라우터로 설정하여 양방향 IP 연결 및 스레드 종료 기기의 서비스 검색을 제공했습니다.
다음 단계
다음 Codelab을 확인하세요.