5.2 KiB
Архитектура
Границы ответственности
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.
Поток применения
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.
Файловая модель
/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 согласованы.