נתב Thread Border - קישוריות IPv6 דו-כיוונית וגילוי שירות מבוסס-DNS

1. מבוא

699d673d05a55535.png

מהו נתב Thread Border?

פרוטוקול Thread הוא פרוטוקול רשת אלחוטית מבוסס-IP בעל מתח נמוך, שמאפשר תקשורת מאובטחת ממכשיר למכשיר וממכשירים לענן. רשתות של פרוטוקול Thread יכולות להסתגל לשינויים בטופולוגיה כדי להימנע מנקודת כשל בודדת.

נתב Thread Border יחובר לרשת של פרוטוקול Thread לרשתות אחרות שמבוססות על כתובות IP, כמו Wi-Fi או אתרנט. לרשת בפרוטוקול Thread נדרש נתב גבול כדי להתחבר לרשתות אחרות. נתב Thread Border י נמצא תמיכה מינימלית בפונקציות הבאות:

  • קישוריות IP דו-כיוונית בין רשתות פרוטוקול Thread ו-Wi-Fi/אתרנט.
  • זיהוי שירות דו-כיווני דרך mDNS (בקישור Wi-Fi/אתרנט) ו-SRP (ברשת פרוטוקול Thread).
  • תשתית של פרוטוקול Thread שממזג מחיצות של פרוטוקולי Thread עם קישורים שמבוססים על כתובות IP.
  • ניהול פרוטוקול חיצוני של פרוטוקול Thread (לדוגמה, טלפון נייד) כדי לבצע אימות של מכשיר פרוטוקול Thread ולחבר אותו לרשת בפרוטוקול Thread.

OpenThread Border Router (OTBR) שהושק על ידי Google הוא הטמעת קוד פתוח של נתב Thread Border.

מה תפַתחו

ב-Codelab הזה בוחרים להגדיר נתב Thread Border Border על גבולות ולחבר את הטלפון הנייד למכשיר קצה של פרוטוקול Thread באמצעות נתב גבול.

מה תלמדו

  • איך מגדירים OTBR
  • איך ליצור רשת בפרוטוקול Thread עם OTBR
  • איך לפתח מכשיר OpenThread CLI עם תכונת ה-SRP
  • איך לרשום שירות באמצעות SRP
  • איך למצוא מכשיר קצה של פרוטוקול Thread ולהגיע אליו.

למה תזדקק?

  • מכשיר Raspberry Pi 3/4 וכרטיס SD עם יכולת של 8GB לפחות.
  • 2 לוחות פיתוח של מוליכים למחצה נורדיים nRF52840.
  • נקודת גישה ל-Wi-Fi ללא IPv6 Router Ad Guard בנתב.
  • טלפון 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-lite). כדי להשלים את השלבים לטלפון הנייד ב-Codelab הזה, צריך לחבר את Raspberry Pi ל-AP ל-Wi-Fi. במדריך הזה מוסבר איך להגדיר קישוריות אלחוטית. נוח להתחבר ל-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/אתרנט) שמצוין ב-INFRA_IF_NAME. כברירת מחדל, ממשק פרוטוקול ה-thread נוצר על ידי 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 ו-Flash

OTBR תומך בצ'יפ רדיו 15.4 במצב Radio Co-Processor (RCP) . במצב הזה, המקבץ של OpenThread פועל בצד המארח ומשדר או מקבל פריימים דרך המשדר IEEE802.15.4.

פועלים לפי שלב 4 של בניית רשת פרוטוקול Thread באמצעות לוחות nRF52840 ו-Codelab של OpenThread כדי לבנות מכשיר 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. יצירת רשת בפרוטוקול Thread

יש פקודת ot-ctl שבה אפשר להשתמש כדי לשלוט בשירות otbr-agent. ot-ctl מקבל את כל פקודות ה-OpenThread ב-CLI. פרטים נוספים זמינים במדריך ל-CLI של OpenThread.

יצירת רשת בפרוטוקול Thread עם 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 פועל כ-thread leader ושיש קידומת off-mesh-routable (OMR) בנתוני רשת ה-Thread:

$ 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

פועלים לפי שלב 5 של בניית רשת פרוטוקול Thread באמצעות לוחות nRF52840 ו-codelab של OpenThread כדי ליצור מכשיר קצה nRF52840 CLI ולעדכן אותו.

