Skip to content

יישומי Reticulum: יעדים, קישורים ומגבלות פעולה ללא תשתית

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

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

Reticulum הוא מחסנית רשת למספר תווכים מוגדרים, ובהם ממשקי רדיו ו־IP מתאימים. היעדים שלו אינם דורשים הקצאה מרכזית של כתובות IP; עדיין יש חשיבות לחומרה, לתוכנה, לכללי הרדיו ולהגדרת הממשקים.

כמפתחים, עלינו להתחיל לחשוב על גישות ״לא־מקוון תחילה״ ו״מקומי תחילה״ לא רק כאסטרטגיות סנכרון של ממשק המשתמש, אלא כפרדיגמות רשת יסודיות. במאמר נעמיק ב־Reticulum, באופן פעולת הקריפטוגרפיה שלו ובדרך להתחיל לכתוב קוד לרשת mesh מבוזרת זו כבר היום.

מהו Reticulum, ולמה הוא לא רק עוד VPN?

Reticulum מספק מודל יעד והעברה משלו, ולא רק VPN מעל IP. הוא יכול לפעול מעל IP או ממשקים מתאימים שאינם IP; הוא אינו הופך בשקיפות יישומי TCP/IP קיימים ליישומים ללא תשתית.

כדי להבין את Reticulum, צריך לבחון את מגבלות התכנון המרכזיות שלו:

  • פחות ניהול כתובות: יישומים משתמשים ביעדים במקום בתתי־רשתות IP מוקצים. הממשקים והתנהגות ההעברה עדיין דורשים הגדרה.
  • ללא רשויות מרכזיות: אין שורשי DNS, שרתי תיאום או רשויות ספרייה.
  • ההצפנה תלויה בסוג היעד: יעדי SINGLE וקישורי Link מצפינים מטענים; יעדי PLAIN מאפשרים שידורים מקומיים בלתי מוצפנים. הצפנה אינה הבטחת אנונימיות.
  • מגוון תווכים: יש תמיכה בקישורים צרי־פס, אך השהיה, מגבלות מטען, הפרעות וקיבולת משפיעות על תכנון היישום. הם אינם מתנהגים כמו Ethernet מהיר.

יישומים פונים אל יעדים. הגיבובים כוללים את שם היישום וההיבטים שלו, וביעדים מבוססי זהות גם מידע על הזהות; יעד אינו פשוט המפתח הציבורי של הזהות.

היסודות הקריפטוגרפיים: זהות ומיעון יעדים

ברשת מסורתית, אם אני רוצה לשלוח מנה אל sysseder.com, עליי לסמוך על שרשרת שרתי DNS שתמיר את השם לכתובת IP, ואז על נתבי BGP שישלחו את המנות לשרת הפיזי הנכון. בדרך כל נתב יכול לבדוק את היעד שלי, ואם איני משתמש ב־HTTPS — גם את המטען.

Reticulum הופך את המודל הזה באמצעות מושגים מקריפטוגרפיה של מפתח ציבורי. כך פועל המיעון:

  1. זהות Reticulum מכילה זוגות מפתחות נפרדים: X25519 להצפנה ולהחלפת מפתחות ו־Ed25519 לחתימה. חומר המפתח הפרטי המשולב כולל מפתח בן 256 סיביות לכל תפקיד.
  2. כתובות יעד הן גיבובים מקוצרים בני 16 בתים, כלומר 128 סיביות, המוצגים בדרך כלל ב־32 תווים הקסדצימליים; הטענה על 80 סיביות אינה מתארת כתובות אלה.
  3. התיעוד שנבדק מתאר X25519,‏ Ed25519,‏ HKDF ו־AES-256-CBC עם HMAC-SHA256. למנה מוצפנת בודדת ולקישור Link פעיל תהליכים שונים; אין להחליפם במימוש קריפטוגרפי ביתי.

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

הבנת מחסנית Reticulum

