Реализован production-hardening по fix1: env/reconfigure, IPv4-only, TLS, secrets, firewall, docs

This commit is contained in:
2026-04-26 07:27:06 +05:00
parent 2b4a45ad23
commit 3fccd5c442
109 changed files with 1773 additions and 569 deletions
+9 -1
View File
@@ -59,11 +59,18 @@ Hysteria2 — основной транспортный компонент се
## TLS
Требования:
- нормальный домен
- production default: `acme`
- поддерживаемые режимы: `acme | file | self_signed_dev`
- `self_signed_dev` только для dev/lab
- корректный `server_name` / SNI на клиентах
- одна понятная TLS policy
- без смешивания нескольких несовместимых схем по умолчанию
Инварианты:
- `acme` -> только `acme` block в конфиге;
- `file` -> только `tls.cert`/`tls.key` block;
- `self_signed_dev` -> только dev сценарии.
## Auth policy
Для baseline выбирается одна предсказуемая auth-модель.
@@ -88,6 +95,7 @@ Hysteria2 — основной транспортный компонент се
- `/etc/hysteria/config.yaml`
- `/var/lib/hysteria/`
- `/etc/hy2xs/hy2xs.env`
- `/etc/hysteria/post-install.env`
## Серверные инварианты
+3
View File
@@ -57,6 +57,7 @@ Bundled H UI должна:
- поставляться внутри итогового пакета
- иметь свой install dir
- иметь свой data dir
- иметь rootless systemd unit (`hy2xs-admin`)
- запускаться отдельным systemd unit
- не требовать target-side build
@@ -76,6 +77,7 @@ Bundled H UI должна:
- Hysteria2 устанавливается install-оркестратором с official upstream
- Hysteria2 запускается отдельным `hysteria-server.service`
- HY2XS admin работает как operator UI и HTTP auth/traffic layer
- HY2XS admin не запускается от root
- смена версии Hysteria2 через UI отключена в baseline
- список upstream releases не является частью operator UI baseline
@@ -85,6 +87,7 @@ Bundled H UI должна:
- склеивать unit Hysteria и unit H UI в один сервис
- раздувать оркестратор из-за особенностей UI
- использовать HY2XS admin как updater бинаря Hysteria2
- использовать `JWT_SECRET` как `trafficStats.secret` для Hysteria API
## Что фиксировать в `post-install.env`
+10 -1
View File
@@ -9,7 +9,7 @@
В baseline этого пакета docs входит только следующее:
- установка Hysteria2
- установка HY2XS admin
- базовая настройка systemd / firewall / `post-install.env`
- базовая настройка systemd / firewall / `hy2xs.env` / `post-install.env`
- подготовка рабочего серверного окружения
## Что не входит в baseline
@@ -31,6 +31,15 @@
Но это не делает access layer частью install baseline.
## Публичный endpoint
В клиентской части используется только `public_host/public_port`.
Инварианты:
- `listen` и `public endpoint` разделены;
- в клиентских URL не используется `0.0.0.0`;
- проект остаётся IPv4-only.
## Почему это важно
Если смешать install baseline и delivery layer, документация начинает неверно обещать лишнее:
+20 -4
View File
@@ -21,10 +21,19 @@
Базовые требования:
- отдельный unit `hy2xs-admin.service`
- запуск от `User=hy2xs-admin`, не от root
- отдельный install dir
- отдельный data dir
- отдельный жизненный цикл от Hysteria
Рекомендуемый hardening:
- `NoNewPrivileges=true`
- `PrivateTmp=true`
- `ProtectHome=true`
- `ProtectSystem=strict`
- `ReadWritePaths=/var/lib/hy2xs-admin /var/log/hy2xs`
- `RestrictAddressFamilies=AF_INET AF_UNIX`
Важно:
- HY2XS admin не должен запускаться как часть unit Hysteria
- unit-файлы не должны быть склеены
@@ -36,14 +45,21 @@
- TCP-порт SSH
- established/related traffic
IPv4-only policy:
- использовать `table ip`, а не `table inet`;
- IPv6 правила не добавлять;
- UI-порт разрешать только с локального bind-host.
После staged-проверки можно включать default policy `drop`.
## Порядок применения
1. Добавить allow-правила.
2. Проверить, что SSH-сессия не теряется.
3. Проверить listen Hysteria-порта.
4. Только потом затягивать policy.
1. Подготовить candidate-файл (`/etc/nftables.d/hy2xs.nft`).
2. Проверить `nft -c -f`.
3. Создать rollback timer.
4. Применить candidate и проверить SSH/Hysteria/UI.
5. При успехе отменить rollback timer.
6. При провале — rollback.
## Что не делаем
+16 -14
View File
@@ -18,14 +18,15 @@
## Главная роль оркестратора
Оркестратор работает **только на target machine** и умеет только:
- выполнить первичную установку
Оркестратор работает **только на target machine** и умеет:
- выполнить первичную установку (`install`)
- выполнить явную реконфигурацию (`reconfigure --dry-run|--apply`)
- разложить bundled UI
- скачать Hysteria2 из official upstream
- создать базовые конфиги
- создать/обновить конфиги
- создать unit-файлы
- применить baseline firewall
- создать `post-install.env`
- применить staged firewall
- создать `post-install.env` и runtime env-файл
## Оркестратор не умеет
@@ -112,15 +113,16 @@
## CLI baseline
Допустимые флаги:
- `--non-interactive`
- `--domain`
- `--port`
- `--ssh-port`
- `--skip-firewall`
- `--skip-start`
- `--ui-port`
- `--ui-bind-host`
Команды:
- `install --package-dir <path> [--config /etc/hy2xs/hy2xs.env]`
- `reconfigure --package-dir <path> --config /etc/hy2xs/hy2xs.env --dry-run`
- `reconfigure --package-dir <path> --config /etc/hy2xs/hy2xs.env --apply`
Инварианты:
- только IPv4 bind/listen;
- TLS modes: `acme | file | self_signed_dev`;
- `trafficStats.secret` отдельный от `JWT_SECRET`;
- при `reconfigure --apply`: backup -> staged apply -> smoke -> rollback on fail.
## Что не реализовывать
+21 -10
View File
@@ -1,12 +1,20 @@
# Post-install env
# Runtime env и post-install snapshot
## Цель документа
Зафиксировать `post-install.env` как компактный deploy reference file после первичной установки.
Зафиксировать двухслойную модель:
- editable runtime env: `/etc/hy2xs/hy2xs.env`
- generated deploy snapshot: `/etc/hysteria/post-install.env`
## Зачем нужен файл
После первичной установки оператору нужна одна точка, где видно:
После первичной установки оператору нужны:
1) runtime-файл, который оркестратор читает и валидирует;
2) snapshot-файл фактического deploy-состояния.
В snapshot видно:
- какой пакет был установлен
- какой build артефакт использован
- какой стек оркестратора применён
@@ -24,12 +32,15 @@
- не заменяет runtime-конфиги
- не превращает target в builder
## Рекомендуемый путь
## Рекомендуемые пути
```bash
/etc/hy2xs/hy2xs.env
/etc/hysteria/post-install.env
```
Оба файла должны иметь права `0600`.
## Минимальный набор переменных
### Deploy / package
@@ -73,18 +84,18 @@
- `HUI_INSTALL_DIR`
- `HUI_DATA_DIR`
## Как работать с файлом
## Как работать с файлами
Правильная модель:
1. оркестратор создаёт файл при первичной установке
2. оператор использует файл как reference/source-of-truth
3. при необходимости оператор вручную переносит изменения в реальные рабочие конфиги
4. затем оператор применяет изменения документированным способом
1. оркестратор создаёт `hy2xs.env` и `post-install.env` при установке;
2. оператор редактирует только `hy2xs.env`;
3. оператор запускает `reconfigure --dry-run`, затем `reconfigure --apply`;
4. оркестратор обновляет runtime и перезаписывает snapshot.
## Что нельзя делать
- сваливать туда временный мусор
- считать, что edit env автоматически меняет runtime
- считать, что edit env автоматически меняет runtime без `reconfigure --apply`
- использовать файл как замену настоящей конфигурации сервисов
## Пример
+13 -4
View File
@@ -25,21 +25,26 @@
3. bundled HY2XS admin раскладывается локально из пакета
4. создаются нужные каталоги
5. создаются systemd unit-файлы
6. создаётся `post-install.env`
7. baseline firewall применяется корректно
6. создаются `hy2xs.env` и `post-install.env` с правами `0600`
7. baseline firewall применяется корректно через staged mode
8. SSH остаётся доступным
9. `reconfigure --dry-run` выводит план изменений
10. `reconfigure --apply` применяет изменения и проходит smoke
## C. Runtime tests
1. `hysteria-server` active
2. `hy2xs-admin` active
3. UDP-порт слушается
4. HY2XS admin открывается по ожидаемому admin path
3. Hysteria слушает только IPv4 (`0.0.0.0:<udp_port>`)
4. HY2XS admin слушает ожидаемый `HY2XS_UI_BIND_HOST:<ui_port>`
5. тестовый совместимый клиент подключается
6. идёт реальный трафик
7. лимит 50/50 Mbps соблюдается при согласованной клиентской конфигурации
8. reboot не ломает baseline
9. Hysteria2 управляется systemd unit, а не внутренним updater'ом admin panel
10. нет IPv6 listen (`[::]`) для Hysteria/HY2XS admin
11. `trafficStats.secret` не равен `JWT_SECRET`
12. bootstrap admin secret существует и имеет `0600`
## D. Negative tests
@@ -51,6 +56,8 @@
6. Hysteria upstream недоступен
7. firewall применился частично
8. install flow прерван посередине
9. попытка использовать `HY2XS_IPV6_ENABLED=true`
10. `HY2XS_PUBLIC_HOST=0.0.0.0`
## Acceptance criteria
@@ -64,3 +71,5 @@
6. оркестратор зафиксирован как Bun/TypeScript stack и поставляется как готовый install-артефакт
7. оркестратор не требует update / rollback / uninstall логики
8. Telegram/access layer не требуется для прохождения install acceptance
9. отсутствует production path для port hopping
10. UI не запускается от root
+15 -3
View File
@@ -9,16 +9,27 @@ PACKAGE_VERSION=0.1.0
ORCH_SOURCE_STACK=bun-typescript
ORCH_BUILD_MODE=bun-compile
ORCH_BUILD_ID=orch-build-20260413-001
ORCH_BUILD_ID=build-20260413-001
ORCH_ENTRYPOINT=/usr/local/lib/hy2xs/hy2xs-orchestrator
DEPLOY_DOMAIN=example.com
PUBLIC_HOST=example.com
PUBLIC_PORT=443
SSH_PORT=22
HY2XS_FIREWALL_ENABLED=true
HY2XS_FIREWALL_STAGED_APPLY=true
HY2_SOURCE=official-upstream
HY2_VERSION=v2.8.1
HY2_TLS_MODE=acme
HY2_ACME_EMAIL=admin@example.com
HY2_TLS_CERT_PATH=
HY2_TLS_KEY_PATH=
HY2_LISTEN_HOST=0.0.0.0
HY2_PORT=443
HY2_AUTH_MODE=http
HY2_AUTH_URL=http://127.0.0.1:8081/hui/hysteria2/auth
HY2_TRAFFIC_STATS_LISTEN=127.0.0.1:25413
HY2_OBFS_TYPE=salamander
HY2_OBFS_PASSWORD=CHANGE_ME
HY2_BANDWIDTH_UP_Mbps=50
@@ -27,9 +38,10 @@ HY2_IGNORE_CLIENT_BANDWIDTH=false
HY2_CONFIG_PATH=/etc/hysteria/config.yaml
HUI_ENABLED=true
HUI_FORK_REF=main
HUI_BUILD_ID=hy2xs-admin-build-20260413-001
HUI_FORK_REF=packaged
HUI_BUILD_ID=build-20260413-001
HUI_BIND_HOST=127.0.0.1
HUI_PORT=8081
HUI_INSTALL_DIR=/opt/hy2xs-admin
HUI_DATA_DIR=/var/lib/hy2xs-admin
HUI_LOG_DIR=/var/log/hy2xs-admin