owner: группа docker убрана у сервисных пользователей
Linting / YAML Lint (push) Canceled after 0s
Linting / Ansible Lint (push) Canceled after 0s

- 20 приложений её не получают: контейнерами рулит ansible от root, а
  членство в группе docker равносильно root на хосте
- у gitea, miniflux и outline группа осталась — их backup.sh дампит базу
  через docker compose exec из-под самого приложения
- задача service-users-docker-group закрыта, остаток вынесен в новую
  backup-dump-without-docker-group
This commit is contained in:
av
2026-08-22 19:40:57 +03:00
parent 856bf72560
commit c5217607b1
27 changed files with 55 additions and 43 deletions
+1 -1
View File
@@ -17,13 +17,13 @@ _(sec-ревью)_ — три независимых security-ревью на м
## Высокий
- [Убрать группу `docker` у сервисных пользователей](service-users-docker-group.md) — `docker` = root на хосте; ~все app-аккаунты фактически root, изоляция «юзер на сервис» обнуляется _(sec-ревью)_
- [Изолировать/запаролить сессионный redis Authelia](authelia-redis-isolation.md) — стор сессий SSO в общей сети без пароля; запись в него = hijack SSO всех сервисов _(sec-ревью)_
- [Алерты на проблемные контейнеры](container-alerts.md) — wakapi крутился в restart-loop несколько дней незамеченным; healthcheck в compose + алерты Netdata
- [Никаких секретов в выводе плейбуков](no-secrets-in-playbook-output.md) — `inv pl` всегда с `--diff`, и каждая задача, рендерящая файл с секретом, печатает его в терминал; `no_log` стоит ровно в одном месте из четырнадцати
## Средний
- [Дампы бэкапов без группы `docker`](backup-dump-without-docker-group.md) — у miniflux/gitea/outline группа осталась: их backup.sh дампит через `docker compose exec` из-под самого приложения
- [Захардить мониторинг-стек (netdata / dozzle / goaccess)](harden-monitoring-stack.md) — netdata/dozzle: лишние привилегии + docker.sock + доверие Remote-User в общей сети; socket-proxy + monitoring_network _(sec-ревью)_
- [Закрыть calibre-web forward-auth и проверить дефолтные креды](calibre-forward-auth.md) — домен без forward_auth, защита на встроенной авторизации с дефолтом `admin/admin123` _(sec-ревью)_
- [Включить автообновления безопасности](security-autoupdates.md) — патчи openssh/libssl только вручную; окна в недели между CVE и фиксом _(sec-ревью)_
@@ -0,0 +1,33 @@
# Дампы бэкапов без группы `docker` у сервисных пользователей
**Приоритет:** средний
Группу `docker` (= root на хосте) убрали у всех сервисных пользователей, кроме
трёх: `miniflux`, `gitea`, `outline`. Их `backup.sh` делает `docker compose exec`
(pg_dump, `gitea dump`), а `files/backups/backup-all.py` запускает такие скрипты
через `su --login <app_user>`, то есть от имени самого приложения — без членства
в группе дамп упадёт.
Дампить снаружи докера нельзя: postgres порт не публикует, `gitea dump` живёт
только внутри контейнера.
Варианты, как развязать:
- **A. sudo-обёртка на дамп.** Плейбук кладёт `/usr/local/sbin/backup-<app>-dump.sh`
(root:root, 0755 — сам app_user его не перепишет) с единственным
`docker compose exec …`, в sudoers — `<app_user> ALL=(root) NOPASSWD:` ровно на
этот файл, а `backup.sh` дёргает его через `sudo`. Пользователь получает право
на одну фиксированную команду вместо права на весь докер. Механизм в проекте
уже обкатан: так `playbook-backups.yml` разрешает `primary_user` запускать
`backup-all.py`.
- **B. root-скрипты в оркестраторе.** Новый контракт в `backup-all.py`: если у
приложения есть `backup-root.sh` с владельцем root — запускать его без `su`.
Механизм один на всех, но от root пойдёт скрипт целиком, включая
`keep-files.py`, и дампы станут root-овыми файлами в директориях приложения.
- **C. оставить как есть** — три аккаунта как осознанное исключение,
задокументированное в плейбуках.
Предпочтение на момент записи — A.
Связано: playbook-miniflux.yml, playbook-gitea.yml, playbook-outline.yml,
files/*/backup.template.sh, files/backups/backup-all.py.
@@ -1,20 +0,0 @@
# Убрать группу `docker` у сервисных пользователей
**Приоритет:** высокий
Все приложения заводят системного пользователя с `owner_extra_groups: ["docker"]`
(во всех `playbook-*.yml`), но docker.sock реально монтируют только netdata и
dozzle. Членство в группе `docker` эквивалентно root на хосте (`docker run -v
/:/host`), поэтому выделенные «непривилегированные» аккаунты (authelia, outline,
gitea и т.д.) фактически все имеют root — изоляция «пользователь на сервис», ради
которой их и заводили, обнуляется. Контейнерами рулит Ansible от root (become),
сервисам группа не нужна. Убрать `docker` из `owner_extra_groups` у всех, кроме
тех, кому он действительно нужен для самостоятельного управления своим compose (и
тем — лучше через socket-proxy). За `primary_user` группу оставить для ручных
операций (`inv ssh`).
Из sec-ревью (fable, 2026-07-13). Усиливает риск из серии `secrets-file-*`
(секреты в `environment:` контейнеров): членство в группе `docker` — как раз тот
доступ, которым такие переменные и вычитываются.
Связано: все playbook-*.yml (owner_extra_groups), roles/owner, playbook-docker.yml.