blchv ENвсе штуки

Кого заденет блокировка адресов VPN

Я делаю VPN-сервис и разбирался, почему связь иногда пропадает сразу у всех. Часто дело не в протоколе: все пользователи знают одни и те же адреса серверов, и потеря этих адресов бьёт по всем. Шарды — способ раздать адреса так, чтобы потеря задевала одну группу. Ниже симулятор, выжимка на минуту и разбор: что это даёт, чего стоит и где не помогает.

что сломать

сценарий · выбери, что сломать

Общий профиль

каждый знает все семь адресов

0без связи

переключились
—
без запасного
—
не заметили
—
на грани обрыва
—
замену узнают
—
запас адресов
—

Шарды

три группы по 40, у каждой свои адреса

0без связи

переключились
—
без запасного
—
не заметили
—
на грани обрыва
—
замену узнают
—
запас адресов
—

Условности: приложение само переходит на рабочий адрес (так умеют не все), люди поровну на адресах, на весь пример три подсети. «На грани» — рабочий вход остался один или все в одной подсети, «запас» — рабочие основные адреса у тех, кого задело.

кто к какому адресу подключён

Общий профиль

203.0.113.17
203.0.113.18
203.0.113.90
198.51.100.40
198.51.100.41
198.51.100.77
192.0.2.55аварийный, тихий

Шарды

шард 1 · платящие

203.0.113.17
198.51.100.40
192.0.2.55аварийный, тихий

шард 2 · платящие

203.0.113.18
198.51.100.41
192.0.2.55аварийный, тихий

шард 3 · пробные

203.0.113.90
198.51.100.77

Коротко

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

Идея. Шарды: людей делят на группы, у каждой группы свои адреса, общих нет. Внутри группы адреса берут из разных подсетей и у разных хостеров, чтобы при блокировке одной подсети оставался запасной.

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

Цена и границы. Запасных адресов у каждого человека меньше, поэтому группа ближе к обрыву при череде блокировок. От распознавания протокола и белых списков шарды не спасают, от решения хостера — только разные хостеры внутри группы. Шарды уменьшают ущерб, но не прячут VPN.

Подробный разбор · 6 минут ↓

Как ломается связь

Связь телефона с VPN-сервером ломается на разных уровнях, и от каждого защищает своё.

Шарды работают с первыми тремя уровнями. С четвёртым справляются только протоколы и их настройки.

Адрес, порт, группа

IP-адрес — номер сервера в интернете. Порт — номер «двери» на этом адресе, дверей может быть много. Точка подключения — адрес, порт и протокол вместе: в приложении она выглядит как «сервер». На одном адресе их обычно две, по TCP и по UDP.

Общая ли у точек на одном адресе судьба, зависит от того, что заблокировали:

Поэтому пять портов с одним протоколом спасают только от блокировки порта. От распознавания протокола нужен другой протокол, от блокировки адреса — другой адрес. И протоколы на одном адресе связаны: если один распознают и в ответ заблокируют адрес, умрут оба.

Шард — группа людей, которым сервис выдал один и тот же набор адресов. Других адресов сервиса они не знают, а их адреса не знает никто вне группы. Вариант, когда каждый получает все адреса, дальше называется общим профилем.

Главное правило: каждый адрес принадлежит одному шарду. Если два шарда делят адрес, его блокировка бьёт по обоим. Поэтому пять шардов на одном адресе не сделать, а несколько адресов в одном шарде можно и нужно — из разных подсетей и у разных хостеров. Шард — это люди, а не сервер: на одном сервере могут жить адреса разных шардов.

шард 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

Каждый квадратик — человек, рамка — шард. Заблокировали 203.0.113.18: обе точки подключения на нём, TCP и UDP, закрылись вместе с адресом. Задет только шард 2: 20 человек перешли на 198.51.100.41 (зелёные), ещё 20 работают без запасного (жёлтая рамка). Шарды 1 и 3 этого адреса не знали.
для технарейКак это выглядит в конфигурации

