Как устроено
Из чего сделан MultiOBX
Коротко о том, на чём работает сервис и почему сделано именно так. Только то, что есть в коде и что можно проверить.
01Основа
Протокол WireGuard
Туннель работает по протоколу WireGuard. У него фиксированный набор шифров (ChaCha20-Poly1305 для трафика, Curve25519 для обмена ключами), настроек, которые можно случайно ослабить, в нём нет. Код протокола небольшой, его рукопожатие прошло формальную проверку.
Рукопожатие занимает один обмен пакетами. Поэтому соединение поднимается за доли секунды и переживает смену сети: переключились с Wi-Fi на мобильный интернет, туннель продолжил работать с того же места.
Служба на Rust
Служба, которая держит туннель и сетевые правила, написана на Rust. Язык не допускает ошибок работы с памятью, а на них держится большая часть уязвимостей в сетевых программах.
Окно приложения работает отдельно и без прав администратора. Со службой оно общается через именованный канал Windows, а не через порт на localhost, к которому могла бы обратиться открытая в браузере страница.
02Заслон раньше туннеля
Правила файрвола ставятся до создания сетевого адаптера, а не после.
Порядок при подключении такой: поставить правила «закрыть всё, кроме адреса сервера», создать адаптер, дождаться рукопожатия, настроить DNS, разрешить трафик через адаптер. Между первым и последним шагом наружу не уходит ни одного пакета. Порядок закреплён тестом: поменяешь его, сборка не пройдёт.
Обрыв связи, недоступный сервер, перезапуск туннеля сеть не открывают. Открывает только кнопка «Отключить». Отдельно есть режим «замок»: с ним интернет без туннеля не работает вообще, даже после ручного отключения. Полезно на ноутбуке, который просыпается в кафе или в гостинице.
03DNS отдельно от всего
Перед тем как открыть сайт, компьютер запрашивает его адрес по имени. Эти DNS-запросы уходят с машины отдельно от остального трафика, и это самая частая утечка. Типичный случай: вы включили «Локальную сеть», чтобы работал принтер, а домашний роутер тоже локальная сеть, и запросы пошли через него к провайдеру.
У нас DNS вынесен в отдельный слой правил. Разрешён только резолвер внутри туннеля и локальный адрес 127.0.0.1. Даже при включённой локальной сети роутер DNS-запросов не получит. На это есть отдельный тест.
Правило, которое разрешает соединение с нашим сервером, привязано к исполняемому файлу службы. Другая программа отправить пакет на адрес сервера мимо туннеля не сможет.
Все правила стоят в Windows Filtering Platform, системном фильтре трафика. Их видно любой программой, которая умеет читать WFP, и они не зависят от того, открыто окно приложения или нет.
04Когда сеть режет трафик
В офисной, гостиничной или мобильной сети UDP могут ограничивать или замедлять. На этот случай в приложении несколько способов установить соединение. Оно пробует их по очереди.
UDP напрямую
Штатный режим WireGuard. Самый быстрый. Работает дома и почти во всех мобильных сетях.
Поверх TCP, порт 443
Тот же туннель внутри TCP-соединения на 443-й порт. Этот порт открыт практически везде, потому что на нём работают обычные сайты.
Через два сервера
Трафик входит на один сервер и выходит с другого. Первый видит ваш адрес, но не видит, куда вы идёте. Второй наоборот. Режим доступен, когда серверов больше одного.
Есть ещё маршрут через сеть добровольных анонимных узлов. Соединение проходит три узла, и ни один из них не знает одновременно отправителя и получателя. Медленнее остальных, зато наш сервер в этом маршруте не участвует. Ставить отдельную программу не нужно, всё внутри приложения.
Какой способ прошёл в вашей сети, видно в разделе «Диагностика». Гарантировать соединение в любой сети мы не можем.
05Откуда приложение узнаёт адреса серверов
Приложению нужно откуда-то получить список серверов. Если этот источник пропадает, подключиться не выйдет, даже когда сами серверы в порядке. Слабое место любого такого сервиса именно здесь.
Поэтому список подписан (Ed25519), а открытый ключ для проверки подписи зашит в приложение при сборке. На сервере этого ключа нет. Подменённый список приложение отбросит. Получить список можно несколькими независимыми путями: с основного адреса, с запасных, через защищённые DNS-запросы к публичным резолверам. Достаточно одного рабочего.
Обновления приложения подписаны так же. Закрытый ключ подписи лежит у владельца, не на серверах: взлом сервера не позволит раздать чужую программу под видом обновления.
06Что хранится на сервере
- Ключ
- 24 символа из алфавита в 31 знак, без 0, O, 1, I и L, чтобы не путать при переписывании. Последний символ контрольный, опечатка отсекается ещё до отправки. На сервере лежит HMAC-SHA256 от ключа, сам ключ нигде не записан.
- Устройства
- Открытый ключ WireGuard, адрес внутри туннеля, имя из словаря. Настоящее имя компьютера не запрашивается.
- Срок
- Дата, до которой оплачено. Больше ничего.
- Журналы
- Серверы не ведут журнал соединений: кто, когда, куда. Хранить нечего, и отдавать тоже.
- Смена ключа
- Раз в 30 дней ключ можно заменить из кабинета. Устройства, адреса и оплаченные дни остаются. Старый ключ перестаёт работать сразу.
07Как проверить
В приложении есть раздел «Диагностика». Он показывает, есть ли у службы права ставить правила, сколько правил стоит в данный момент и какие, какой DNS используется, когда было последнее рукопожатие. То же самое из командной строки: multiobx doctor.
Список правил можно посмотреть и без нашего приложения, средствами Windows:
netsh wfp show filters file=filters.xml
Простой опыт: подключитесь, на пару секунд выдерните кабель или выключите Wi-Fi, потом верните. Интернет появится только вместе с туннелем, не раньше.