107 lines
3.7 KiB
Markdown
107 lines
3.7 KiB
Markdown
# systemd and firewall
|
||
|
||
## Цель документа
|
||
|
||
Зафиксировать базовый systemd/firewall слой под новую install model.
|
||
|
||
## systemd: Hysteria2
|
||
|
||
Базовые требования:
|
||
- отдельный unit `hysteria-server.service`
|
||
- отдельный пользователь `hysteria`
|
||
- автозапуск после reboot
|
||
- restart policy для падений
|
||
|
||
Базовый ExecStart:
|
||
```bash
|
||
/usr/local/bin/hysteria server -c /etc/hysteria/config.yaml
|
||
```
|
||
|
||
## systemd: HY2XS admin
|
||
|
||
Базовые требования:
|
||
- отдельный unit `hy2xs-admin.service`
|
||
- запуск от `User=hy2xs-admin`, не от root
|
||
- отдельный install dir
|
||
- отдельный data dir
|
||
- отдельный жизненный цикл от Hysteria
|
||
|
||
Рекомендуемый hardening:
|
||
- `NoNewPrivileges=true`
|
||
- `PrivateTmp=true`
|
||
- `UMask=0077`
|
||
- `ProtectHome=true`
|
||
- `ProtectSystem=strict`
|
||
- `ReadOnlyPaths=/etc/hysteria/config.yaml`
|
||
- `ReadWritePaths=/var/lib/hy2xs-admin /var/log/hy2xs`
|
||
- `RestrictAddressFamilies=AF_INET AF_UNIX`
|
||
- `SystemCallArchitectures=native`
|
||
- `LockPersonality=true`
|
||
|
||
Для `hysteria-server.service` также обязателен sandbox-контур:
|
||
- `ProtectSystem=strict`
|
||
- `ReadOnlyPaths=/etc/hysteria/config.yaml`
|
||
- `ReadWritePaths=/var/lib/hysteria`
|
||
- `CapabilityBoundingSet=CAP_NET_BIND_SERVICE`
|
||
|
||
Важно:
|
||
- HY2XS admin не должен запускаться как часть unit Hysteria
|
||
- unit-файлы не должны быть склеены
|
||
|
||
## Базовая firewall-модель
|
||
|
||
Нужно разрешить:
|
||
- UDP-порт Hysteria2
|
||
- TCP-порт SSH
|
||
- established/related traffic
|
||
|
||
IPv4-only policy:
|
||
- использовать `table ip`, а не `table inet`;
|
||
- IPv6 правила не добавлять;
|
||
- UI работает только на `127.0.0.1` в production baseline.
|
||
|
||
## Firewall modes
|
||
|
||
`HY2XS_FIREWALL_MODE=managed`:
|
||
- orchestrator управляет baseline nftables.
|
||
- существующий `foreign` entrypoint блокирует install/reconfigure (fail-fast).
|
||
|
||
`HY2XS_FIREWALL_MODE=takeover`:
|
||
- явный destructive takeover.
|
||
- использовать только после ручной проверки хоста.
|
||
|
||
`HY2XS_FIREWALL_MODE=external`:
|
||
- orchestrator не модифицирует nftables.
|
||
- оператор полностью управляет firewall вручную.
|
||
|
||
`HY2XS_FIREWALL_MODE=off`:
|
||
- firewall-слой оркестратора отключён.
|
||
- `--skip-firewall` эквивалентно runtime-отключению на время операции.
|
||
|
||
После staged-проверки можно включать default policy `drop`.
|
||
|
||
## Порядок применения
|
||
|
||
1. Подготовить candidate-файл (`/etc/nftables.d/hy2xs.nft`).
|
||
2. Проверить `nft -c -f`.
|
||
3. Создать rollback timer.
|
||
4. Применить candidate и проверить SSH/Hysteria/UI.
|
||
5. При успехе отменить rollback timer.
|
||
6. При провале — rollback.
|
||
|
||
## Что не делаем
|
||
|
||
В baseline не делаем:
|
||
- port hopping
|
||
- сложную динамическую firewall-логику
|
||
- смешение UI-портов и публичного транспортного порта в один firewall-контур без правил
|
||
|
||
## Инварианты
|
||
|
||
Система считается корректной, если:
|
||
1. Hysteria и HY2XS admin работают отдельными systemd unit
|
||
2. Hysteria слушает нужный UDP-порт
|
||
3. SSH не ломается после применения firewall
|
||
4. firewall-политика не противоречит listen policy
|
||
5. после reboot оба нужных сервиса стартуют корректно
|