כדי לכתוב יישומי Reticulum, כדאי לדמיין כיצד הוא משתווה למודל OSI המסורתי. Reticulum מרכז כמה שכבות במסגרת מאוחדת:

שכבת היישום
(LXMF,‏ Nomad Network, יישומים מותאמים)
↓
ממשק API / ספריית Reticulum
(משאבים, ערוצים, מנות, בקשות קישור)
↓
ליבת Reticulum
(ניתוב, קריפטוגרפיה, ניהול ממשקים)
↓
ממשק פיזי
(Ethernet,‏ WiFi,‏ LoRa, חיבור טורי, AX.25)

במקום לנהל sockets גולמיים, מפתחים המשתמשים ב־SDK של Reticulum עובדים עם שלוש הפשטות עיקריות:

  • מנות בודדות: מתאימות במיוחד לטלמטריה קטנה בשיטת ״שלח ושכח״, לנתוני חיישנים או לפינגים.
  • קישורים: שיחות דו־כיווניות מוצפנות עם ממשקי API נוספים. מנות גולמיות בקישור אינן זרם בתים של TCP; בחרו Channel, בקשה או Resource בהתאם להתנהגות המסירה הדרושה.
  • משאבים: העברות גדולות עם חלוקה למקטעים וטיפול בשלמות. השלמה עדיין תלויה בקישוריות ובמשאבים זמינים; העברות עלולות להיכשל.

מעבירים למעשה: בניית שירות Reticulum ב־Python

מימוש הייחוס כתוב ב־Python. דוגמאות ההד שלהלן נבדקו סטטית מול ה־API המתועד ולא הורצו. כל ניסוי עתידי צריך להיות מוגבל למעבדה מורשית ללא מידע רגיש.

ראשית, צריך להתקין את SDK של Reticulum:

pip install rns

קובץ ברירת מחדל עשוי להיווצר ב־~/.reticulum/config. AutoInterface משתמש בגילוי multicast מקומי בקישור IPv6 ובתעבורת UDP; חומות אש או בידוד לקוחות Wi-Fi עלולים למנוע גילוי. בדקו אילו ממשקים נבחרו לפני אתחול RNS.

שלב 1: יצירת מקבל — השירות

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

import RNS
import time
APP_NAME = "echo_service"

def packet_received(data, packet):
    # Educational lab: bounded, nonsensitive payloads only.
    if len(data) > 128:
        return
    RNS.Packet(packet.link, b"Echo: " + data).send()

def link_established(link):
    link.set_packet_callback(packet_received)

def main():
    rns = RNS.Reticulum()
    identity = RNS.Identity()  # Temporary: address changes on restart.
    destination = RNS.Destination(identity, RNS.Destination.IN,
        RNS.Destination.SINGLE, APP_NAME, "echo")
    destination.set_link_established_callback(link_established)
    destination.announce()
    print(destination.hash.hex())
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        pass

if __name__ == "__main__":
    main()

שלב 2: יצירת הלקוח

כעת נכתוב לקוח שיתחבר לשירות ההד באמצעות גיבוב היעד שלו. שמרו בשם client.py. יש להעתיק את כתובת היעד שהשרת מדפיס ולהדביק אותה בסקריפט, או להעביר אותה כארגומנט.

import sys
import time
import threading
import RNS
APP_NAME = "echo_service"
done = threading.Event()

def received(data, packet):
    if data == b"Echo: Hello, lab!":
        print("Expected echo received")
    packet.link.teardown()
    done.set()

def established(link):
    RNS.Packet(link, b"Hello, lab!").send()