В конфигурации клиента точка подключения — это outbound: адрес, порт, протокол, транспорт и параметры маскировки. Шард получает только outbound'ы своих адресов. Если в конфигурации вместо IP стоит домен, он тоже общая судьба: один домен на несколько шардов связывает их. С ключами так же: у каждого шарда свои ключи и пароли, у каждого пользователя свой идентификатор. Тогда утёкший аккаунт можно отключить и видно, из какого шарда утечка.

Строим по шагам

Условный сервис на 120 человек, адреса добавляем по одному.

Адреса в примере взяты из диапазонов для документации (RFC 5737) и никому не принадлежат.

Шаг 1. Один адрес на всех

ШардАдресаЛюдей
все203.0.113.17 (TCP, UDP)120

Если придушат UDP, приложение перейдёт на TCP. Если заблокируют адрес, без связи останутся все 120.

Шаг 2. Второй адрес у того же хостера

ШардАдресаЛюдей
1203.0.113.1760
2203.0.113.1860

Блокировка одного адреса задевает 60 человек. Но оба адреса из подсети 203.0.113.0/24, и её блокировка снова отключает всех 120.

Шаг 3. Второй хостер

ШардАдресаЛюдей
1203.0.113.17 + 198.51.100.4060
2203.0.113.18 + 198.51.100.4160

В каждом шарде теперь адреса двух хостеров из разных подсетей, и каждый адрес по-прежнему принадлежит одному шарду. Блок подсети 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.40192.0.2.5540
2платящие203.0.113.18 + 198.51.100.41192.0.2.5540
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 перешли на TCP2, только TCPто же6, только TCP
Заблокировали 203.0.113.1720 переключились, 20 без запасного, 80 не заметили; замену узнают 401 + аварийный20 переключились, 100 без запасного; замену узнают 1205 + аварийный
Заблокировали подсеть 203.0.113.0/24 или хостер Б выключил сервер60 переключились, 60 без запасного; 40 пробных на последнем адресе1 (у платящих + аварийный)60 переключились, 60 без запасного3 + аварийный
Выключили аварийный 192.0.2.5580 платящих без аварийного, никто не заметил2120 без аварийного, никто не заметил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, шарды
Серверов133
Дополнительных адресов044
В месяц10 €38 €38 €
Без связи, если адреса утёкшей конфигурации заблокируют12012040

Если шард разросся, его делят, переводя часть людей на новые адреса. Это делают редко и вручную.

Чего шарды не решают

вопрос из залаМожно купить адрес, на который хостер не сможет претендовать?

Почти нет. «Купленный отдельно» адрес у облачного провайдера всё равно его адрес, оформленный отдельной услугой, и он может его отозвать. Разница в том, что тогда не придётся пересоздавать сервер. Собственный блок /24 получают через регионального регистратора и его посредников (LIR) или берут на вторичном рынке: свободных IPv4 давно нет. Анонсировать его можно у хостера, который это позволяет, но и тогда хостер управляет маршрутизацией и машиной. А свой /24, попавший в блокировку, остаётся заблокированным у любого хостера.

вопрос из залаМожно настроить сервер так, чтобы хостер не понял, что это VPN?

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

справкаСловарик
IP-адрес
Номер сервера в интернете, например 203.0.113.17.
Подсеть /24
Блок из 256 адресов с одинаковым началом. Самый мелкий блок, который сети маршрутизируют отдельно.
Порт
Номер «двери» на адресе. Блокировка адреса закрывает все порты.
Точка подключения
Адрес, порт и протокол вместе; в приложении выглядит как «сервер». В конфигурации — outbound.
Шард
Группа людей со своим набором адресов. Потеря этих адресов задевает только её.
Общий профиль
Раскладка, при которой каждый пользователь получает все адреса сервиса.
Протокольный резерв
Несколько протоколов (например, TCP и UDP) на одном адресе. Защищает от поломки протокола, не от блокировки адреса.
Аварийный адрес
Адрес, которым пользуются, только когда все основные адреса шарда не работают.
Когорта
Пробный шард, который набирают до лимита или за день и потом закрывают для новых.
Перекрытие
Замена адреса, при которой новый сначала добавляют рядом со старым, а старый убирают позже.
справкаИсточники