# ramshare_ui Легковесная, автономная утилита для безопасного обмена текстом и файлами внутри локальных сетей (Wi-Fi, точки доступа со смартфонов, офисные LAN, домашние роутеры, VPN/Tailscale `100.64.0.0/10`). Приложение спроектировано для работы в условиях нестабильного окружения и роуминга устройств (ноутбуки, телефоны, сменяющие IP-адреса при переходе между сетями). Работает как в виде локального веб-интерфейса, так и через полноценный CLI без графической оболочки. --- ## Ключевые особенности * **Криптографическая безопасность из коробки:** * Соединения работают строго по **TLS 1.3** с обязательной взаимной аутентификацией (**mTLS**) через самоподписанные сертификаты. * Пиннинг сертификатов: соединение устанавливается только с известным и явно подтверждённым отпечатком (SHA-256). * **SAS-коды сверки (Short Authentication String):** 80-битный симметричный верификационный код вида `XXXX-XXXX-XXXX`, вычисляемый из отпечатков обоих узлов, предотвращает атаки типа Man-in-the-Middle (MitM). * Двусторонняя верификация: передача данных блокируется до тех пор, пока **оба** участника не подтвердят код на своих экранах. * **Приватность и потоковая передача:** * **Текст принимается исключительно в ОЗУ** (до 64 КБ на сообщение, кольцевой буфер на 50 записей). При закрытии процесса или нажатии кнопки очистки текст бесследно исчезает. * **Потоковая передача файлов с backpressure:** чтение и запись производятся чанками с константным потреблением памяти ($O(1)$ RAM), поддерживаются файлы объёмом до 2 ГБ. * Файлы записываются во временные `.part_*` файлы с атомарным переименованием и очисткой битых передач по таймауту. * **Адаптивность к смене сетей и роумингу:** * Автоматическое отслеживание изменений сетевых интерфейсов и актуального IP-адреса без перезапуска. * Приоритезация IP-адресов: узлы сначала опрашивают адреса из своей текущей `/24` подсети. * Поддержка частных диапазонов RFC 1918 (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`), Link-Local (`169.254.0.0/16`) и CGNAT / Carrier VPN (`100.64.0.0/10`). * **Энергоэффективный опрос (Smart Ping):** * Если устройство перестаёт отвечать, система делает до **5 попыток** опроса, после чего переводит пир в `offline` и **полностью прекращает фоновый опрос**, экономя заряд батареи и сетевой трафик. * Опрос возобновляется автоматически при ручном пинге, общем сканировании подсети или если пир сам пришлёт UDP-маяк/данные. * **Автономное обнаружение:** * Быстрое обнаружение через UDP-рассылку (порт `5354`) без зависимости от тяжелых сервисов mDNS / Avahi / Bonjour. * Встроенный многопоточный сканер диапазонов IPv4 (CIDR, списки, диапазоны тире). * **Интерфейс без внешних зависимостей:** * Web UI встроен непосредственно в бинарный файл (zero-external-assets, никаких внешних CDN и шрифтов). * Работает прямо на `[http://127.0.0.1:8080/](http://127.0.0.1:8080/)` без необходимости ввода одноразовых токенов. * Защита от межсайтовых атак: валидация заголовков `Host` и `Origin` (защита от DNS-rebinding и CSRF), строгие CSP-заголовки. * Разделение интерфейса на активные устройства и отдельную вкладку со всеми ранее заверенными пирами. --- ## Архитектура сетевого взаимодействия ``` +-------------+ +-------------+ | Node A | | Node B | +-------------+ +-------------+ | | | --- 1. UDP Broadcast Beacon (порт 5354) ------------> | | | | <--- 2. HTTPS/TLS 1.3 Handshake (mTLS /p2p/info) ---> | | (Обмен именами, портами и статусом доверия) | | | | === 3. Сверка SAS-кода пользователями на экранах === | | | | --- 4. Запрос доверия: x-node-trusts: -------> | | <--- Ответ: trusts_you: true --------------------- | | | | [Взаимное доверие установлено (Status: mutual)] | | | | --- 5. POST /p2p/text (Только в ОЗУ) ---------------> | | --- 6. POST /p2p/media (Поток на диск) -------------> | ``` --- ## Сборка и установка Требуется компилятор Rust версии **1.75+** (Cargo). ```bash # Клонирование репозитория git clone https://github.com/your-username/ramshare_ui.git cd ramshare_ui # Сборка оптимизированного релиза (LTO + Strip) cargo build --release # Исполняемый файл появится по пути: ./target/release/ramshare_ui ``` --- ## Быстрый старт ### 1. Запуск узла с веб-интерфейсом Запустите узел на обоих устройствах в сети: ```bash # Запуск с параметрами по умолчанию (P2P: 8443, UI: 8080) ramshare_ui serve # Либо с явным указанием имени узла ramshare_ui serve --name "Laptop-Work" ``` После старта откройте в браузере: **`[http://127.0.0.1:8080](http://127.0.0.1:8080)`**. ### 2. Запуск в headless-режиме (сервер/терминал) Если веб-интерфейс не нужен (например, на удалённом сервере или Raspberry Pi): ```bash ramshare_ui serve --no-ui --name "Home-Server" ``` *Входящие текстовые сообщения будут выводиться прямо в stdout терминала, а принятые файлы сохраняться в папку `received_media/`.* --- ## Использование через CLI Все операции можно выполнять через консоль без открытия веб-интерфейса. ### Поиск устройств в сети ```bash # Показать устройства, которые видны прямо сейчас ramshare_ui peers # Вывод списка в формате JSON ramshare_ui peers --json # Сканирование текущей подсети (например, 192.168.1.1-254) ramshare_ui scan # Сканирование произвольного диапазона ramshare_ui scan 192.168.1.50-100 ramshare_ui scan 10.0.0.0/24 ``` ### Заверение устройства (Trust) Для отправки данных устройства должны взаимно подтвердить SAS-код: ```bash # Заверить по имени, IP или префиксу ID ramshare_ui trust Laptop # С ожиданием подтверждения с противоположной стороны (до 60 секунд) ramshare_ui trust 192.168.1.45 --confirm-wait 60 # Отозвать доверие ramshare_ui untrust Laptop ``` ### Отправка текста и файлов ```bash # Отправить текст в оперативную память устройства ramshare_ui send-text Laptop "Привет! Пароль от архива: secret123" # Передача содержимого через конвейер (stdin) cat dump.sql | ramshare_ui send-text Laptop - echo "токен_авторизации" | ramshare_ui send-text 192.168.1.50 - # Отправка одного или нескольких файлов ramshare_ui send-file Laptop ./document.pdf ./archive.tar.gz ``` ### Просмотр параметров узла ```bash ramshare_ui config ``` --- ## Структура каталогов По умолчанию приложение хранит данные рядом с бинарным файлом (или в пути, переданном через `--data-dir`): ```text . ├── ramshare_ui # Исполняемый файл ├── config/ # Каталог конфигурации │ ├── config.json # Идентичность узла (приватный ключ, сертификат, имя) │ └── trusted.json # База данных заверенных устройств и их адресов └── received_media/ # Папка принятых файлов ├── report.pdf └── 1774500000_a1b2c3_photo.png ``` *Файл `config.json` генерируется автоматически при первом запуске с правами доступа `0600` (Unix).* --- ## Параметры командной строки | Параметр | По умолчанию | Описание | | --- | --- | --- | | `--name <имя>` | Имя хоста ОС | Имя устройства, отображаемое другим пирам в сети | | `--p2p-port <порт>` | `8443` | Порт для HTTPS / mTLS соединений передачи данных | | `--ui-port <порт>` | `8080` | Порт веб-интерфейса (привязывается строго к `127.0.0.1`) | | `--ip ` | Авто | Принудительная привязка к конкретному локальному адресу | | `--data-dir <путь>` | Рядом с бинарником | Базовая папка для каталогов `config/` и `received_media/` | | `--ping-interval <с>` | `15` | Интервал периодического опроса устройств (от `10` до `30` с) | | `--no-ui` | `false` | Запуск сервера без поднятия локального веб-сервера | | `--wait <с>` | `4` | Время прослушивания UDP-маяков при выполнении CLI-команд | | `--scan <диапазон>` | `None` | Автоматически сканировать указанную сеть, если пир не найден | | `--confirm-wait <с>` | `0` | Время ожидания подтверждения со второго устройства при `trust` | | `--json` | `false` | Вывод списков узлов (`peers`, `scan`) в формате JSON | | `-y, --yes` | `false` | Пропуск интерактивного запроса подтверждения в CLI | | `-h, --help` | — | Вывод справки по доступным командам | --- ## Безопасность и модель угроз 1. **Защита от прослушивания в открытых сетях:** Весь трафик шифруется TLS 1.3 с современными наборами шифров (AEAD). Провайдер сети или сосед по Wi-Fi не видят передаваемый контент или имена файлов. 2. **Защита от подмены (MitM):** Если злоумышленник пытается перехватить трафик и подменить самоподписанный сертификат на лету, у пользователей **не совпадут SAS-коды сверки**. При несовпадении кодов подтверждать соединение запрещено. 3. **Безопасность Web UI:** Сервер интерфейса слушает только `127.0.0.1`. При попытке внешнего сайта выполнить запрос в локальный браузер (CSRF / DNS-rebinding) запрос отклоняется благодаря проверке заголовков `Origin` и `Host`, а также строгой политике CSP (`frame-ancestors 'none'`, `default-src 'none'`). 4. **Защита файловой системы:** Имена входящих файлов нормализуются с вырезанием управляющих символов и попыток выхода из каталога (`../`). Файлы с исполняемыми расширениями (`.sh`, `.exe`, `.bat` и др.) помечаются в интерфейсе как потенциально опасные и не открываются автоматически.