Как ломается связь
Связь телефона с VPN-сервером ломается на разных уровнях, и от каждого защищает своё.
- Адрес. У сервера есть IP-адрес, например 203.0.113.17. Если его внесли в список блокировки, до сервера не доходит ничего.
- Подсеть. Адреса лежат блоками по 256 штук, это подсеть /24. Соседние адреса одного хостера почти всегда в одной подсети, а блокировать можно и блок целиком. По сообщениям операторов, с конца лета 2026 года так делают всё чаще.
- Хостер. Компания может выключить сервер или забрать адрес. Бывает, что ограничивают доступ и ко всей сети хостера.
- Протокол. Фильтр может узнать сам способ подключения по виду трафика или резать UDP на мобильных сетях. Тогда адрес доступен, а данные не идут.
Шарды работают с первыми тремя уровнями. С четвёртым справляются только протоколы и их настройки.
Адрес, порт, группа
IP-адрес — номер сервера в интернете. Порт — номер «двери» на этом адресе, дверей может быть много. Точка подключения — адрес, порт и протокол вместе: в приложении она выглядит как «сервер». На одном адресе их обычно две, по TCP и по UDP.
Общая ли у точек на одном адресе судьба, зависит от того, что заблокировали:
- адрес, его подсеть или сервер у хостера — умирают все порты и протоколы на нём;
- один порт — остальные порты работают;
- UDP — страдают точки на UDP на любых адресах, а TCP работает;
- протокол, узнанный по трафику — он перестаёт работать везде, поможет только другой протокол.
Поэтому пять портов с одним протоколом спасают только от блокировки порта. От распознавания протокола нужен другой протокол, от блокировки адреса — другой адрес. И протоколы на одном адресе связаны: если один распознают и в ответ заблокируют адрес, умрут оба.
Шард — группа людей, которым сервис выдал один и тот же набор адресов. Других адресов сервиса они не знают, а их адреса не знает никто вне группы. Вариант, когда каждый получает все адреса, дальше называется общим профилем.
Главное правило: каждый адрес принадлежит одному шарду. Если два шарда делят адрес, его блокировка бьёт по обоим. Поэтому пять шардов на одном адресе не сделать, а несколько адресов в одном шарде можно и нужно — из разных подсетей и у разных хостеров. Шард — это люди, а не сервер: на одном сервере могут жить адреса разных шардов.
шард 1 · 40
203.0.113.17tcp · udp
198.51.100.40tcp · udp
шард 2 · 40
203.0.113.18tcp · udp — обе закрыты
198.51.100.41tcp · udp
шард 3 · пробные
203.0.113.90tcp · udp
198.51.100.77tcp · udp
192.0.2.55 · аварийный, общий для шардов 1 и 2
для технарейКак это выглядит в конфигурации
В конфигурации клиента точка подключения — это outbound: адрес, порт, протокол, транспорт и параметры маскировки. Шард получает только outbound'ы своих адресов. Если в конфигурации вместо IP стоит домен, он тоже общая судьба: один домен на несколько шардов связывает их. С ключами так же: у каждого шарда свои ключи и пароли, у каждого пользователя свой идентификатор. Тогда утёкший аккаунт можно отключить и видно, из какого шарда утечка.
Строим по шагам
Условный сервис на 120 человек, адреса добавляем по одному.
Адреса в примере взяты из диапазонов для документации (RFC 5737) и никому не принадлежат.
Шаг 1. Один адрес на всех
| Шард | Адреса | Людей |
|---|---|---|
| все | 203.0.113.17 (TCP, UDP) | 120 |
Если придушат UDP, приложение перейдёт на TCP. Если заблокируют адрес, без связи останутся все 120.
Шаг 2. Второй адрес у того же хостера
| Шард | Адреса | Людей |
|---|---|---|
| 1 | 203.0.113.17 | 60 |
| 2 | 203.0.113.18 | 60 |
Блокировка одного адреса задевает 60 человек. Но оба адреса из подсети 203.0.113.0/24, и её блокировка снова отключает всех 120.
Шаг 3. Второй хостер
| Шард | Адреса | Людей |
|---|---|---|
| 1 | 203.0.113.17 + 198.51.100.40 | 60 |
| 2 | 203.0.113.18 + 198.51.100.41 | 60 |
В каждом шарде теперь адреса двух хостеров из разных подсетей, и каждый адрес по-прежнему принадлежит одному шарду. Блок подсети 203.0.113.0/24 больше никого не отключает: 60 человек переходят на свои адреса 198.51.100.x, ещё 60 остаются без запасного. Отсюда принцип: внутри шарда разнообразие, между шардами изоляция.
Шаг 4. Аварийный адрес
Адрес 192.0.2.55 у третьего хостера получают оба шарда, но пользуются им, только когда у шарда умерли все основные адреса. Это осознанное исключение из главного правила: через него почти никто не подключается, поэтому по трафику его трудно заметить. Платим тем, что его знают все, и утечка любой конфигурации раскрывает и его. Тихим он остаётся, только если приложение получает полную конфигурацию с балансировщиком; в простом списке серверов это обычная строка, которую видно и можно выбрать.
Шаг 5. Пробные отдельно
40 пробных пользователей уходят в свой шард на своих адресах, без аварийного.
| Шард | Кто | Адреса | Аварийный | Людей |
|---|---|---|---|---|
| 1 | платящие | 203.0.113.17 + 198.51.100.40 | 192.0.2.55 | 40 |
| 2 | платящие | 203.0.113.18 + 198.51.100.41 | 192.0.2.55 | 40 |
| 3 | пробные | 203.0.113.90 + 198.51.100.77 | нет | 40 |
Семь адресов на 120 человек: каждый основной адрес знают 40, аварийный — 80 платящих. Это раскладка из симулятора. Для примера хватило трёх подсетей, поэтому все шарды их делят и блок подсети задевает каждый. В жизни шардам лучше давать свои подсети.
для технарейАварийный адрес в Xray
Основные outbound'ы шарда собирают в балансировщик, аварийный указывают в его fallbackTag. Балансировщик выбирает по данным observatory (или burstObservatory), которая проверяет outbound'ы из своего subjectSelector. Если тег аварийного туда не входит, его не проверяют, и трафик пойдёт на него, когда основные признаны нерабочими. Ложные срабатывания, например когда у человека просто пропала сеть, иногда отправляют туда трафик раньше времени.
вопрос из залаА если нарезать «один хостер — один шард»?
Тогда неприятности хостера останутся в его шардах, но эти шарды упадут целиком, если у них нет второго адреса где-то ещё. Обычно разнообразие внутри шарда выгоднее: отказ хостера или блок подсети забирают у людей запасной адрес, но не связь.
Пробные пользователи
Пробный доступ получить проще всего, поэтому чаще всего утекает именно пробная конфигурация. Если пробные знают адреса платящих, такая утечка бьёт и по платящим. Поэтому пробных держат в своих шардах, на своих адресах и без аварийного. Одно это отделение даёт половину пользы: если в примере поделить людей только на пробных и платящих, утечка платной конфигурации отключит 80 человек вместо 120, а деление платящих на два шарда снижает это до 40.
Один пробный шард годится только маленькому сервису. При большом потоке пробных набирают когортами: шард принимает новых, пока не наберёт лимит или не пройдёт день, потом закрывается, и следующих отправляют в новый. Когда у всей когорты кончился пробный период, её адреса выводят и платящим больше не выдают: их знают ушедшие. При оплате человек один раз переходит в платный шард и получает новые адреса.
подробнееЧто меняется при 1000 пробных в день
Цифра условная. Если пробный период длится неделю, одновременно активны около 7000 пробных пользователей. В одном шарде каждый его адрес знали бы все они, а каждую замену узнавали бы тысячи новых людей в день, и она сгорала бы так же быстро.
С когортами по 200 человек живых пробных шардов около 35, на них уходит 35–70 дешёвых адресов: по условным ценам из раздела про стоимость это 70–140 € в месяц. Можно экономнее: лимит 500 или когорта на день. Меньше лимит — меньше людей на адрес, но больше адресов и замен. Пробным шардам не нужен аварийный, а несколько их адресов могут жить на одном сервере: для пробных общая судьба сервера допустима.
Когорты не мешают собрать адреса многократными пробными регистрациями, но делают это дороже: вчерашние адреса не касаются сегодняшней когорты. Ограничение частоты регистраций снижает такой сбор ещё сильнее.
подробнееЛюди от одного блогера — вместе или вразброс
Здесь легко смешать три задачи.
- Изоляция риска решает, кто с кем делит адреса. Один человек, который сливает конфигурацию, раскроет свой шард, где бы он ни был. Группировка по источнику помогает в другом случае: когда через один канал пришло много таких людей. Собранные вместе, они раскроют одну когорту, а разбросанные — все шарды. Если когорта кампании горит быстро, это ещё и сигнал о самом источнике.
- Нагрузка — сколько людей на одном адресе. Всплеск от кампании переполнит её шард, поэтому и здесь нужен лимит: кампания занимает несколько шардов, но не смешивается с остальными.
- Учёт источника шарда не требует: откуда пришёл человек, записывают меткой в базе.
Разумный вариант по умолчанию: пробных группируют по времени, крупные кампании — в свои когорты с лимитом, платящих раскладывают по открытым платным шардам, а источник хранят меткой. Сама оплата уже работает как фильтр.
Что меняется при поломках
Одиночные блокировки — адрес, подсеть, сервер у хостера. Без связи никто не остаётся ни в общем профиле, ни в шардах: у каждого есть адрес в другой подсети. Это заслуга разных подсетей, а не шардов. Шарды дают другое: замену заблокированного адреса узнают 40 человек вместо 120, и утечь ей труднее.
Цена. Запасных адресов у человека в шарде меньше: после блока подсети у него один основной адрес против трёх в общем профиле. Пробные в примере после такого блока сидят на последнем адресе, и следующая блокировка их отключит. Нагрузка при переходе тоже собирается на оставшемся адресе шарда, а не расходится по пяти.
Потеря целого набора адресов. Допустим, конфигурация утекла и все её адреса заблокировали. Так бывает не всегда и не сразу, но готовятся к худшему случаю. В общем профиле без связи остаются все 120 и менять приходится все семь адресов. В шардах — одна группа из 40 и два-три адреса.
Против сканирования диапазонов хостеров и анализа трафика число знающих адрес значения не имеет. Шарды помогают против утечек конфигураций и отчасти против связывания адресов по тому, кто на них ходит.
подробнееВсе сценарии одной таблицей
Колонка «осталось» — сколько рабочих основных адресов у затронутых, кто остался на связи.
| Что сломалось | Шарды | Осталось | Общий профиль | Осталось |
|---|---|---|---|---|
| Душат UDP (60 на мобильном интернете) | 60 перешли на TCP | 2, только TCP | то же | 6, только TCP |
| Заблокировали 203.0.113.17 | 20 переключились, 20 без запасного, 80 не заметили; замену узнают 40 | 1 + аварийный | 20 переключились, 100 без запасного; замену узнают 120 | 5 + аварийный |
| Заблокировали подсеть 203.0.113.0/24 или хостер Б выключил сервер | 60 переключились, 60 без запасного; 40 пробных на последнем адресе | 1 (у платящих + аварийный) | 60 переключились, 60 без запасного | 3 + аварийный |
| Выключили аварийный 192.0.2.55 | 80 платящих без аварийного, никто не заметил | 2 | 120 без аварийного, никто не заметил | 6 |
| Утекла пробная конфигурация, её адреса заблокировали | 40 пробных без связи, 80 не заметили | — | все 120 без связи | — |
| Утекла платная конфигурация из шарда 1, её адреса заблокировали | 40 без связи, шард 2 без аварийного, шард 3 не заметил | 2 у шарда 2 | все 120 без связи | — |
для технарейГде модель упрощает
Модель считает, что приложение само переходит на рабочий адрес. Так умеют клиенты, получающие полную конфигурацию с балансировщиком или автовыбором; в приложениях со списком серверов переключаются вручную. Если UDP не режут, а душат, проверки соединения могут проходить, и автоматического перехода не будет. Люди в модели делятся по адресам поровну, а балансировщики выбирают по задержке, поэтому в общем профиле люди обычно кучкуются на «быстром» адресе, и его блокировка задевает больше двадцати. Документация Xray предупреждает, что регулярные проверки observatory оставляют поведенческий след: в общем профиле каждый клиент касается каждого адреса. Общий аварийный раскрывается утечкой любой платной конфигурации, поэтому при большом числе платящих его делают отдельным на каждую группу шардов.
Замена адресов
Заблокированный адрес заменяют, а людей оставляют в их шарде. Новый адрес берут у хостера и из подсети, которых в шарде ещё нет: соседний 203.0.113.140 уйдёт вместе с подсетью при следующей блокировке. Его добавляют рядом со старым, люди получают его при обновлении подписки, а старый убирают, когда клиенты обновились. Ориентир — сутки, решение по фактическому онлайну на старом адресе. Если перекладывать людей между шардами при каждом инциденте, новые соседи узнают адреса старого.
Заблокированный адрес обычно остаётся в блокировке надолго, поэтому адреса не гоняют по кругу: адрес приходит, работает, сколько проработает, и уходит навсегда. Срок жизни адресов стоит измерять по каждому хостеру и подсети, причём проверками изнутри сетей, где блокируют: с самого сервера блокировку не видно.
вопрос из залаПочему бы не купить 10 адресов и не менять их каждые два часа?
Вернуться к адресу по кругу почти наверняка значит вернуться к мёртвому адресу. Частая смена засвечивает все адреса сразу: если все пользователи каждые два часа переезжают на следующий, за день под нагрузкой побывают все десять. И каждая смена рвёт соединения, а приложения получают новый список не мгновенно. Заменять адрес заранее иногда имеет смысл: если у хостера адреса обычно живут дней десять, можно менять их на седьмой. Обрыва люди не заметят, но адресов уйдёт примерно в полтора раза больше.
Раздача и размер группы
Человек попадает в шард один раз, при подключении: по кругу или в наименее заполненный. Назначение записано и само не меняется, иначе со временем человек узнал бы все адреса. Разумный размер платного шарда для небольшого сервиса — 20–50 человек. Мельче — больше адресов и замен, а выигрыш от дробления всё меньше. Деньги уходят на адреса. Деление людей поверх тех же адресов почти ничего не стоит в деньгах, но стоит запаса на человека и работы: замен и мониторинга становится больше.
подробнееСколько это стоит
Условные цены: сервер 10 € в месяц, дополнительный адрес 2 € в месяц.
| Шаг 1 | Общий профиль на 7 адресах | Шаг 5, шарды | |
|---|---|---|---|
| Серверов | 1 | 3 | 3 |
| Дополнительных адресов | 0 | 4 | 4 |
| В месяц | 10 € | 38 € | 38 € |
| Без связи, если адреса утёкшей конфигурации заблокируют | 120 | 120 | 40 |
Если шард разросся, его делят, переводя часть людей на новые адреса. Это делают редко и вручную.
Чего шарды не решают
- Распознавание протокола. Если фильтр узнаёт сам способ подключения, не помогут ни новый адрес, ни новый шард. Помогают протоколы и их настройки.
- Белые списки. Если в сети разрешены только одобренные адреса, адрес из обычного хостинга не заработает, сколько шардов ни нарежь.
- Хостер. Он может забрать адрес или выключить сервер, иногда без предупреждения (пример на Хабре). От этого защищает только разнообразие хостеров внутри шарда.
вопрос из залаМожно купить адрес, на который хостер не сможет претендовать?
Почти нет. «Купленный отдельно» адрес у облачного провайдера всё равно его адрес, оформленный отдельной услугой, и он может его отозвать. Разница в том, что тогда не придётся пересоздавать сервер. Собственный блок /24 получают через регионального регистратора и его посредников (LIR) или берут на вторичном рынке: свободных IPv4 давно нет. Анонсировать его можно у хостера, который это позволяет, но и тогда хостер управляет маршрутизацией и машиной. А свой /24, попавший в блокировку, остаётся заблокированным у любого хостера.
вопрос из залаМожно настроить сервер так, чтобы хостер не понял, что это VPN?
Нет. Хостеру не нужно расшифровывать трафик, ему достаточно видеть потоки: сотни домашних и мобильных адресов подключаются к одной машине, входящий объём примерно равен исходящему. Это характерная картина ретранслятора. Протоколы прячут содержимое от фильтров в сети, но картину потоков видит тот, кто владеет оборудованием. Поэтому надёжная схема исходит из того, что любой адрес и любой сервер когда-нибудь пропадут, и заранее готовится их быстро заменить.