Thread Border Router - اتصال دوطرفه IPv6 و سرویس مبتنی بر DNS کشف

1. معرفی

699d673d05a55535.png

Thread Border Router چیست؟

Thread یک پروتکل شبکه بی سیم کم مصرف مبتنی بر IP است که ارتباطات دستگاه به دستگاه و دستگاه به ابر را ایمن می کند. شبکه های نخ می توانند با تغییرات توپولوژی سازگار شوند تا از یک نقطه شکست جلوگیری کنند.

Thread Border Router یک شبکه Thread را به سایر شبکه های مبتنی بر IP مانند Wi-Fi یا Ethernet متصل می کند. یک شبکه Thread برای اتصال به شبکه های دیگر به یک مسیریاب مرزی نیاز دارد. روتر Thread Border حداقل از توابع زیر پشتیبانی می کند:

  • اتصال IP دو طرفه بین شبکه های Thread و Wi-Fi/Ethernet.
  • کشف سرویس دو طرفه از طریق mDNS (در پیوند Wi-Fi/Ethernet) و SRP (در شبکه Thread).
  • Thread-over-Infrastructure که پارتیشن های Thread را روی پیوندهای مبتنی بر IP ادغام می کند.
  • راه اندازی Thread خارجی (به عنوان مثال، تلفن همراه) برای احراز هویت و پیوستن یک دستگاه Thread به شبکه Thread.

روتر مرزی OpenThread (OTBR) منتشر شده توسط گوگل یک پیاده سازی متن باز از Thread Border Router است.

چیزی که خواهی ساخت

در این کد لبه، شما قصد دارید یک Thread Border Router راه اندازی کنید و تلفن همراه خود را از طریق Border Router به یک Thread End Device متصل کنید.

چیزی که یاد خواهید گرفت

  • نحوه راه اندازی OTBR
  • نحوه تشکیل شبکه Thread با OTBR
  • چگونه یک دستگاه OpenThread CLI با ویژگی SRP بسازیم
  • نحوه ثبت سرویس با SRP
  • نحوه کشف و دسترسی به یک دستگاه پایان Thread.

آنچه شما نیاز دارید

  • یک دستگاه Raspberry Pi 3/4 و یک کارت SD با حداقل ظرفیت 8 گیگابایت.
  • 2 برد توسعه دهنده Nordic Semiconductor nRF52840 .
  • یک AP وای فای بدون محافظ تبلیغات روتر IPv6 روی روتر فعال شده است.
  • تلفن iOS با حداقل iOS 14 یا تلفن Android با حداقل Android 8.1.

2. راه اندازی OTBR

راه اندازی Raspberry Pi

راه اندازی یک دستگاه Raspberry Pi تازه با ابزار rpi-imager با پیروی از دستورالعمل های raspberrypi.org ساده است (به جای استفاده از آخرین سیستم عامل Raspberry Pi در ابزار، دانلود 2021-05-07-raspios-buster-armhf -خطوط توسط خودتان). برای تکمیل مراحل تلفن همراه در این کد لبه، باید Raspberry Pi را به یک AP وای فای متصل کنید. برای راه اندازی اتصال بی سیم این راهنما را دنبال کنید. ورود به Raspberry Pi با SSH راحت است، می توانید دستورالعمل ها را در اینجا بیابید.

کد OTBR را دریافت کنید

وارد Raspberry Pi خود شوید و ot-br-posix را از GitHub کلون کنید:

$ git clone https://github.com/openthread/ot-br-posix.git --depth 1

ساخت و نصب OTBR

OTBR دو اسکریپت دارد که Thread Border Router را بوت استرپ و راه اندازی می کند:

$ cd ot-br-posix
$ ./script/bootstrap
$ INFRA_IF_NAME=wlan0 ./script/setup

OTBR هم بر روی یک رابط Thread و هم بر روی رابط شبکه زیرساخت (مانند Wi-Fi/Ethernet) که با INFRA_IF_NAME مشخص شده است، کار می کند. رابط Thread توسط خود OTBR ایجاد شده است و به طور پیش فرض wpan0 نام دارد و اگر wlan0 به صراحت مشخص نشده باشد، واسط زیرساخت دارای مقدار پیش فرض INFRA_IF_NAME است. اگر 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 از تراشه رادیویی 15.4 در حالت رادیویی Co-Processor (RCP) پشتیبانی می کند. در این حالت، پشته OpenThread در سمت میزبان اجرا می شود و فریم ها را از طریق فرستنده گیرنده IEEE802.15.4 ارسال/دریافت می کند.

