release: prepare 0.2.0 for sing-box 1.14
This commit is contained in:
+51
-70
@@ -2,97 +2,78 @@
|
||||
|
||||
## Границы ответственности
|
||||
|
||||
Hysteria2 URI содержит только переносимые реквизиты VPN:
|
||||
Hysteria2 URI содержит переносимые реквизиты: auth, hostname/ports, SNI,
|
||||
`insecure`, тип obfs и obfs password. Production HY2XS выдаёт Gecko URI.
|
||||
|
||||
- authentication;
|
||||
- hostname и port/port ranges;
|
||||
- SNI и `insecure`;
|
||||
- `salamander` и obfs password.
|
||||
|
||||
`policy.json` содержит локальную инфраструктурную политику:
|
||||
|
||||
- `eth0` — upstream;
|
||||
- `eth1` — VPN LAN;
|
||||
- `tun-sb0`, `172.19.0.1/30`, MTU 1400;
|
||||
- TUN routes, nftables marks и rule/table indexes;
|
||||
- bootstrap DNS и DoH через `hy2-out`;
|
||||
- bandwidth hints и healthcheck.
|
||||
|
||||
Renderer не патчит существующий JSON. Полная конфигурация каждый раз строится
|
||||
из typed model. Это устраняет config drift и исторические endpoint `/32`.
|
||||
`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 parsing / schema validation
|
||||
├─ exact sing-box version and build-tag gate
|
||||
├─ deterministic render
|
||||
├─ secure candidate in /etc/sing-box
|
||||
└─ sing-box check -c candidate
|
||||
├─ strict validation
|
||||
├─ exact 1.14.0 + build-tag gate
|
||||
├─ renderer_1_14_0
|
||||
└─ sing-box check на private candidate
|
||||
│
|
||||
▼
|
||||
redacted comparison
|
||||
│
|
||||
unchanged ─────── changed
|
||||
│ │
|
||||
▼ ├─ last-good backup
|
||||
no restart ├─ atomic replace
|
||||
unchanged ───── changed
|
||||
│ │
|
||||
▼ ├─ проверка provenance текущего config
|
||||
state.json ├─ versioned last-good backup
|
||||
├─ atomic replace
|
||||
├─ systemctl restart
|
||||
└─ bounded local connectivity healthcheck
|
||||
│
|
||||
fail ┴ success
|
||||
│ │
|
||||
▼ ▼
|
||||
rollback state.json
|
||||
└─ bounded healthcheck
|
||||
```
|
||||
|
||||
Все операции изменения сериализованы `flock`-совместимой блокировкой. Поэтому
|
||||
ручной `import` и запоздалый event от systemd.path не могут применять два
|
||||
candidate одновременно.
|
||||
Первое применение после чистой установки не создаёт `last-good`: предыдущего
|
||||
управляемого конфига нет. При следующих изменениях backup разрешён только если
|
||||
SHA установленного config совпадает со state этого же релиза и sing-box 1.14.0.
|
||||
|
||||
## Почему endpoint IP не нужен
|
||||
## Gecko и DNS
|
||||
|
||||
Outbound сохраняет DNS hostname и содержит `bind_interface=eth0`. В 1.13.19
|
||||
`route.auto_detect_interface` не применяется к outbound с явным
|
||||
`bind_interface`. Bootstrap DNS также привязан к `eth0`. Endpoint IP поэтому не
|
||||
является частью TUN policy.
|
||||
Renderer добавляет для Gecko `min_packet_size=512` и
|
||||
`max_packet_size=1200`. Эти параметры являются частью локального HY2XS
|
||||
compatibility profile и не читаются из URI.
|
||||
|
||||
После смены A-записи следующая Hysteria2-сессия разрешает имя заново через
|
||||
`bootstrap-dns`. `doctor` дополнительно проверяет, что текущие A-записи не
|
||||
попали в exclusions.
|
||||
В sing-box 1.14.0 TUN по умолчанию использует `dns_mode=hijack`, что меняет
|
||||
настройки интерфейса и platform-level interception. Проект явно задаёт
|
||||
`dns_mode=disabled` и сохраняет собственное route action `port 53 ->
|
||||
hijack-dns`. Bootstrap UDP DNS привязан к `eth0`; remote DoH использует detour
|
||||
`hy2-out`.
|
||||
|
||||
## 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
|
||||
/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
|
||||
└── backups/ ограниченная история, 0700/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
|
||||
/etc/sing-box/config.json root:root 0600
|
||||
```
|
||||
|
||||
Service sing-box уже имеет `CAP_DAC_READ_SEARCH`, поэтому сохраняется текущая
|
||||
рабочая модель `root:root 0600`.
|
||||
Metadata не обеспечивает доверие от root-компрометации. Её задача — исключить
|
||||
случайное смешивание релизов и повреждённых backup-файлов.
|
||||
|
||||
Guard читает имена интерфейсов из того же policy и устанавливает всю nftables
|
||||
таблицу одной batch-транзакцией. Если новый ruleset некорректен, nft не оставляет
|
||||
систему с частично заменённой таблицей.
|
||||
## Граница установки
|
||||
|
||||
Package-managed drop-in добавляет для `sing-box.service` зависимости
|
||||
`Requires=` и `After=` от guard. Поэтому при совместном запуске ошибка guard
|
||||
блокирует старт sing-box. Уже активный oneshot не является watchdog: ручное
|
||||
удаление nftables-таблицы обнаруживает `doctor`, но не systemd dependency.
|
||||
|
||||
## Версионная граница
|
||||
|
||||
В коде существует только `renderer_1_13_19.py`. Renderer для 1.14 не является
|
||||
пустой заготовкой: он появится только в отдельной миграции после аудита схемы,
|
||||
маршрутизации и полных интеграционных тестов.
|
||||
0.2.0 не содержит кода миграции 0.1.0. `debian/preinst` отклоняет in-place
|
||||
upgrade, а `postinst` отклоняет legacy policy/state или unmanaged
|
||||
`/etc/sing-box/config.json`. Same-release reinstall допускается, если state и
|
||||
config согласованы.
|
||||
|
||||
Reference in New Issue
Block a user