Submarine

Эта страница — перевод. Если он расходится с английской версией, силу имеет английская версия. Английская версия

Как защищены ваши данные

Мы не просим вас нам доверять. На этой странице точно описано, что шифруется, что наш сервер может видеть, а что — нет, и как вы можете сами проверить каждое утверждение.

Главное за минуту

  • Ваши серверы, учётные данные, ключи и заметки хранятся в одном файле на вашем устройстве и зашифрованы алгоритмом AES-256-GCM. Несколько настроек, которые относятся только к этому устройству, — например, внешний вид приложения и папка, к которой открыт доступ RDP-серверу, — хранятся в настройках приложения без шифрования и никогда не синхронизируются.
  • Ключ получается из пароля профиля с помощью Argon2id — метода, который намеренно работает медленно, чтобы подбор пароля обходился дорого. Пароль никогда нигде не хранится и никуда не отправляется.
  • Если вы включите синхронизацию, каждый элемент шифруется на вашем устройстве перед загрузкой на сервер. Сервер хранит данные, которые не может расшифровать.
  • При этом сервер видит внешнюю сторону ваших данных: ваш адрес электронной почты, когда и с какого IP-адреса вы выполняете синхронизацию, сколько у вас элементов каждого типа и какого они размера, названия ваших профилей, а для общих профилей — их названия и адреса электронной почты участников.
  • В приложении нет рекламы, аналитики и отправки отчётов о сбоях.

Сервер не может прочитать

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

Сервер может видеть

  • Ваш адрес электронной почты, а также пароль учётной записи при входе (сервер хранит только его хеш bcrypt)
  • IP-адрес и время входов и синхронизаций
  • Сколько элементов каждого типа в профиле, их размеры, а также когда и с какого устройства изменён каждый из них (устройство обозначается случайным идентификатором)
  • Названия ваших профилей
  • Для общих профилей: их названия, адреса электронной почты участников и их роли

Что происходит при синхронизации

Никогда не покидает ваше устройство
Пароль профиляArgon2idКлюч профиляAES-256-GCMЗашифрованные элементы
HTTPSСервер синхронизацииХранит зашифрованные элементы и перечисленные выше сведения
Пароль и ключи остаются на вашем устройстве. Отправляются только зашифрованные элементы и сопутствующие сведения о них.

1. На вашем устройстве

Каждый профиль — это один файл. Внутри — небольшая база данных с вашими серверами, учётными данными, SSH-ключами, заметками и настройками. Вся база данных сжимается, а затем шифруется алгоритмом AES-256-GCM. При каждом сохранении файла используется новый случайный nonce, а сам файл сначала записывается во временную копию, поэтому из-за сбоя не может остаться наполовину записанный файл.

Ключ получается из пароля профиля и случайной соли, своей для каждого профиля, с помощью Argon2id с параметрами: память — 64 MiB, проходов — 3, потоков — 4. Эти параметры жёстко заданы в приложении, поэтому изменённый файл не может их ослабить.

Пароль никогда не записывается на диск и никуда не отправляется. Когда ключ получен, копия пароля в ядре приложения стирается, а сам ключ стирается, когда вы блокируете профиль. Блокировка также закрывает все соединения и прерывает вход, который ещё выполняется. Если вы забудете пароль, профиль невозможно будет открыть. Сброса нет, потому что нигде не хранится ничего, чем его можно было бы открыть.

Быстрая разблокировка необязательна и по умолчанию выключена. В Windows она использует Windows Hello и TPM, на Android — сканер отпечатков пальцев и Android Keystore. Система хранит ключ профиля, но никогда не хранит ваш пароль, и этот ключ никогда не синхронизируется. На Android системное облачное резервное копирование данных приложения отключено.

В Windows, когда «Подключение к удалённому рабочему столу» (Remote Desktop Connection) открывает сервер с сохранённым паролем, приложение передаёт ему пароль во временном файле .rdp. Пароль в нём зашифрован с помощью Windows DPAPI для вашего пользователя Windows, а файл удаляется, как только эта программа его прочитает (не позднее чем через 30 секунд; файл, оставшийся после сбоя, удаляется при следующем запуске).

2. Cloud sync (облачная синхронизация)

Пока вы не вошли в учётную запись, синхронизация выключена. У каждого профиля есть свой случайный 256-битный ключ данных, который хранится внутри зашифрованного профиля. Перед загрузкой на сервер каждый элемент (сервер, учётные данные, ключ, заметка…) шифруется отдельно этим ключом — алгоритмом AES-256-GCM с новым случайным nonce.

