Unissh — open-source Ssh‑клиент с zero‑knowledge self-hosted сервером синхронизации

unissh - современный open-source SSH‑клиент с self-hosted zero‑knowledge сервером для синхронизации данных

unissh появился из очень практичной боли: когда работаешь с серверами регулярно, хочется одинаково комфортного доступа и с ноутбука, и со смартфона. Носить с собой один-единственный "главный" девайс - сомнительная идея, а разрозненные наборы конфигов, ключей и заметок на разных устройствах рано или поздно превращаются в хаос. При этом "готовые" клиенты с синхронизацией часто предлагают компромиссы, которые подходят не всем: привязку к экосистеме Apple через iCloud, синк через сторонние файлохранилища, спорные решения по интерфейсу, отсутствие шифрования, а иногда и невозможность нормально забрать свои же данные без подписки.

Именно поэтому unissh задуман как простой, современный и кроссплатформенный SSH‑клиент с нормальной синхронизацией - но без необходимости доверять серверу содержимое ваших данных. Проект открыт, написан на Rust и Tauri, и при всей "вайбкодной" природе разработки команда постаралась уделить внимание тестированию и предсказуемости поведения на разных платформах.

Что умеет unissh как клиент

По функциональности это не "терминал на минималках", а полноценный инструмент для повседневной работы:

- Кроссплатформенность: Windows, macOS, Linux, iOS и Android. Логика при этом единая, а не "пять реализаций одной и той же идеи".
- Терминалы: базовые удобства для тех, кто живет в SSH - сплит вкладок в разных вариантах, дублирование сессий, переименование и прочие привычные возможности.
- SFTP: загрузка и выгрузка файлов на сервера и обратно. Для сценариев с большим количеством объектов можно регулировать число активных SFTP‑подключений. Встроен базовый текстовый редактор, чтобы не прыгать между приложениями.
- Массовое выполнение команд в двух режимах:
- *Broadcast*: открываются несколько SSH‑сессий к выбранным серверам, и вы наблюдаете вывод команд вживую.
- *Fleet exec*: команды отправляются на узлы "пакетом", а в ответ показывается результат выполнения (exit code) по каждому серверу - полезно, когда важна сводка, а не поток логов.
- Секреты и все, что вокруг доступа: SSH‑ключи, пароли, "идентичности", заметки. Поддерживается импорт из `~/.ssh/config`. У секретов есть история версий, что удобно для аудита собственных изменений и откатов.
- SSH‑туннели: Local, Remote и Dynamic - чтобы прокидывать порты, поднимать SOCKS и решать типовые задачи администрирования.
- Запись сессий в формате asciicast v2 - пригодится для воспроизводимых отчетов, демо и разборов инцидентов.
- Сниппеты: заготовки команд, которые можно хранить и запускать быстрее, чем вспоминать "как там было в прошлый раз".
- Гибкая кастомизация интерфейса: поддержка тем, светлых/темных вариаций, плюс возможность делать свои. Из коробки упомянуты темы приложения Mono, Nebula, Barbie (да, с "барби‑настроением"), а также несколько тем терминала.
- Подключение к нескольким серверам синхронизации: сценарий, когда есть личное хранилище "своих волтов" и отдельное рабочее пространство компании/команды.

Архитектура: один криптокод для всех платформ

Одна из сильных сторон unissh - то, как организован проект. В основе лежит кроссплатформенное ядро на Rust (rust-core): workspace из девяти крейтов, где живут криптография, "волты" на SQLCipher, SSH‑стек (russh), встроенный in‑memory SSH‑агент и логика синхронизации.

Важно, что крипта и SSH не "переписываются отдельно под iOS/Android/десктоп". Клиент на iOS, десктопный клиент и даже админка в браузере используют один и тот же код: клиенты подключаются к ядру через UniFFI, а веб‑панель администрирования работает через это же ядро, собранное в WASM. Такой подход уменьшает расхождения в поведении и снижает вероятность ошибок, которые обычно рождаются при дублировании критичной логики.

Сами клиенты сделаны на Tauri v2 + React: один кодбейс на пять платформ. UI - "тонкий слой": оболочка, терминал на xterm.js, а чувствительные операции остаются по другую сторону FFI‑границы внутри rust‑ядра.

Сервер: self-hosted и принципиально "ничего не знает"

Сервер нужен не всем. Если вы используете unissh на одном устройстве, можно жить и без него. Но если требуется синхронизация между девайсами или командная работа - сервер становится центральной точкой обмена.

При этом ключевой принцип сформулирован жестко: сервер - zero‑knowledge. Он не должен понимать, что именно вы храните и синхронизируете. Технически это реализовано так: сервер - небольшой бинарь на Rust (axum + sqlx) с базой на выбор (SQLite или PostgreSQL). Его роль - хранить шифроблобы, версии и правила членства (кто к какому пространству/волту относится).

Шифрование происходит на устройстве до отправки. Ключи выводятся из Secret Key (аналог "Emergency Kit" в духе менеджеров паролей) и пароля через Argon2id. На сервер уходит только ciphertext: содержимое секретов, заметок, ключей и прочих данных в виде набора зашифрованных объектов.