برای ساختن و فلش کردن یک دستگاه RCP nRF52840، مرحله 4 از ساخت شبکه Thread را با بردهای nRF52840 و کد OpenThread دنبال کنید:

$ 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. یک شبکه Thread تشکیل دهید

یک دستور ot-ctl وجود دارد که می تواند برای کنترل سرویس otbr-agent استفاده شود. ot-ctl همه دستورات OpenThread CLI را می پذیرد، برای جزئیات بیشتر به راهنمای OpenThread CLI مراجعه کنید.

با OTBR یک شبکه Thread تشکیل دهید:

$ 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 به عنوان یک Thread leader عمل می کند و یک پیشوند off-mesh-routable (OMR) در Thread Network Data وجود دارد:

$ 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 Client End Device را راه اندازی کنید

ساخت و فلش OT CLI

برای ساختن و فلش کردن یک دستگاه پایانی nRF52840 CLI، مرحله 5 از شبکه Build a Thread را با بردهای nRF52840 و Codelab OpenThread دنبال کنید.

اما به جای فعال بودن OT_COMMISSIONER و OT_JOINER ، گره CLI به ویژگی های OT_SRP_CLIENT و OT_ECDSA نیاز دارد.

بنابراین فراخوان کامل ساخت باید به شکل زیر باشد:

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

به شبکه OTBR بپیوندید

برای پیوستن به شبکه Thread ایجاد شده توسط سرویس otbr-agent ، باید Active Operational Dataset را از دستگاه OTBR دریافت کنیم. بیایید به خط فرمان otbr-agent و مجموعه داده فعال را دریافت کنیم:

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

به جلسه صفحه گره کلاینت SRP برگردید و مجموعه داده فعال را تنظیم کنید:

> dataset set active 0e080000000000010000000300001235060004001fffe002083d3818dc1c8db63f0708fda85ce9df1e662005101d81689e4c0a32f3b4aa112994d29692030f4f70656e5468726561642d35326532010252e204103f23f6b8875d4b05541eeb4f9718d2f40c0302a0ff
Done

سپس، رابط Thread را راه اندازی کنید:

> ifconfig up
Done
> thread start
Done

چند ثانیه صبر کنید و بررسی کنید که آیا پیوستن به شبکه 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

مطمئن شوید که داده های شبکه با داده های چاپ شده در OTBR مطابقت دارند. اکنون می توانیم آدرس 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

5. سرویس را در دستگاه پایانی منتشر کنید

mDNS به طور گسترده برای انتشار سرویس DNS-SD در لینک محلی استفاده شده است. اما پیام‌های چندپخشی پهنای باند زیادی مصرف می‌کنند و باتری دستگاه‌های کم مصرف را به سرعت تمام می‌کنند. Thread از پروتکل unicast SRP برای ثبت خدمات خود در Border Router استفاده می کند و برای تبلیغ خدمات در پیوند Wi-Fi یا Ethernet به Border Router متکی است.

ما می توانیم یک سرویس را با دستور srp client ثبت کنیم.

به جلسه صفحه نمایش گره کلاینت SRP بروید و کلاینت SRP را به طور خودکار راه اندازی کنید:

> srp client autostart enable
Done

نام میزبانی را که در پیوند Wi-Fi/Ethernet تبلیغ می‌شود، تنظیم کنید:

> srp client host name ot-host
Done

برای اینکه دستگاهی در پیوند Wi-Fi/Ethernet به دستگاه پایان رشته دسترسی پیدا کند، آدرس 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/Ethernet تبلیغ می‌شد. اکنون زمان کشف و رسیدن به دستگاه نهایی فرا رسیده است!

6. سرویس را کشف کنید

خدمات را با تلفن همراه کشف کنید

54a136a8940897cc.png

ما از برنامه مرورگر سرویس برای کشف سرویس‌های mDNS با تلفن Android استفاده می‌کنیم، یک برنامه معادل برای دستگاه‌های همراه iOS نیز می‌توان یافت. برنامه را باز کنید و سرویس _ipps._tcp باید ظاهر شود.

سرویس را با میزبان لینوکس کشف کنید

اگر می خواهید سرویس را از یک هاست لینوکس دیگر کشف کنید، می توانید از دستور 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 کشف کنید