Вместе с каждым зашифрованным элементом сервер получает случайный идентификатор, тип элемента, метку времени и флаг, который показывает, удалён ли элемент. Метка времени содержит случайный идентификатор устройства, на котором сделано изменение. По размеру зашифрованного элемента можно примерно судить о размере самого элемента. Кроме того, сервер хранит название каждого профиля. Известные ключи хостов, история команд, настройки мониторинга и параметры, заданные только для этого устройства, никогда не синхронизируются.

Вот что сервер хранит для одного элемента: (Пример)

{
  "uuid": "6f1c2e0a9b7d4c3e8a5f0d1b2c3e4f50",
  "entity_type": "servers",
  "updated_at": "001761043562118:00000:9f3a61c2d4e5b7a8",
  "deleted": false,
  "blob": "4e8a1f0c2b9d3e7a5c6f8b1d0a2e4c6b8d0f1a3c5e7b9d1f…"
}

3. Открытие профиля на новом устройстве

Чтобы открыть синхронизированный профиль на другом устройстве, этому устройству нужен ключ данных профиля. Поэтому сервер хранит ещё одну запись: ключ данных, зашифрованный ключом, который получается из вашего пароля профиля с теми же параметрами Argon2id. Сервер не может её открыть.

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

4. Пароль учётной записи

У вашей учётной записи синхронизации свой пароль, отдельный от пароля профиля. При входе он передаётся на сервер по HTTPS, а сервер хранит только его хеш bcrypt. После 5 попыток с неверным паролем вход по паролю приостанавливается на 15 минут.

Перед сервисом стоит Cloudflare, который берёт на себя HTTPS-соединение. Поэтому Cloudflare, как и сервер, мог бы видеть ваш пароль учётной записи при входе, а ваши элементы — только в зашифрованном виде.

Никогда не используйте пароль профиля в качестве пароля учётной записи. Тогда ничто из того, что когда-либо видят сервер или Cloudflare, не сможет открыть ваши профили.

5. Общий доступ к профилю

Для общего доступа к профилям у каждой учётной записи есть пара ключей X25519. Закрытый ключ шифруется ключом, который получается из вашей парольной фразы для общего доступа (снова с помощью Argon2id), а сама парольная фраза никогда не покидает ваше устройство. Каждый участник общего профиля получает ключ данных профиля, зашифрованный его собственным открытым ключом.

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

6. Если бы сервер был враждебным

Хорошая безопасность определяется не только тем, что сервер должен делать. Вот что мог бы и чего не мог бы сделать тот, кто полностью контролирует сервер.

Он не смог бы

  • Прочитать ваши элементы или незаметно изменить их содержимое
  • Открыть хранимую копию ключа профиля без вашего пароля профиля
  • Узнать ваш пароль профиля или парольную фразу для общего доступа — приложение их никогда не отправляет
  • Изменить приложение на вашем устройстве: автоматических обновлений нет, приложение только показывает, что есть новая версия

Он смог бы

  • Попытаться подобрать слабый пароль профиля офлайн — по одному медленному прогону Argon2id на каждую попытку
  • Перехватить ваш пароль учётной записи при следующем входе
  • Удалять элементы, возвращать старые версии или задерживать изменения. Прежде чем синхронизация что-либо удалит, приложение сохраняет на вашем устройстве копию профиля
  • Выдать не тот открытый ключ, когда вы приглашаете кого-то в общий профиль
  • Видеть сведения, перечисленные в таблице выше

7. Всё, к чему подключается приложение

Ваши собственные серверы, а также прокси и промежуточные хосты, которые вы для них настроили. Сервер синхронизации — только когда вы вошли в учётную запись. И GitHub — чтобы проверить, нет ли новой версии: когда открывается список профилей и когда вы нажимаете «Check for updates», приложение обращается к публичному списку релизов на GitHub. Этот запрос содержит только название и версию приложения.

В приложении нет кода для аналитики, отчётов о сбоях или рекламы. Для синхронизации приложение доверяет только собственному встроенному списку центров сертификации и никогда не следует перенаправлениям, поэтому его нельзя незаметно направить на другой сервер.

8. Что удалённый рабочий стол получает с вашего устройства

