fix(security): harden diagnostics storage boundary

This commit is contained in:
2026-09-07 19:52:11 +05:00
parent af9f476658
commit a3445f79c5
12 changed files with 562 additions and 37 deletions
+5 -2
View File
@@ -349,9 +349,12 @@ hy2xs-orchestrator redact-config --config /etc/hysteria/config.yaml --out /root/
(`hy2xs-orchestrator diagnostics collect`), который собирается автоматически при
неудачной установке или реконфигурации. Бандл предназначен для передачи наружу,
поэтому попадающие в него `hy2xs.env`, `post-install.env` и `config.yaml`
редактируются перед упаковкой.
редактируются перед упаковкой. Готовый архив находится в
`/var/lib/hy2xs/diagnostics`, принадлежит `root:root` и имеет режим `0600`.
Сам каталог имеет режим `0700`; не ослабляйте его права и не переносите bundle
в `HY2XS_LOG_DIR`, доступный сервисному пользователю.
При отказе **до** начала применения изменений (`fatal_pre_apply`) бандл не
собирается: его сбор сам создал бы каталоги в `/var/log/hy2xs` на сервере,
собирается: его сбор сам создал бы каталог в `/var/lib/hy2xs/diagnostics` на сервере,
который мы обещали не трогать.
+10 -2
View File
@@ -254,7 +254,7 @@ preflight-ошибка со словом `nftables` приводила к отк
него нельзя ни при одном взведённом флаге, включая `stateTouched`. В этом
случае system rollback не выполняется, `install-state.json` не пишется,
diagnostics-бандл не собирается (его сбор сам создал бы каталоги в
`/var/log/hy2xs`).
`/var/lib/hy2xs/diagnostics`).
- `systemctl stop/disable` выполняется **только если текущая операция сама
развернула эти unit-файлы**.
@@ -695,7 +695,15 @@ Diagnostics не копирует env/YAML и не перенаправляет
редакцию и лишь затем записываются с режимом `0600`. Некорректный UTF-8 в
конфигурационном файле даёт безопасный маркер пропуска без исходных байтов.
Вывод каждой внешней команды ограничен 8 МиБ на поток и при усечении явно
помечается; архив создаётся сразу под `umask 077`.
помечается.
Staging и архив лежат только в `/var/lib/hy2xs/diagnostics`, а не в
service-writable `HY2XS_LOG_DIR`. Родитель проверяется через `lstat`: symlink,
не-root владелец, доступ на запись для группы/остальных или режим дочернего
каталога не `0700` останавливают сбор fail closed. Рабочий каталог получает
непредсказуемое имя через `mkdtemp`, archive path заранее резервируется через
эксклюзивный `open("wx")`, итоговый файл проверяется как обычный
`root:root 0600`. После успешной упаковки staging удаляется.
Это не косметика. Построчное правило `auth:\s*(.*)` подставляло маркер в
заголовок mapping'а и оставляло нетронутым вложенный
+9
View File
@@ -406,6 +406,15 @@
хвостовую пунктуацию; идемпотентен — регрессия на diagnostics-бандл, где
редактировались env и YAML, а `journal-admin.log` копировался как есть.
`orchestrator/test/diagnostics-storage.test.ts` отдельно фиксирует границу
привилегий: production path не входит в `HY2XS_LOG_DIR`, symlink и чужой
владелец отвергаются, режим root-каталога равен `0700`, рабочие каталоги
уникальны, а archive path резервируется эксклюзивно до запуска `tar`.
`orchestrator/test/package-meta-utf8.test.ts` проверяет соседнюю fail-closed
границу metadata: fallback разрешён только для отсутствующего файла; каталог
вместо файла и повреждённый UTF-8 пробрасываются как ошибка пакета.
## A7. Machine token в журналах (unit)
`apps/middleware/log_test.go` — запрос