Files
singbox_glue/docs/architecture.md
T

96 lines
5.2 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.
# Архитектура
## Границы ответственности
Hysteria2 URI содержит переносимые реквизиты: auth, hostname/ports, SNI,
`insecure`, тип obfs и obfs password. Новые production-установки HY2XS получают
Gecko URI. Salamander остаётся явно согласуемым compatibility fallback.
`policy.json` хранит локальную инфраструктуру: `eth0`, `eth1`, TUN CIDR и MTU,
route exclusions, таблицу 2022, marks, NFQUEUE, DNS, bandwidth и healthcheck.
Renderer никогда не патчит старый JSON, а строит полный deterministic config из
typed model.
## Поток применения
```text
URI + policy
├─ strict validation
├─ exact 1.14.0 + build-tag gate
├─ renderer_1_14_0
└─ sing-box check на private candidate
current отсутствует ── current существует
│ │
│ provenance gate
│ │
│ unchanged ───── changed
│ │ │
│ ▼ ├─ versioned last-good backup
│ state.json │
└────────────────────────────────┼─ atomic replace
├─ systemctl restart
└─ bounded healthcheck
```
Первое применение после чистой установки не создаёт `last-good`: предыдущего
управляемого конфига нет. При следующих изменениях backup разрешён только если
SHA установленного config совпадает со state этого же релиза и sing-box 1.14.0.
Побайтовое совпадение с candidate не доказывает ownership: существующий config
без такого state отклоняется и не «усыновляется» контроллером.
## Gecko и DNS
Renderer добавляет для Gecko `min_packet_size=512` и
`max_packet_size=1200`. Эти параметры являются частью локального HY2XS
compatibility profile и не читаются из URI.
Renderer явно задаёт штатный для sing-box 1.14.0 `dns_mode=hijack`. Поле
`dns_address` не задаётся: sing-box выводит IPv4 DNS address `172.19.0.2` как
следующий адрес после `172.19.0.1/30`, автоматически связывает его с DNS module
и при `auto_redirect=true` устанавливает nftables DNAT для TCP/UDP 53. Поэтому
отдельного route action `hijack-dns` в generated config нет.
Bootstrap UDP DNS привязан к `eth0`; remote DoH использует detour `hy2-out`.
Собственный outbound sing-box исключается из auto-redirect по output mark, что
необходимо подтвердить privileged Linux acceptance без bootstrap recursion.
Platform hijack не создаёт DNS listener на локальном LAN-адресе шлюза: трафик к
такому адресу попадает в kernel `local` table раньше пользовательских rules.
Если DHCP должен выдавать сам gateway как DNS server, требуется отдельный
listener/service, который не входит в контракт 0.2.0.
## Endpoint routing
Hysteria outbound хранит hostname и `bind_interface=eth0`, а его
`domain_resolver` указывает на bootstrap DNS через `eth0`. Публичный IP сервера
не добавляется в `route_exclude_address`; смена A-записи не требует изменения
policy.
## Файловая модель
```text
/etc/vpn-egress/ root:root 0700
├── policy.json root:root 0600
└── hysteria2.uri root:root 0600
/var/lib/vpn-egress/ root:root 0700
├── state.json без секретов, 0600
├── last-good.json содержит secrets, 0600
├── last-good.meta.json версия и SHA-256, 0600
└── backups/ config + соседний .meta, 0700/0600
/etc/sing-box/config.json root:root 0600
```
Metadata не обеспечивает доверие от root-компрометации. Её задача — исключить
случайное смешивание релизов и повреждённых backup-файлов.
## Граница установки
0.2.0 не содержит кода миграции 0.1.0. `debian/preinst` отклоняет установку
поверх любого другого релиза, а `postinst` отклоняет legacy policy/state или
unmanaged `/etc/sing-box/config.json`. Same-release reinstall 0.2.0 допускается,
если state и config согласованы.