def main():
    if len(sys.argv) != 2:
        raise SystemExit("Usage: python client.py DESTINATION_HEX")
    try:
        target = bytes.fromhex(sys.argv[1])
    except ValueError:
        raise SystemExit("Invalid hexadecimal address")
    if len(target) != 16:
        raise SystemExit("Address must contain 16 bytes")
    rns = RNS.Reticulum()
    deadline = time.monotonic() + 30
    if not RNS.Transport.has_path(target):
        RNS.Transport.request_path(target)
    while not RNS.Transport.has_path(target):
        if time.monotonic() >= deadline:
            raise SystemExit("No path before lab timeout")
        time.sleep(0.1)
    identity = RNS.Identity.recall(target)
    if identity is None:
        raise SystemExit("No verified identity for target")
    destination = RNS.Destination(identity, RNS.Destination.OUT,
        RNS.Destination.SINGLE, APP_NAME, "echo")
    if destination.hash != target:
        raise SystemExit("Destination name or identity mismatch")
    link = RNS.Link(destination)
    link.set_packet_callback(received)
    link.set_link_closed_callback(lambda link: done.set())
    link.set_link_established_callback(established)
    if not done.wait(30):
        print("No completed echo before lab timeout")
        link.teardown()

if __name__ == "__main__":
    main()

הרצת ההדגמה

פתחו שני חלונות מסוף במחשב:

  1. במסוף 1, python server.py מדפיס יעד בן 32 תווים הקסדצימליים. השתמשו רק בכתובת האמיתית של שרת המעבדה המורשה שלכם.
  2. במסוף 2 השתמשו ב־python client.py DESTINATION_HEX, עם הכתובת המלאה בת 32 התווים במקום הסמן.

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

ארכיטקטורה: צומתי העברה מוגדרים וגילוי נתיבים

צומת B שבו הוגדר transport יכול לתווך בין A ל־C אם קיימים הממשקים, ההכרזות ומצב הנתיב הנדרשים. הדבר אינו יוצר כיסוי רדיו או נתיב חלופי במקום שבו אינם קיימים.

RNS.Transport.request_path(target_hash) מבקש גילוי נתיב. הכרזות מספקות מידע על היעד המשמש ללימוד נתיבים; הגילוי והמטמון מנוהלים לפי הפרוטוקול, ואין הבטחה שכל שאילתה תיענה.

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

היכן מפתחים יכולים להשתמש ב־Reticulum כיום?

אולי Reticulum נראה כמו מקרה קצה למתכוננים למצבי חירום או לחובבי רדיו, אבל ההשלכות ההנדסיות שלו נרחבות:

  • טלמטריה מרחוק: חומרת רדיו מתאימה יכולה לתמוך בהודעות חיישנים מוגבלות במקום שקיים קישור רדיו מתוכנן. כיסוי, חשמל, כללי מחזור עבודה והתאוששות דורשים תכנון ובדיקה נפרדים; אין מכאן הבטחה לתיקון עצמי.
  • תקשורת מקומית מוכנה מראש: רשת מוגדרת, מחוברת לחשמל ובדוקה עשויה לתמוך בכלים מקומיים בעת תקלה. היא אינה תחליף לשירותי חירום ואינה נוצרת מעצמה.
  • תכנון מודע לפרטיות: מיעון מקור מצומצם הוא מאפיין אחד של הפרוטוקול, לא הבטחת פרטיות של מטא־נתונים. העריכו סיכוני תצפית ורישום בנקודות הקצה; אין להסתמך על המדריך לבטיחות אישית או לאנונימיות.

סיכום וקריאה לפעולה

Reticulum מציע מודל העברה נוסף ליישומים שתוכננו סביבו. עמידות, אבטחה ושליטת משתמשים תלויות במכלול הפריסה, התחזוקה ומודל האיום, ולא בעצם אימוץ הפרוטוקול.

בפעם הבאה שאתם מתכננים יישום נייד, צד שרת ל־IoT או פלטפורמה בגישת ״מקומי תחילה״, שאלו: ״איך זה יעבוד אם האינטרנט ייפול?״

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

האם התנסיתם ברשתות mesh או בתקשורת ללא תשתית? מה דעתכם על מעבר ממחסנית IP ליישומים מקומיים? בואו נדבר בתגובות!

מקורות ראשוניים

Post a Comment

Previous Post Next Post