Отдельно заложена криптографическая дисциплина целостности: сервер, как минимум, может проверять подписи (например, на Ed25519) и корректность структуры данных, но не получает возможности их расшифровать. Иными словами, это хранилище, которое следит за версиями и доступами, а не "облачный сервис, которому вы отдаете все".

Быстрый селфхостинг и админ‑панель

Идея self-hosted часто разбивается о реальность: конфиги, миграции, непонятные зависимости, полдня на "завести". Здесь цель обратная - поднять сервер быстро, чтобы синхронизация стала доступной без долгой подготовки. Серверный компонент - компактный и не требует экзотических технологий: запускаете бинарь, выбираете SQLite или PostgreSQL, задаете параметры хранилища - и можно подключать клиентов.

Для управления предусмотрена веб‑панель администратора. Важный момент: админка использует то же крипто‑ядро (WASM‑сборка rust-core), поэтому поведение в части проверок, форматов и совместимости не расходится с клиентами. Это снижает риск ситуации, когда "в браузере одно, в приложении другое".

---

Дополнительные важные моменты, о которых стоит знать (расширение темы)

1) Кому unissh особенно полезен

В первую очередь - тем, кто живет в инфраструктуре: DevOps/SRE, админы, разработчики, которые постоянно заходят на стенды, прод и тестовые окружения. Если у вас десятки хостов, разные ключи, туннели и "памятки" по запуску команд - единое зашифрованное пространство с синхронизацией экономит часы.

2) Чем zero‑knowledge отличается от "просто шифрования"

"Данные шифруются" - формулировка слишком общая. В zero‑knowledge подходе критично, что сервер не получает ни ключей, ни производных, позволяющих расшифровать содержимое. Даже при полном доступе к базе он видит только наборы ciphertext и метаданные, необходимые для синка (версии, членство, идентификаторы объектов). Это меняет модель угроз: вы защищаетесь не только от перехвата трафика, но и от компрометации самого сервера.

3) Как не потерять доступ: роль Secret Key и пароля

Обратная сторона сильной модели - ответственность. Если Secret Key и пароль потеряны, "магической кнопки восстановления" быть не должно: иначе сервер перестал бы быть zero‑knowledge. Поэтому подход ближе к философии "Emergency Kit": хранить ключ безопасно (офлайн‑копия, менеджер секретов, сейф-подход), а пароль - достаточно стойкий, чтобы Argon2id имел смысл.

4) Почему единое ядро на Rust - это не просто "модно"

В приложениях, где есть криптография, синхронизация и работа с ключами, самая частая причина проблем - расхождение реализаций по платформам. Когда iOS‑клиент шифрует чуть иначе, чем Android‑клиент, начинаются "призраки" в данных и сложные для отладки ошибки. Единое rust‑ядро, используемое через UniFFI/WASM, резко снижает класс подобных рисков.

5) Командные сценарии: разделение личного и рабочего

Поддержка нескольких серверов синхронизации - практичная деталь. Можно держать личные "волты" на своем сервере, а рабочие - на сервере компании, не смешивая контексты. Это упрощает и безопасность (разные домены доверия), и гигиену данных (меньше случайных утечек между средами).

6) Массовые команды без самообмана

Два режима - Broadcast и Fleet exec - закрывают разные задачи. Broadcast хорош, когда вы реально хотите видеть вывод (например, диагностика). Fleet exec полезнее для типовых "применить/проверить" на пачке машин: вам важен факт успеха/ошибки и быстрый список результатов, а не километры логов.

7) Запись сессий в asciicast: не только "красиво"

asciicast v2 - это не просто формат "для демо". Он подходит для воспроизведения действий при разборе инцидентов, для обучения новичков в команде и для фиксации последовательности команд, которые привели к определенному эффекту. При аккуратном использовании это становится инструментом дисциплины: меньше "я не помню, что делал", больше воспроизводимости.

8) SFTP и параллельность - важная деталь для больших каталогов

Когда работаешь с сотнями и тысячами файлов, производительность SFTP упирается в параллельные запросы и управление соединениями. Возможность регулировать количество активных подключений - не "галочка", а практический рычаг: можно ускоряться там, где это безопасно, или снижать нагрузку на слабые серверы.

9) Темы и UI - это тоже часть надежности

Интерфейс в SSH‑клиенте недооценивают до первого ночного инцидента. Когда вы по усталости путаете вкладки, окружения или хосты, цена ошибки растет. Кастомизация тем, названий, структура вкладок и сплитов - это не только эстетика, но и снижение человеческого фактора.

10) Кому self-hosted сервер не нужен

Если вы не синхронизируете данные между устройствами и не делаете командный доступ, сервер можно не поднимать вовсе. В этом случае unissh остается локальным инструментом: терминал, ключи, туннели, сниппеты - все на устройстве. Сервер - опция, а не обязательная часть.

unissh в итоге выглядит как попытка собрать "правильный минимум" и добавить ровно те возможности, которые в реальной админской жизни оказываются важнее всего: кроссплатформа, удобная работа с множеством хостов, SFTP, массовые команды, туннели, записи сессий и - главное - синхронизация без доверия серверу благодаря zero‑knowledge модели. Это ровно тот случай, когда проект решает понятную практическую задачу, а архитектура под эту задачу выстроена не ради модных слов, а ради снижения рисков и упрощения поддержки.

Прокрутить вверх