Skip to main content

03 — Control plane ↔ клиент

Как control plane общается с клиентом после первой авторизации: доставка по публичной сети, подписочный сервис, миграция региона как перенос пира, и роль Telegram-ассистента.

Доверенный якорь → доставка по публичной сети

После первой авторизации у клиента есть доверенный якорь: либо уже поднятый туннель, либо device-credential, выданный control plane при онбординге. Именно он, а не MDM, становится каналом для последующих изменений.

Значит: конфиги можно доставлять по публичной сети напрямую — по TLS, с проверкой пер-девайс токена/credential. MDM — лишь один из способов «тихо применить»; где есть свой агент или подписочный клиент, MDM не нужен (см. файлы 02, 06).

Control plane как subscription-сервер

Для sing-box (файл 05) control plane играет роль сервера подписки. По сути это небольшой HTTP-сервис (в твоём идиоме — FastAPI, как MetricForge):

  1. принимает запрос на персональный URL с HTTP Basic / токеном;
  2. валидирует device-credential, находит клиента в БД;
  3. рендерит per-device JSON: подставляет приватный ключ клиента, его pool-IP, endpoint и серверный pubkey текущего региона, правила маршрутизации;
  4. ставит управляющие заголовки ответа:
    • profile-update-interval — как часто клиент перечитывает подписку;
    • subscription-userinfo: upload=…; download=…; total=…; expire=… — клиент покажет пользователю срок/квоту;
  5. отдаёт по TLS.

Миграция региона на этой стороне — просто ветка шаблона, отдающая endpoint другого региона. Клиент подтянет на следующем обновлении.

Миграция региона — это перенос пира, а не смена endpoint

Самая частая ошибка в рассуждениях: «поменяем IP endpoint в конфиге». В модели B (файл 01) при смене региона меняются Address, Endpoint и Peer PublicKey (серверный ключ в каждом регионе свой). А главное — клиента нужно зарегистрировать пиром на новом сервере и снять со старого. Порядок критичен, потому что в момент переключения активный туннель рвётся:

1. PROVISION  — завести пира клиента на НОВОМ региональном сервере
(его pubkey должен оказаться там ДО переключения)
2. PUSH — отдать новый конфиг (MDM-пуш или обновлённая подписка)
3. CONFIRM — дождаться рукопожатия от этого pubkey на новом сервере
(latest-handshake), т.е. подтверждаем по WG-серверу, НЕ по ответу MDM
4. CLEANUP — только теперь снять пира со СТАРОГО сервера

Поменяешь местами provision и push — клиент прилетит на сервер, который его не знает, handshake не пройдёт. Снимешь старого пира до confirm — отрежешь рабочий путь раньше, чем поднялся новый.

Ключ клиента при миграции

В модели B приватный ключ клиента на смене региона не ротируем — переиспользуем ту же пару, просто регистрируем существующий pubkey на новом сервере. Меняется только серверная сторона пира. Ротацию ключа клиента оставляем на re-issue и компрометацию (файл 01).

Консистентность состояния

Чтобы миграция и отзыв не оставляли мусор, control plane обязан вести peer_installations — на каких серверах сейчас стоит пир каждого клиента. Тогда:

  • CLEANUP точно знает, откуда снимать;
  • revoke снимает пира со всех инсталляций;
  • можно периодически сверять БД с реальным состоянием серверов (reconcile-петля) и удалять сиротские пиры.

Telegram-ассистент

Telegram здесь — не канал доставки конфигов (см. предупреждение ниже), а управляющий слой:

  • уведомления: «твой VPN мигрирует в регион 5»;
  • подтверждение/аппрув миграции, второй фактор;
  • триггер действий;
  • «пинок» на iOS: «профиль обновлён, открой приложение, чтобы применить» — закрывает то, что iOS не делает в фоне (ненадёжное фоновое автообновление подписки, файл 05).

Почему не возить конфиги через Telegram: облачные чаты и сообщения ботов не end-to-end (ключи у Telegram, E2E только в Secret Chats, а боты в них не участвуют). WG-приватник, посланный ботом, ложится на сторонний сервер и оседает в истории чата. Поэтому сам конфиг — по одноразовой TLS-ссылке на control plane, а Telegram несёт только ссылку/уведомление/аппрув.

Грабли

  • Подтверждай миграцию по WG-серверу, а не по ответу MDM.
  • Соблюдай порядок provision → push → confirm → cleanup.
  • Не ротируй ключ клиента на каждой миграции — только на re-issue.
  • Веди peer_installations и делай reconcile.
  • Telegram — для уведомлений и ссылок, не для тела конфига.