Reticulum зблизька: мережевий стек, де адреса — це ключ
Reticulum — не месенджер, не VPN і не «мережа для темних справ». Це повний мережевий стек, у якому адреса — відбиток ключа, шифрування не має вимикача, а носієм може бути LoRa-рація, шматок дроту чи звичайний TCP. Ця нотатка розбирає його пошарово: від бітів у заголовку пакета до плати на столі. Фізика радіо під ним — у розборі LoRa.
Яку задачу він розв'язує
Щоб зрозуміти Reticulum, спершу варто побачити, на яких припущеннях стоїть звичайний інтернет. Він не універсальний — він оптимізований під конкретний світ. Reticulum побудований під протилежний.
Назва — з латини: reticulum, «сіточка». Автор, Mark Qvist, почав із простого питання: що має бути в мережі, якщо забрати з неї провайдерів, реєстратори адрес, центри сертифікації й припущення, що канал завжди широкий? Виявилося, що переписати доведеться майже все — від адресації до формату пакета. Сам протокол автор передав у суспільне надбання ще 2016 року; еталонна реалізація на Python поширюється під власною Reticulum License.
| звичайний інтернет припускає | Reticulum припускає | що з цього випливає |
|---|---|---|
| Канал швидкий і дешевий: мегабіти, затримка в мілісекундах | Канал може бути 250 біт/с і з затримкою в секунди | Пакет — 500 байт. Кожен зайвий байт заголовка коштує реального часу в ефірі |
| Адреси роздає ієрархія: IANA → регіональний реєстратор → провайдер → DHCP | Адресу обчислюють самі з власного ключа | Ні реєстрації, ні оренди, ні можливості адресу відібрати |
| Імена дає DNS, довіру — центри сертифікації | Ні DNS, ні CA. Адреса і є посвідченням | Адресами обмінюються поза мережею: QR-код, папірець, оголошення в ефірі |
| Вузли онлайн постійно, з'єднання — норма | Вузол може вмикатися раз на добу | Потрібне зберігання з подальшою пересилкою, а не лише живі сесії |
| Носій — Ethernet або Wi-Fi, кадри великі | Носій — будь-що, що вміє передати байт: радіо, дріт, труба, TCP | Стек свідомо нічого не знає про фізику під собою |
Reticulum не заміна інтернету в побуті й не змагається з ним у швидкості. Він змагається з ситуацією, коли мережі немає взагалі — або вона є, але чужа, повільна й контрольована. Це різні змагання.
Три ідеї, на яких тримається все
Далі буде багато деталей, але всі вони виростають рівно з трьох рішень.
ідея перша
Адреса — це відбиток ключа
Не «мені видали адресу», а «я порахував хеш свого публічного ключа, і це моя адреса». Звідси одразу: підробити адресу — те саме, що підробити ключ, а відібрати її не може ніхто, бо ніхто її й не давав.
ідея друга
Шифрування — не опція
У стеку немає режиму «без шифрування» для звичайного призначення. Не треба ні вмикати TLS, ні купувати сертифікат, ні домовлятися про ключі: хто знає адресу, той уже знає публічний ключ, бо адреса з нього й зроблена.
ідея третя
Стеку байдуже, по чому їхати
Від носія потрібно одне: «візьми цей блок байтів і спробуй донести». Радіо, серійний кабель, TCP-з'єднання, звукова карта — однаково. Тому одна мережа може їхати частково по LoRa, частково по інтернету.
Оскільки адреса вже містить ключ, а шифрування вбудоване, Reticulum не потребує рукостискання, щоб просто щось надіслати. Пакет можна зашифрувати незнайомцю й кинути в ефір, нічого не питаючи й не чекаючи відповіді. Цей режим далі називатиметься «опортуністичним».
Особистість і адреса: звідки береться <a4f1…>
Найважливіші п'ять хвилин усього тексту: якщо стане зрозуміло, як із ключа виходить адреса, решта буде лише наслідками.
Особистість — це дві пари ключів
Під час першого запуску будь-якого застосунку на Reticulum створюється Identity — не логін і не акаунт, а просто два згенеровані набори ключів:
X25519
Для обміну ключами
Дозволяє двом сторонам порахувати спільний секрет, жодного разу не передаючи його в ефір. Із нього виходить ключ, яким шифрується вміст.
Ed25519
Для підписів
Дозволяє довести, що пакет справді від цього відправника. Підпис — 64 байти; без приватного ключа його не підробити.
Публічні частини обох ключів разом — рівно 64 байти. Це все, що мережі треба знати про учасника.
Далі — два хешування
Чотири типи призначень
| тип | що означає |
|---|---|
| SINGLE | Адресоване одній особистості, шифрується під її публічний ключ — прочитає тільки вона. Цей тип використовують майже всюди |
| GROUP | Спільний симетричний ключ, роздатий учасникам заздалегідь. Хто має ключ, читає все |
| PLAIN | Без шифрування взагалі. Для службових речей, де нічого ховати, — маяк, публічний ретранслятор |
| LINK | Адреса живої сесії — про неї в розділі про Link нижче. Існує, лише поки сесія жива |
Цифри, які варто пам'ятати
- ключі — 32 + 32 = 64 байти публічної частини
- хеш — SHA-256, зрізаний до 128 біт = 16 байт
- ім'я — хеш імені застосунку, 10 байт
- підпис — 64 байти (Ed25519)
- адреса — 16 байт = 32 шістнадцяткові символи
Про колізії. 128 біт — це приблизно 3,4 × 10³⁸ можливих адрес. Випадково вони не збігаються, а підібрати навмисно — окрема серйозна робота.
Анатомія пакета: усі 500 байт
У пакеті видно всю філософію. Коли канал дає 250 біт/с, кожен байт заголовка — це реальні мілісекунди в ефірі й реальні міліампери з акумулятора. Тому заголовок аскетичний до непристойності: два байти службових полів — і одразу адреса.
Що всередині першого байта
Вісім біт, у яких лежить усе, що стек має знати про пакет, ще не почавши його розбирати:
Чотири типи пакетів — і це весь протокол
| тип | код | навіщо |
|---|---|---|
| DATA | 0x00 | Власне дані. Усе, що не службове, — DATA |
| ANNOUNCE | 0x01 | «Я існую, ось мій ключ». Єдиний спосіб потрапити в чужі таблиці шляхів |
| LINKREQUEST | 0x02 | Запит на сесію з ефемерними ключами |
| PROOF | 0x03 | Криптографічний доказ: «я це отримав». Підтвердження доставки, яке не підробити |
У TCP/IP заголовок IPv4 — 20 байт, TCP — ще 20, і це до будь-якого TLS. Тут службового — 19 байт на все разом, включно з адресою й криптографічним контекстом. На каналі 250 біт/с різниця між 19 і 60 байтами — це різниця між «дійшло» і «не встигло».
Як вузол знаходять: announce
Адресу порахували — але мережа про неї нічого не знає. Немає DNS, немає реєстру, немає сервера, де «зареєструватися». Є рівно один механізм: вузол кричить у ефір announce, а всі, хто почув, запам'ятовують, у який бік до нього йти.
В announce лежать: адреса призначення, 64 байти публічних ключів, хеш імені застосунку, випадковий хеш (щоб два однакові announce не виглядали однаково), підпис — і опційно невеликий шматок даних застосунку, наприклад ім'я, яке месенджер покаже в списку.
| вузол | кого навчився знаходити | передавати через | хопів | коли дізнався |
|---|---|---|---|---|
| B | a4f1c8e0…88d29d2c | джерело (напряму) | 1 | +1,9 с |
| C | a4f1c8e0…88d29d2c | B | 2 | +3,5 с |
| D | a4f1c8e0…88d29d2c | B | 2 | +3,5 с |
| E | a4f1c8e0…88d29d2c | C | 3 | +5,1 с |
| F | a4f1c8e0…88d29d2c | E | 4 | +6,7 с |
| G | a4f1c8e0…88d29d2c | E | 4 | +6,7 с |
А якщо шляху ще немає?
Тоді в мережу йде запит шляху (path request) з потрібною адресою, і вузли, що її знають, відповідають. Це протилежний бік announce: announce — «я тут», path request — «а де ось цей?». Тому месенджер іноді думає кілька секунд перед першим повідомленням новому контакту — він шукає дорогу.
Шляхи не вічні
Запис має строк придатності. Якщо про вузол давно не чути, шлях забувається, і наступного разу дорогу доведеться шукати заново. Тому вузли, які хочуть бути знайденими, час від часу повторюють announce, а ті, хто не хоче зайвої уваги, мовчать і ходять мережею самі.
Announce публічний за задумом, інакше вузол неможливо знайти. Тобто будь-хто в радіусі чутності бачить, що така адреса існує, і бачить її публічний ключ. Зміст повідомлень лишається закритим, але сам факт «цей вузол у мережі» — ні. Reticulum ніколи й не обіцяв анонімності.
Transport: хто насправді ретранслює
Деталь, яку майже всі пропускають: не кожен вузол ретранслює чужий трафік. За замовчуванням вузол обслуговує лише себе.
Щоб вузол став транзитним, у конфігурації треба явно ввімкнути enable_transport = Yes. Такий вузол бере на себе роботу поштаря: тримає таблиці шляхів, переписує пакети з інтерфейсу на інтерфейс, склеює радіосегмент з інтернет-сегментом. Саме транзитні вузли перетворюють набір окремих островів на мережу.
звичайний вузол
Тільки для себе
Приймає й шле власні пакети. Чужі бачить, але не переносить. Це телефон у кишені.
транзитний вузол
Поштар мережі
Пересилає чуже, тримає шляхи, з'єднує різні носії. Зазвичай це щось, що працює цілодобово: Raspberry Pi, VPS, коробка на горищі з антеною.
вузол доставки
Ще й тримає пошту
Транзитний вузол, який додатково погодився зберігати повідомлення для тих, кого зараз немає в мережі. Про нього — у розділі про LXMF.
Режими інтерфейсів — інструмент, про який мало хто знає
Кожному інтерфейсу можна задати режим, і це змінює, як через нього поширюються announce і будуються шляхи. Так вузьке радіо не заливається службовим трафіком із широкого інтернет-каналу.
| режим | поведінка | типовий випадок |
|---|---|---|
| full | Усе за замовчуванням: announce ходять в обидва боки, шляхи будуються вільно | Домашня мережа, звичайний лінк |
| access point | Інтерфейс для «клієнтів», які самі нічого не ретранслюють | Точка входу для телефонів поруч |
| point-to-point | Виділений лінк рівно між двома вузлами | Радіоміст між двома пагорбами |
| roaming | Лінк, який то з'являється, то зникає; стек це враховує | Вузол у машині, телефон у русі |
| boundary | Межа між сегментами: сюди пускають не все | Стик повільного радіо й швидкого інтернету |
Інтерфейсу можна задати код доступу (Interface Access Code) — спільний секрет. Тоді вузли без коду не просто не приєднаються: вони взагалі не розпізнають цей трафік як Reticulum. Так на одній частоті співіснують кілька незалежних мереж, які не бачать одна одну.
Link: сесія з ключами, які потім зникнуть
Досі йшлося про поодинокі пакети: зашифрував під чужий публічний ключ, кинув у ефір, забув. Це працює, але має слабке місце: якщо хтось записує весь ефір і колись дістане приватний ключ адресата, він розшифрує все записане заднім числом. Саме проти цього придуманий Link.
навіщо ще лінк
Підтвердження доставки
PROOF — не «галочка в месенджері», а криптографічний доказ: підписати його міг лише той, хто справді отримав пакет. Підробити «доставлено» неможливо.
навіщо ще лінк
Можна назватися
За замовчуванням у лінку відправник анонімний навіть для співрозмовника. За бажанням можна явно представитися — підписати сесію своєю постійною особистістю. Це окрема дія, а не побічний ефект.
навіщо ще лінк
Великі передачі
Ресурси (наступний розділ) їдуть саме поверх лінка: там є куди вписати прогрес, повтори й запити відсутніх частин.
Для короткого повідомлення піднімати сесію — марна витрата ефіру. Тоді працює опортуністичний режим: один пакет, зашифрований під постійний ключ адресата, кинутий у мережу без рукостискання. Дешево, але без підтвердження й без forward secrecy. Для цього випадку в Reticulum додали ратчети — ключі, що регулярно «прокручуються», щоб і поодинокі пакети не читалися заднім числом.
Ресурси: коли даних більше, ніж 500 байт
Фото, файл, сторінка з картинками в один пакет не влазять. Для цього є окремий механізм — Resource. Він не просто ріже дані на шматки: він переживає втрати, не починаючи все спочатку.
Інтерфейси: по чому воно насправді їде
Стек нічого не знає про фізику. Він знає лише «інтерфейс» — штуку, яка вміє взяти блок байтів і спробувати його донести; решта — подробиці драйвера. Тому один вузол може одночасно тримати радіо, кабель і TCP, і для мережі це буде одна суцільна тканина.
AutoInterface
Локалка, нуль налаштувань
Шукає інших через IPv6-мультикаст у тій самій мережі. Увімкнути на двох ноутбуках в одному Wi-Fi — і вони вже бачать одне одного. Найшвидший спосіб спробувати Reticulum узагалі без заліза.
Швидкість: як у локальної мережі
TCPClient / TCPServer
Через звичайний інтернет
З'єднує два сегменти мережі поверх TCP. Так влаштовані публічні вузли testnet: локальний радіоострів під'єднується до світової мережі одним рядком у конфігу.
Швидкість: скільки дасть канал
RNodeInterface
LoRa-радіо через USB
Той самий випадок, заради якого все затівалося: жодного провайдера, жодного дроту. Плата підключається як звичайний серійний пристрій, а стек сам виставляє частоту, смугу й spreading factor.
Швидкість: 0,25–5,5 кбіт/с
KISS / AX.25
Стара добра радіоаматорщина
Reticulum уміє їхати поверх звичайного TNC і аматорської рації — зокрема на КХ, де сигнал огинає планету. Повільно до непристойності, зате дальність міряють континентами.
Швидкість: 300–9600 бод
SerialInterface / Pipe
Байти будь-яким дротом
Два пристрої, з'єднані кабелем. Або пара дротових модемів. Або взагалі чужа програма, яка вміє передавати потік байтів, — Reticulum поїде і по ній.
Швидкість: яку задали
I2PInterface
Коли треба ще й сховатися
Reticulum їде всередині I2P. Вузол не має ні білого IP, ні домену, ні порту, який можна заблокувати, — а адресація лишається власною.
Швидкість: повільно, зате непомітно
Залізо: RNode і фізика радіо
Тут закінчується софт і починається те, чого не обійти жодним кодом: антена, рельєф і закони поширення радіохвиль.
Що таке RNode
RNode — відкрита конструкція радіомодема: мікроконтролер плюс LoRa-чип, прошиті спеціальною прошивкою. Збирається з дешевих плат для розробників (T-Beam, Heltec, RAK тощо). Для стека це просто серійний пристрій, для власника — автономний вузол, що працює від акумулятора й нічого ні в кого не питає.
Чому LoRa чує те, чого «не чутно»
LoRa передає дані не рівним тоном, а свистком із наростаючою частотою — чирпом. Приймач точно знає форму цього свистка, тому витягує його навіть тоді, коли сигнал слабший за шум ефіру. Платня — час: чим «розтягнутіший» свисток (вищий spreading factor), тим далі чутно й тим повільніше йдуть дані. Детально — в розборі LoRa.
| spreading factor | швидкість, смуга 125 кГц | дальність | 500-байтовий пакет в ефірі |
|---|---|---|---|
| SF7 | ≈ 5,5 кбіт/с | найменша | менш як секунда |
| SF9 | ≈ 1,8 кбіт/с | середня | ≈ 2 секунди |
| SF12 | ≈ 250 біт/с | максимальна | ≈ 16 секунд |
Числа орієнтовні: швидкість залежить ще й від смуги й коду корекції помилок, а час в ефірі — від службових даних. Але порядок саме такий: перехід від SF7 до SF12 коштує приблизно двадцятикратного уповільнення.
Скільки реально пролазить
Найчастіше розчарування виглядає так: піднята LoRa-мережа, надіслане фото — і воно летить годину. Ось чесні числа, щоб такого не було. Повзунок розміру показує будь-який свій випадок.
| що надсилаємо | SF12 · 250 біт/с | SF7 · 5,5 кбіт/с | висновок |
|---|---|---|---|
| Текстове повідомлення, 1 КіБ | ≈ 33 с | ≈ 1,5 с | Комфортно навіть на найповільнішому режимі |
| Сторінка Nomad Network, 8 КіБ | ≈ 4,4 хв | ≈ 12 с | Читабельно, якщо сторінка текстова |
| Голосове, 1 хв стисненого, 15 КіБ | ≈ 8 хв | ≈ 22 с | На SF7 — терпимо, на SF12 — ні |
| Фото, 200 КіБ | ≈ 1 год 49 хв | ≈ 5 хв | Тільки коли справді треба й нема куди поспішати |
| Відео | — | — | Ні. І не буде: це не питання оптимізації |
Висновок не «LoRa погана», а «LoRa — для тексту». Далекобійний режим існує не щоб возити мегабайти, а щоб повідомлення дійшло за 30 кілометрів через гору, де нічого іншого не працює.
LXMF: пошта, яка вміє чекати адресата
Reticulum сам по собі не знає поняття «повідомлення» — він возить пакети. Месенджери поверх нього говорять окремим форматом, LXMF. Саме він відповідає за те, щоб повідомлення дочекалося людини, яка вмикає рацію раз на добу.
Що всередині повідомлення LXMF
- кому — адреса призначення (16 байт)
- від кого — адреса відправника
- підпис — щоб підмінити відправника було неможливо
- вміст — час, заголовок, текст і довільні поля; сюди ж лягають вкладення
Стани повідомлення в клієнті — не прикраса: «надіслано» означає «пішло в мережу», а «доставлено» ставиться лише тоді, коли повернувся PROOF.
Як тут борються зі спамом
Класичні фільтри неможливі: вузол не бачить вмісту. Тому LXMF використовує «марки»: відправник має витратити трохи обчислень, щоб його повідомлення прийняли. Для живої людини це непомітно, для розсилки на мільйон адрес — руйнівно дорого.
Плюс звичайне: від знайомих контактів марку можна не вимагати, від незнайомих — вимагати дорожчу.
Чого Reticulum не робить
Найшвидший спосіб розчаруватися в інструменті — чекати від нього того, чого він не обіцяв.
- ✕ Не анонімізує. Announce публічний, адреси призначення видно транзитним вузлам, а на спільному радіо видно, хто й коли виходив в ефір. Зміст закритий, факт спілкування — ні.
- ✕ Не має глобальних імен. Нічого схожого на DNS немає. Адресу співрозмовника треба звідкись узяти: QR-код, папірець, оголошення в ефірі, спільний вузол-довідник.
- ✕ Не гарантує доставку сам по собі. Гарантія з'являється лише там, де є PROOF або ресурс із повторами. Пакет, кинутий «опортуністично», може просто зникнути.
- ✕ Не возить звичайний веб. HTTP і браузер сюди не приїдуть: MTU 500 байт — інший світ. Замість вебу є Nomad Network із власною легкою розміткою сторінок.
- ✕ Не замінює інтернет у побуті. Стрімінг, дзвінки, хмари — ні. Текст, координати, невеликі файли, керування пристроями — так.
І це не Meshtastic — найчастіша плутанина, бо залізо в них однакове.
Reticulum і Meshtastic: та сама плата, різні задуми
| питання | Meshtastic | Reticulum |
|---|---|---|
| Що це | Готовий продукт: груповий чат і GPS по LoRa | Мережевий стек загального призначення, на якому пишуть свої застосунки |
| Носій | Тільки LoRa | Будь-що: LoRa, радіо, дріт, TCP, I2P |
| Маршрутизація | Керований флуд у межах невеликої групи вузлів | Таблиці шляхів, до 128 хопів, склеювання різних носіїв |
| Адреса | 4 байти з MAC-адреси плати | 16 байт хешу від ключа, глобально унікальна |
| Шифрування | Ключ каналу для груп; власні ключі вузлів — для приватних | Наскрізне до конкретної особистості, завжди |
| Кому підійде | «Увімкнув і працює» для групи в горах | Тим, хто будує власну мережу або застосунок під неї |
Обидва проєкти живі й обидва працюють на тих самих дешевих платах: Meshtastic дає готовий сценарій, Reticulum — конструктор. На одній платі можна спробувати і те, і те, просто змінивши прошивку.
Практика: підняти за вечір
Найдешевший спосіб зрозуміти — запустити. Для першого кроку залізо не потрібне взагалі: досить двох комп'ютерів в одному Wi-Fi.
Крок 1 — поставити стек
# сам стек і утиліти
pip install rns
# демон: тримає інтерфейси й шляхи
rnsd
# що з інтерфейсами просто зараз
rnstatus
# який шлях до адреси і скільки хопів
rnpath <hash>
# пінг транзитного вузла
# (у нього має бути ввімкнено respond_to_probes)
rnprobe rnstransport.probe <hash>
# забрати файл із віддаленого вузла
rncp --fetch ~/file.txt <hash>
Крок 2 — конфіг
Лежить у ~/.reticulum/config. Ось вузол, який одночасно в локальній мережі, на радіо й у світовій мережі:
[reticulum]
enable_transport = No
share_instance = Yes
[interfaces]
[[Default Interface]]
type = AutoInterface
interface_enabled = True
[[LoRa]]
type = RNodeInterface
interface_enabled = True
port = /dev/ttyUSB0
frequency = 867200000
bandwidth = 125000
txpower = 7
spreadingfactor = 8
codingrate = 5
[[Public hub]]
type = TCPClientInterface
interface_enabled = True
target_host = amsterdam.connect.reticulum.network
target_port = 4965
Частоту й потужність задають за правилами свого регіону — це не порада, а закон. Актуальні публічні точки входу — в документації проєкту: вони змінюються.
Крок 3 — прошити плату, коли дійде до радіо. Плата підключається по USB, далі — за підказками утиліти:
rnodeconf --autoinstall
Що поставити зверху
месенджер
Sideband
Android, iOS, десктоп. Найпростіший вхід: після встановлення генерується особистість і видно контакти, які оголосилися в мережі.
веб-інтерфейс
MeshChat
Зручна панель у браузері: повідомлення, файли, карта вузлів, стан інтерфейсів.
термінал
Nomad Network
Текстовий інтерфейс у дусі BBS: сторінки з власною розміткою, файли, дошки. Найкраще відчуття «іншої мережі».
Словник
- Identity — пара ключових пар (X25519 + Ed25519), особистість. Файл, який варто берегти: відновити його нізвідки.
- Destination — адреса: 16 байт хешу від особистості та імені застосунку. Те, що дають співрозмовнику.
- Aspect — частина імені застосунку, напр.
lxmf.delivery. Визначає, кому всередині вузла віддати пакет. - Announce — пакет «я існую, ось мій ключ». Єдиний спосіб потрапити в чужі таблиці шляхів.
- Path — запис у таблиці: «щоб дійти до цієї адреси, передай ось цьому сусідові». Має строк придатності.
- Transport node — вузол, якому явно дозволили ретранслювати чужий трафік. Без них мережа розпадається на острови.
- Link — сесія з одноразовими ключами. Дає forward secrecy, підтвердження доставки й ресурси.
- Proof — підписаний доказ отримання. Підробити «доставлено» неможливо.
- Resource — механізм передачі даних, більших за пакет: стиснення, нарізка, хешмапа, точкові повтори.
- Interface — драйвер носія: AutoInterface, TCP, RNode, KISS, Serial, I2P. По суті стек їх не розрізняє.
- IFAC — код доступу до інтерфейсу. Чужі вузли навіть не впізнають цей трафік як Reticulum.
- MTU / MDU — стеля розміру пакета (500 байт) і те, що лишається під корисні дані після заголовка.
- LXMF — формат повідомлень поверх Reticulum. Те, чим насправді говорять месенджери.
- Propagation node — вузол, що тримає зашифровану пошту, поки адресат офлайн. Ключів не має.
- RNode — відкрита конструкція LoRa-модема: дешева плата плюс прошивка. Для стека — звичайний серійний пристрій.
- Spreading factor — наскільки «розтягнутий» радіосигнал. Вище — далі чутно й повільніше дані.
Швидкості тут розрахункові; конкретні параметри конфігурації варто звіряти з документацією проєкту.
- LoRa зблизька — фізичний рівень: чирп, spreading factor, час в ефірі, дальність
- Meshtastic зблизька — готовий чат на «сирій» LoRa: керований флуд, канали, ролі вузлів
- Чотири інтернети — Reticulum, I2P, Yggdrasil і Nostr поруч: хто на якому поверсі