برای حل این سرویس می توانید از dns-sd در 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     ""
...

7. دستگاه پایان را پینگ کنید

پینگ از تلفن همراه

تلفن Pixel را به عنوان مثال در نظر بگیرید، ما می‌توانیم آدرس OMR سرویس ثبت‌شده قبلی «ot-service» را در صفحه جزئیات نمونه سرویس در برنامه مرورگر سرویس پیدا کنیم.

bb992962e68d250b.png888daa1df1e1a9bf.png

اکنون می توانیم آدرس OMR را با یک برنامه تحلیلگر شبکه دیگر پینگ کنیم.

متأسفانه، نسخه Android برنامه Network Analyzer از درخواست‌های mDNS برای ابزار پینگ پشتیبانی نمی‌کند و نمی‌توانیم نام میزبان ot-host.local مستقیماً پینگ کنیم (می‌توانیم نام میزبان را با نسخه iOS برنامه پینگ کنیم).

پینگ از یک میزبان Linux/macOS

Thread Border Router تبلیغات روتر ICMPv6 (RA) را برای تبلیغ پیشوندها (از طریق گزینه اطلاعات پیشوند) و مسیرها (از طریق گزینه اطلاعات مسیر) در پیوند Wi-Fi/Ethernet ارسال می کند.

هاست لینوکس را آماده کنید

مهم است که مطمئن شوید RA و RIO در هاست شما فعال هستند:

  1. net.ipv6.conf.wlan0.accept_ra باید حداقل 1 باشد اگر ارسال IP فعال نیست و 2 در غیر این صورت.
  2. net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen نباید کوچکتر از 64 باشد.

برای اکثر توزیع‌ها، accept_ra پیش‌فرض 1 است. اما ممکن است دیمون های شبکه دیگری وجود داشته باشند که این گزینه را لغو کنند (به عنوان مثال، dhcpcd در Raspberry Pi، accept_ra را به 0 تغییر می دهد). می توانید مقدار accept_ra را با استفاده از:

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

و مقدار را روی 1 (یا 2 در صورت فعال بودن ارسال IP) قرار دهید:

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

گزینه 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

این تغییر پس از راه اندازی مجدد میزبان از بین می رود. برای مثال، برای فعال کردن دائمی RIO، دستورات زیر را به /etc/sysctl.conf کنید:

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

ممکن است برای تغییر این تنظیمات خیلی دیر باشد زیرا OTBR قبلاً پیام‌های RA ارسال کرده است و فاصله بین دو پیام RA ناخواسته می‌تواند چند صد ثانیه باشد. یکی از راه‌ها قطع و اتصال مجدد به Wi-Fi AP برای ارسال پیام‌های Router Solicitation است تا OTBR با RAهای درخواست شده پاسخ دهد. گزینه دیگر راه اندازی مجدد تابع Border Routing در Border Router است:

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

اگر می‌خواهید دوباره Wi-Fi را وصل کنید یا رابط اترنت را مجددا راه‌اندازی کنید، مطمئن شوید که dhcpcd برای مدیریت شبکه WiFi/Ethernet IPv6 شما استفاده نمی‌شود. زیرا dhcpcd همیشه هر بار که رابط راه اندازی مجدد می شود، گزینه accept_ra را لغو می کند و پیکربندی accept_ra شما از بین می رود. برای غیرفعال کردن صریح IPv6 در dhcpcd، خطوط زیر را به فایل پیکربندی dhcpcd (به عنوان مثال /etc/dhcpcd.conf ) اضافه کنید:

noipv6
noipv6rs

برای اعمال تغییرات باید ریبوت کنید.

میزبان macOS را آماده کنید

هر دو گزینه accept_ra* به طور پیش فرض فعال هستند، اما باید سیستم خود را حداقل به macOS Big Sur ارتقا دهید.

نام میزبان یا آدرس IPv6 را پینگ کنید

اکنون می‌توانیم نام میزبان ot-host.local را با دستور ping -6 کنیم ( ping6 برای 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
...

این دستور ممکن است در هاست های لینوکس با خطای "Name or service not known" ناموفق باشد. دلیلش این است که دستور ping مشکل ot-host.local. نام با پرس و جوهای mDNS. /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 دوطرفه و کشف سرویس برای دستگاه‌های پایانی Thread راه‌اندازی کردید.

بعدش چی؟

برخی از این کدها را بررسی کنید...

اسناد مرجع