Буфер обмена. Текст, который вы вставляете во вкладку RDP или VNC, уходит на этот сервер, а до вставки ему ничего не предлагается. Когда включён параметр Share the clipboard (так по умолчанию; переключатель есть у каждого сервера), текст, скопированный на удалённом рабочем столе, помещается в буфер обмена этого устройства. Передаётся только текст, никогда не файлы, а VNC передаёт только простой текст ASCII.

Файлы — только со встроенным RDP-клиентом на компьютере и только если вы выберете для этого сервера папку или диск, при желании — только для чтения. Сервер видит выбранное как диск в \\tsclient и больше ничего на вашем компьютере. Каждый путь, который он запрашивает, проверяется: .. не допускается, и по ссылкам на этом пути приложение не переходит, поэтому за пределы выбранного вами выйти нельзя.

Эти настройки хранятся на этом устройстве и никогда не синхронизируются, поэтому никто из тех, с кем вы делитесь профилем, не сможет их включить.

Проверьте сами

Ни в чём из этого не нужно верить нам на слово. Вот способы проверить — от простых до продвинутых.

  1. Прочитайте код

    У приложения открытый исходный код. Ссылки на этой странице ведут ровно на те строки кода, которые за это отвечают, в той версии, которую описывает страница (c9dec31).

  2. Понаблюдайте за соединениями

    Используйте брандмауэр или сетевой монитор. Вы увидите свои серверы, сервер синхронизации (только пока вы вошли в учётную запись) и api.github.com (когда открывается список профилей). Больше ничего.

  3. Посмотрите, что хранит сервер

    Для опытных: возьмите токен входа из папки данных приложения (cloud_token.json) и запросите у API свои данные — GET /api/sync/profiles или POST /api/sync с пустым списком записей — с заголовком X-Auth-Token. В ответ придут только идентификаторы, типы, метки времени, флаги и зашифрованный текст. После этого выйдите из учётной записи в приложении, чтобы завершить этот сеанс.

  4. Изучите трафик

    Для опытных: запустите на своём компьютере небольшой прокси, который передаёт запросы настоящему серверу, и укажите в приложении сервер синхронизации http://127.0.0.1 с портом прокси. Приложение разрешает обычный HTTP только для вашего собственного компьютера. Вы увидите, что отправляет приложение и что ваши элементы зашифрованы. (Сертификат прокси, добавленный в систему, не сработает: приложение использует собственный список центров сертификации.)

  5. Расшифруйте свои данные

    Для опытных: зная пароль, вы можете открыть свои данные любым инструментом для Argon2id и AES-GCM с параметрами из таблицы ниже. Без пароля этого не может никто.

  6. Проверьте скачанный файл

    Сравните контрольную сумму с файлом SHA256SUMS в релизе (начиная с версии 0.4), проверьте сертификат приложения для Android с помощью apksigner или соберите приложение из исходного кода.

Параметры для ваших инструментов

Получение ключаArgon2id, версия 0x13, память — 64 MiB, проходов — 3, потоков — 4, ключ — 32 байта, случайная соль — 16 байт
Файл профиля“OMNV” · версия 1 · соль (16 байт) · nonce (12 байт) · база данных SQLite, сжатая zstd и зашифрованная AES-256-GCM, вместе с 16-байтовым тегом
Синхронизируемый элементhex(nonce (12 байт) · шифротекст и тег AES-256-GCM); ключ — 256-битный ключ данных профиля
Хранимая копия ключа профиляhex(0x02 · соль (16 байт) · nonce (12 байт) · 32-байтовый ключ данных, зашифрованный AES-256-GCM); ключ получается из вашего пароля профиля
Общий доступX25519, HKDF-SHA256, AES-256-GCM

Чего эта страница не обещает

  • Submarine не проходил независимый аудит безопасности. Проверки до сих пор проводил сам автор.
  • Слабый или повторно используемый пароль — самое уязвимое место. Используйте длинный уникальный пароль профиля и другой пароль для учётной записи.
  • Telnet и обычный VNC по своей природе не шифруются. Приложение помечает их и может пропускать их через SSH-сервер. При обычном VNC текст из буфера обмена, который вставляете вы или копирует сервер, тоже передаётся по сети без шифрования.
  • Встроенный RDP-клиент экспериментальный (он собран из коммита IronRDP, а не из релиза) и выключен, пока вы не выберете его для сервера.
  • Эта страница описывает приложение по состоянию на коммит c9dec31. Если код изменится, страница изменится вместе с ним.