נתב גבולות לגבולות – קישוריות IPv6 דו-כיוונית וזיהוי שירות מבוסס-DNS

1. מבוא

699d673d05a55535.png

מהו נתב גבולות לשרשורים?

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

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

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

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

מה תפַתחו

במעבדה הזו אתם מתכננים להגדיר נתב גבולות של Thread ולחבר את הטלפון הנייד אל מכשיר עם Thread End דרך נתב הגבולות.

מה תלמדו

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

מה הדרישות כדי להצטרף לתוכנית?

  • מכשיר Rasperi Pi 3/4 וכרטיס SD עם נפח של 8 GB לפחות.
  • 2 לוחות פיתוח נומריים למחצה nRF52840.
  • AP של Wi-Fi ללא אפוטרופוס לפרסום נתב IPv6 מופעל בנתב.
  • טלפון iOS עם מערכת הפעלה iOS 14 לפחות או Android עם גרסת Android 8.1 לפחות.

2. הגדרת OTBR

הגדרת פטל פאי

פשוט מגדירים מכשיר Raspery Pi חדש באמצעות הכלי rpi-imager. לשם כך, פועלים לפי ההוראות בכתובת raspneypi.org (במקום להשתמש במערכת ההפעלה העדכנית ביותר של Raspney Pi- , אבל מורידים את 2021-05-07-raspios-buster-armhf-lite בעצמכם). כדי להשלים את השלבים בטלפון הנייד ב-Codelab הזה, צריך לחבר את ה-Raspery Pi ל-Wi-Fi AP. יש לפעול לפי המדריך הזה כדי להגדיר קישוריות אלחוטית. קל להתחבר ל-Raspery Pi באמצעות SSH. אפשר למצוא הוראות כאן.

לקבלת קוד OTBR

מתחברים ל-Raspery Pi ומשכפלים את ot-br-posix מ-GitHub:

$ 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 פועל גם בממשק Thread וגם בממשק של רשת תשתית (למשל Wi-Fi/Ethernet) שמצוין ב-INFRA_IF_NAME. ממשק השרשור נוצר על ידי OTBR עצמו, בשם wpan0 כברירת מחדל, וממשק התשתית מקבל ערך ברירת מחדל של wlan0 אם לא צוין אחרת INFRA_IF_NAME. אם פטל פיי מחובר בכבל Ethernet, צריך לציין את השם של ממשק ה-Ethernet (למשל 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.

מפעילים מחדש את ה-Rasperi Pi כדי לבצע את השינויים.

יצירת קושחה ל-RCP

OTBR תומך בצ'יפ רדיו 15.4 במצב תחנת רדיו משותפת (RCP). במצב הזה, סטאק OpenThread פועל בצד המארח ומעביר/מקבל מסגרות באמצעות משדר ה-IEEE802.15.4.

יש לפעול לפי שלב 4 של יצירת רשת של Thread עם לוחות nRF52840 וקוד פתוח של Thread כדי לבנות ולהבליט מכשיר nRF52840 RCP:

$ script/build nrf52840 USB_trans

הפעלת OTBR ואימות הסטטוס

מחברים את לוח ה-nRF52840 ל-Raspney 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 מקבל את כל פקודות CLI של Openthread, לפרטים נוספים אפשר לעיין במדריך OpenThread CLI.

יצירת רשת 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 פועל כשרשור 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

יצירת Flash ב-OT

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

כדי להצטרף לרשת השרשורים שנוצרה על ידי השירות 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

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

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

נכנסים לסשן של צומת לקוח SRP ומפעילים את לקוח SRP באופן אוטומטי:

> srp client autostart enable
Done

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

> srp client host name ot-host
Done

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

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

bb992962e68d250b.png 888daa1df1e1a9bf.png

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

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

פינג ממארח Linux/macOS

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

הכנת מארח של 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 לרוב ההפצות. עם זאת, ייתכן שיש daemons נוספים של רשתות שיחליפו את האפשרות הזו (לדוגמה, dhcpcd ב-Raspery 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 יגיב עם RA שידולו. אפשרות נוספת היא להפעיל מחדש את הפונקציה 'ניתוב גבול' בנתב הגבולות:

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

אם מנסים להתחבר מחדש ל-Wi-Fi או להפעיל מחדש את ממשק ה-Ethernet, צריך לוודא ש-dhcpcd לא משמשת לניהול רשת ה-Wi-Fi/Ethernet 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 Border, כדי לספק קישוריות IP דו-כיוונית וזיהוי שירות למכשירי קצה של Thread.

מה השלב הבא?

בדקו כמה מ-Codelabs אלה...

מסמכי עזר