montana/Russian/Network/РОЛЬ_АРХИТЕКТОР_СЕТИ.md
2026-05-28 23:22:19 +03:00

67 lines
8.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Сеть Montana — Роль: Архитектор сети
**Версия роли:** 1.0.0
**Назначение:** проектирование и эксплуатация **сетевого слоя доступа** Montana — точки входа, Reality-фронты, каскад, выходы по странам, failover, DNS, подписка `montana.quest/vpn/sub`.
Это **не** архитектор протокола (тот живёт в `Протокол/` и отвечает за консенсус/TimeChain). Здесь — инфраструктура доступа поверх протокола: как пользователь из-под цензуры доходит до сети и выходит в нужной стране.
---
## Главный принцип (нерушимый)
**Любое изменение «под капотом» делается так, чтобы сеть продолжала работать по той же подписке и не требовала лишних действий от пользователя.**
1. **Тот же контракт подписки.** `montana.quest/vpn/sub` и хосты в выданных ссылках (`de.montana.quest` и т.д.) стабильны. Инфраструктуру можно перестраивать только так, чтобы **уже выданные** vless-ссылки продолжали работать.
2. **Ноль действий от пользователя.** Никакого переимпорта подписки, смены конфига, ручного переподключения. Переключения — на уровне DNS/маршрутизации, прозрачно для клиента.
3. **Контроль до и после.** Перед правкой снять контрольную точку, после — повторить. Контроль = `curl -s -o /dev/null -w '%{http_code}' https://montana.quest/vpn/sub` (200) + резолв точки входа + Reality-рукопожатие фронта.
Нарушение этого принципа (пользователь вынужден что-то делать, или подписка/связь падает) = методологический сбой, равный поломке прод-сети.
---
## Инварианты сети
- **[N-1] Фиксированный контракт подписки.** Хосты и ключи в выданной подписке стабильны; перестройка инфраструктуры не ломает существующие ссылки.
- **[N-2] Прозрачное переключение.** Failover/смена фронта = переезд A-записи **фиксированного** хоста (`de.montana.quest`), а не смена хоста/ключа в подписке. Все фронты в цепочке предъявляют клиенту **одинаковые** Reality-параметры (UUID-набор / PBK / SID / SNI), иначе переключение рвёт сессии.
- **[N-3] Health-check по реальному сервису.** Живость фронта = успешное **Reality-рукопожатие**, не ICMP и не голый TCP-порт. nginx или иной сервис, отвечающий на :443, «живым фронтом» не считается (это уже держало мёртвую точку входа как рабочую).
- **[N-4] Детерминированный leader-election по упорядоченной цепочке** фронтов: «я мастер, если все, кто выше меня в цепочке, мертвы»; авто-уступка старшему при его восстановлении. (Адаптация «Тройного зеркала» с health-check по [N-3].)
- **[N-5] Домашний вход — самомаскировка под реальный домен на том же IP** (SNI = IP = cert), не под чужой CDN. Избегать корреляции SNI↔IP, которой DPI ловит Reality на иностранном CDN с локального IP.
- **[N-6] Атомарность и откат.** Правки живого :443 / xray / nginx: бэкап → `xray -test` / `nginx -t` → атомарный своп → проверка → **откат при провале**. Без отката хирургию на живом фронте не делать.
- **[N-7] Слепок сети** (`_internal-private/NETWORK-STATE-RUNBOOK.md`) обновляется и версионируется **только по явной команде автора**.
- **[N-8] Никаких IP в публичных артефактах.** Город + хостинг — да; IP — только в Cloudflare DNS и Keychain.
- **[N-9] Для мастера обязателен настроенный резерв.** Единая точка отказа без авто-failover недопустима, когда весь трафик идёт через один фронт.
---
## Что взято из «Тройного зеркала» (003_ТРОЙНОЕ_ЗЕРКАЛО)
- **Упорядоченная цепочка + детерминированный выбор лидера** — для точки входа: `[Москва → Франкфурт → Хельсинки]`. Первый живой в цепочке владеет `de.montana.quest`. Авто-failover + авто-уступка.
- **Малый интервал проверки** (порядок 5 с) + быстрый TTL DNS (60 с) → переключение ≈ детект + TTL.
- **Принципиальная правка относительно документа:** health-check НЕ по ICMP/TCP:22/TCP:443 (как в документе), а по Reality-рукопожатию — иначе ложно-живой фронт. См. [N-3].
- Breathing-sync ключей/манифеста — уже реализован таймерами, для failover входа не требуется.
---
## Топология (детали — в слепке)
Точка входа сейчас: `de.montana.quest → Франкфурт` (мастер), каскад к выходам по cascade-UUID, подписку отдаёт генератор Python. Полная топология, ключи, DNS, причины падений и процедуры восстановления — в `_internal-private/NETWORK-STATE-RUNBOOK.md` (внутренний, с IP).
### Готовность Москвы как мастера (домашний вход для РФ)
Москва (Timeweb RU) достаёт все выходы с низкой задержкой и не режется домашними РФ-провайдерами → топология «отечественный вход → заграничный выход» рабочая. Требования к переводу: совмещение VPN и сайта на :443 через самомаскировку под `montana.quest` (own-key, dest=локальный nginx, [N-5]); подписка несёт ключ Москвы; Франкфурт — зеркальный бэкап с тем же прикрытием ([N-2]); переключение по Reality-проверке ([N-3]). Узкое место/точка отказа смещается на Москву — резерв обязателен ([N-9]).
---
## Процедуры
**Контрольная точка (до и после любой правки):**
```
curl -s -o /dev/null -w '%{http_code}\n' https://montana.quest/vpn/sub # ждём 200
dig +short de.montana.quest @1.1.1.1 # точка входа жива
# Reality-рукопожатие фронта (из внешней точки):
echo | openssl s_client -connect de.montana.quest:443 -servername <masq-sni> 2>/dev/null | grep 'Verify return'
```
**Атомарный своп живого :443:** бэкап конфига → собрать новый → `xray -test` / `nginx -t` → освободить/занять порт → проверить владельца :443 и контрольную точку → при любом провале вернуть бэкап и старый сервис.
**Перед назначением фронта мастером:** проверить `<кандидат> → все выходы` (TCP/Reality), ресурсы (диск/RAM/load), валидность ключа и сертификата прикрытия.