Мультихоп
Концепция
Section titled “Концепция”Цепочка — упорядоченный список из N ≥ 2 нод: входная (entry), 0+ промежуточных (relay), выходная (exit). Клиент подключается к entry; дальше трафик идёт между нодами внутри инфраструктуры, в интернет выходит только exit.
flowchart LR
C[Клиент] -->|"клиентский инбаунд"| E[Entry · NL]
E -->|VLESS Reality| R[Relay · DE]
R -->|VLESS Reality| X[Exit · US]
X -->|freedom| I((Интернет))
Провайдер клиента видит только entry. Сайт назначения видит IP exit. Блокировка entry лечится заменой первого хопа без перестройки остального.
Модель
Section titled “Модель”Цепочка присоединяется к инбаунду, а не к клиенту: inbounds.chain_id направляет весь трафик этого инбаунда в цепочку (Инбаунды). Подписки и группы доступа о мультихопе не знают — «мультихоп-тариф» выражается группой доступа, содержащей инбаунды с цепочкой.
| Сущность | Поля |
|---|---|
chains |
name |
chain_hops |
chain_id, node_id, position (0 — первый после entry), port, 🔒 секрет хопа, 🔒 Reality keypair |
Entry-нода в chain_hops не входит — entry определяется инбаундами, ссылающимися на цепочку. Одна цепочка может обслуживать несколько entry-инбаундов на разных нодах.
Хопы — не инбаунды в смысле Инбаунды и профили: у них нет профиля, клиентов и групп доступа. Их серверная часть (инбаунд chain-in на relay/exit) рендерится из chain_hops напрямую при сборке desired state соответствующей ноды.
Протокол между хопами
Section titled “Протокол между хопами”VLESS + Reality — тот же стек, что для клиентов: трафик хопа неотличим от TLS к прикрытию (dest), сертификаты relay-нодам не нужны, отдельный код в агенте не нужен. Каждый хоп имеет собственный keypair, short_id и dest — одинаковый fingerprint на нескольких нодах создавал бы корреляцию, от которой мультихоп защищает.
Единственный «пользователь» инбаунда chain-in — секрет предыдущего хопа. Sniffing на chain-in выключен: внутри уже проксированный поток.
Рендер
Section titled “Рендер”Каждая нода получает свою часть цепочки в составе обычного desired state:
| Роль ноды | Что рендерится |
|---|---|
| Entry | Клиентский инбаунд (как обычно) + аутбаунд на хоп 0 + правило инбаунд → аутбаунд |
Relay i |
Инбаунд chain-in (секрет хопа i) + аутбаунд на хоп i+1 + правило |
| Exit | Инбаунд chain-in + правило chain-in → freedom |
Порядок применения между нодами не координируется: каждая нода сходится к своему состоянию независимо, reconciliation повторяет попытки. Пока не сошлись все ноды цепочки, трафик через неё не проходит — это видно по applied_revision участников; оркестровать «развёртывание с хвоста» и откаты не нужно (сравнение с императивной моделью — в Архитектуре).
Изменения и деградация
Section titled “Изменения и деградация”- Замена/вставка хопа — правка
chain_hops; ревизии всех затронутых нод инкрементируются, каждая применяет свой новый фрагмент. - Нода цепочки offline — цепочка помечается
degradedв UI (вычисляется из связности участников, не хранится). Трафик через мёртвый хоп не проходит; автопереключение на резервный relay — не MVP, но модель его допускает (заменаnode_idхопа). - Удаление цепочки — запрещено, пока на неё ссылаются инбаунды.
Ограничения
Section titled “Ограничения”Мультихоп защищает от одной точки наблюдения (провайдер клиента, один скомпрометированный узел). Не защищает от глобального наблюдателя, коррелирующего трафик entry и exit по таймингу и объёму. Каждый хоп добавляет RTT; через relay проходит трафик всех клиентов всех цепочек этого relay — учитывается в планировании ёмкости.