Ротация gRPC-путей
Содержание
Давно было в планах — и вот, наконец, свершилось.
В нашей архитектуре самый критический участок — это соединение между entry-нодой и core-нодой. Это трансграничный канал: именно он пересекает периметр, на который направлено повышенное внимание систем DPI.
VLESS поверх gRPC — сильная комбинация. Трафик практически неотличим от обычного HTTPS: TLS с валидным сертификатом, HTTP/2, браузерный TLS-фингерпринт. Со стороны это выглядит как обращение к обычному веб-сервису. Распознать его по сигнатурам практически невозможно.
Но «практически неотличим» не означает «невозможно вычислить».
Даже если содержимое трафика зашифровано и протокол замаскирован, остаются метаданные: кто, куда, как часто, как долго. Постоянное соединение по одному и тому же gRPC-пути на одном хосте — это паттерн. Даже для легитимного gRPC-микросервиса это выглядит подозрительно: реальные сервисы обычно обращаются по разным эндпоинтам.
Если путь не меняется неделями — это маркер. Статистический анализ может выделить такое соединение из общего потока.
Решение: менять gRPC serviceName автоматически, с заданной периодичностью. Каждый новый путь — случайно сгенерированная строка. Со стороны это выглядит как активность различных сервисов и пользователей одного хоста.
Я долго откладывал реализацию, но сегодня руки наконец дошли.
В минимальной реализации это bash-скрипт на core-ноде, который запускается по systemd timer. Скрипт генерирует новый случайный путь, обновляет конфигурации Nginx и Xray на core-ноде, а затем по SSH пушит изменение outbound-пути на каждую entry-ноду.
Важный момент: клиентская сторона не затрагивается. Путь ротируется только на внутреннем участке entry→core. Клиентам не нужно ничего перенастраивать — они продолжают подключаться к entry-ноде по прежнему адресу.
Текущие ограничения #
На короткие секунды в момент ротации связь может пропадать — сервисы перезагружаются. Клиент переподключается автоматически, но разрыв заметен.
В перспективе мы перейдем на Xray gRPC API (hot reload). Это позволит менять пути без перезагрузки сервисов — ротация станет бесшовной, без разрыва соединения.
Сейчас ротация настроена на каждый час. Практика покажет, приносит ли это ощутимые неудобства на клиенте. Если нет — будем увеличивать интервал или перенесем время ротации на периоды наименьшей активности.