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

1. מבוא

699d673d05a55535.png

מהו נתב שרשורי?

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

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

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

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

מה אפשר ליצור

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

מה תלמדו

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

דרישות:

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

2. הגדרת OTBR

הגדרה של פטל פטל

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

לקבלת קוד OTBR

מתחברים ל-Raspberry 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 לא צוין במפורש. אם ה-Raspberry Pi מחובר באמצעות כבל 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 כדי לפעול.

יש להפעיל מחדש את Raspberry Pi כדי שהשינויים ייכנסו לתוקף.

בניית קושחת RCP והבזק שלהם

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

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

בנייה ופלאש של CLI

בצע שלב 5 של בניית רשת שרשורים עם לוחות nRF52840 ו-OpenThread codelab כדי לבנות ולהביע מכשיר קצה 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. אבל הודעות שידור לקבוצה צורכות יותר מדי רוחב פס והסוללה תרוקן את הסוללה מהר ככל האפשר. ב-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 יגיע למכשיר קצה של שרשור, יש לפרסם את כתובת ה-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 של השירות שרשום בעבר 'ot-service' בדף הפרטים של מופע השירות ב'אפליקציית דפדפן השירות'.

bb992962e68d250b.png 888daa1df1e1a9bf.png

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

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

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

נתב שרשור גבול שולח מודעות ICMPv6 Router (RA) כדי לפרסם קידומות (דרך אפשרות של פרטי תחילית) ונתיבים (דרך אפשרות מידע על נתיב) בקישור 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. עם זאת, יש משחקי דימון אחרים ברשת שיחליפו את האפשרות הזו (לדוגמה, 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 כדי לשלוח הודעות ניתוב של בקשת ה-OTR כדי ש-OTBR יגיב באמצעות תשדירי RA. אפשרות נוספת היא להפעיל מחדש את הפונקציה 'ניתוב גבול' בנתב הגבול:

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

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

מה השלב הבא?

הנה כמה ממעבדות הקוד...

מסמכי עזר