אבל במקום להפעיל את OT_COMMISSIONER ואת OT_JOINER, לצומת ה-CLI נדרשות התכונות OT_SRP_CLIENT ו-OT_ECDSA.

כך, ההפעלה המלאה של ה-build אמורה להיראות כך:

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

הצטרפות לרשת OTBR

כדי להצטרף לרשת בפרוטוקול Thread שנוצר על ידי השירות otbr-agent, אנחנו צריכים לקבל את מערך הנתונים התפעולי הפעיל ממכשיר ה-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 ב-link-local. עם זאת, הודעות של Multicast צורכות רוחב פס גדול מדי ויתפסו את הסוללה במכשירים עם צריכת אנרגיה נמוכה במהירות. פרוטוקול Thread משתמש בפרוטוקול SRP של Unicode כדי לרשום את השירותים שלו בנתב הגבולות, ומסתמך על נתב הגבולות כדי לפרסם את השירותים בקישור ל-Wi-Fi או לאתרנט.

אנחנו יכולים לרשום שירות באמצעות הפקודה srp client.

עוברים לסשן מסך של צומת לקוח SRP ומפעילים באופן אוטומטי את לקוח ה-SRP:

> srp client autostart enable
Done

צריך להגדיר את שם המארח שיפורסם בקישור ל-Wi-Fi/אתרנט:

> srp client host name ot-host
Done

כדי שמכשיר שמקושר ל-Wi-Fi או אתרנט יגיע למכשיר קצה בפרוטוקול Thread, יש לפרסם את כתובת ה-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/אתרנט. הגיע הזמן לגלות את מכשיר הקצה ולהגיע אליו עכשיו!

6. מידע על השירות

הכרת השירות באמצעות טלפון נייד

54a136a8940897cc.png

אנחנו משתמשים באפליקציית דפדפן השירות כדי לגלות שירותי mDNS עם טלפון Android. ניתן למצוא אפליקציה מקבילה גם לניידים של 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

כדי לפתור את השירות, אפשר להשתמש ב-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.png 888daa1df1e1a9bf.png

עכשיו אנחנו יכולים לבצע פינג לכתובת ה-OMR באמצעות אפליקציה אחרת של כלי לניתוח רשת.

לצערנו, הגרסה ל-Android של האפליקציה Network Analyzer App לא תומכת בשאילתות mDNS עבור כלי ה-ping, ואנחנו לא יכולים לבצע פינג ישירות לשם המארח ot-host.local (ניתן לבצע פינג לשם המארח עם גרסת ה-iOS של האפליקציה).

פינג ממארח של Linux או macOS

Thread Border Router שולח מודעות לנתבים של ICMPv6 (RA) כדי לפרסם קידומות (דרך אפשרות מידע קידומת) ומסלולים (דרך אפשרות מידע על נתיב) בקישור ל-Wi-Fi/אתרנט.

הכנת מארח Linux

חשוב לוודא שה-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 ברוב ההפצות של Linux היא 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 יגיב בתגובה לבקשת RAS. אפשרות אחרת היא להפעיל מחדש את הפונקציה 'ניתוב גבול' בנתב הגבולות:

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

אם מנסים לחבר מחדש את ה-Wi-Fi או להפעיל מחדש את ממשק האתרנט, צריך לוודא ש-dhcpcd משמש לניהול רשת ה-Wi-Fi/אתרנט IPv6. dhcpc תמיד מבטל את האפשרות accept_ra בכל הפעלה מחדש של הממשק, וההגדרות של accept_ra יאבדו. הוסף את השורות הבאות לקובץ התצורה dhcpcd (לדוגמה /etc/dhcpcd.conf) כדי להשבית באופן מפורש את IPv6 ב-dhcpcd:

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

הפקודה הזו עלולה להיכשל במארחים של Linux עם השגיאה "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 כנתב גבול של פרוטוקולי Thread כדי לספק קישוריות IP דו-כיוונית וגילוי שירות למכשירי קצה בפרוטוקול Thread.

מה השלב הבא?

כדאי לנסות כמה מ-Codelabs האלה...

מסמכי עזר