1. 소개
스레드 보더 라우터란 무엇인가요?
스레드는 기기 간 및 기기 간 안전한 통신을 가능하게 하는 IP 기반의 저전력 무선 메시 네트워킹 프로토콜입니다. 스레드 네트워크는 토폴로지 변화에 적응하여 단일 장애점을 방지할 수 있습니다.
스레드 보더 라우터는 스레드 네트워크를 Wi-Fi 또는 이더넷과 같은 다른 IP 기반 네트워크에 연결합니다. 스레드 네트워크를 사용하려면 보더 라우터가 다른 네트워크에 연결해야 합니다. 스레드 보더 라우터는 최소한 다음 기능을 지원합니다.
- 스레드 및 Wi-Fi/이더넷 네트워크 간의 양방향 IP 연결.
- mDNS (Wi-Fi/이더넷 링크) 및 SRP (스레드 네트워크)를 통한 양방향 서비스 검색
- IP 기반 링크를 통해 스레드 파티션을 병합하는 스레드 오버 인프라입니다.
- 스레드 기기를 인증하고 스레드 네트워크에 조인하기 위한 외부 스레드 커미셔닝 (예: 휴대전화)
Google에서 출시한 OTBR (OpenThread Border Router)은 스레드 보더 라우터를 오픈소스로 구현한 결과물입니다.
빌드할 항목
이 Codelab에서는 스레드 보더 라우터를 설정하고 보더 라우터를 통해 휴대전화를 스레드 종료 기기에 연결합니다.
학습할 내용
- OTBR 설정 방법
- OTBR로 스레드 네트워크를 형성하는 방법
- SRP 기능으로 OpenThread CLI 기기를 빌드하는 방법
- SRP에 서비스를 등록하는 방법
- 스레드 최종 기기를 검색하고 연결하는 방법
필요한 항목
- Raspberry Pi 3/4 기기 및 최소 8GB 용량이 있는 SD 카드
- Nordic Semiconductor nRF52840 개발 보드 2개.
- 라우터에 IPv6 라우터 공지 보호가 사용 설정되지 않은 Wi-Fi AP
- iOS 14 이상이 설치된 iOS 휴대전화 또는 Android 8.1 이상이 설치된 Android 휴대전화
2. OTBR 설정
Raspberry Pi 설정
raspberrypi.org의 안내에 따라 rpi-imager
도구로 새 Raspberry Pi 기기를 간단하게 설정할 수 있습니다 (도구에서 최신 Raspberry Pi OS를 사용하는 대신 2021-05-07-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 기기에서 활성 운영 데이터 세트를 가져와야 합니다. 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는 링크-로컬에 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
모든 설정 작업을 완료했으며 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 버전의 네트워크 분석기 앱은 ping 유틸리티에 대한 mDNS 쿼리를 지원하지 않으므로 호스트 이름 ot-host.local
을 직접 핑할 수 없습니다. iOS 버전의 앱에서 호스트 이름을 핑할 수 있습니다.
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 메시지 두 개 사이의 간격이 수백 초가 될 수 있으므로 구성을 변경하는 것은 너무 늦을 수 있습니다. 한 가지 방법은 OTBR이 요구된 RA로 응답하도록 Wi-Fi AP의 연결을 끊었다가 다시 연결하여 라우터 요청 메시지를 전송하는 것입니다. 또 다른 옵션은 경계 라우터에서 경계선 라우팅 기능을 다시 시작하는 것입니다.
$ sudo ot-ctl br disable Done $ sudo ot-ctl br enable Done
Wi-Fi에 다시 연결하거나 이더넷 인터페이스를 다시 시작하려는 경우 Wi-Fi/이더넷 IPv6 네트워크 관리에 dhcpcd가 사용되지 않는지 확인하세요. 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 ...
8. 최종 기기에서 서비스 게시 취소하기
SRP 클라이언트 노드에서 등록된 주소와 서비스를 삭제하려면 다음 단계를 따르세요.
> srp client host remove Done
지금은 _ipps._tcp
서비스를 검색할 수 없습니다.
9. 축하합니다
수고하셨습니다. 스레드 최종 기기에 양방향 IP 연결과 서비스 검색을 제공하기 위해 OTBR을 스레드 보더 라우터로 설정하셨습니다.
다음 단계
다음 Codelab을 확인하세요.