Files
obsidian-vault/family/documents/vault-sync/2026-09-02-restore-privilege-scope.md
T

139 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
tags: [truenas, restore, incident, git, media, arr, permission]
created: 2026-09-02
status: diagnosed
---
# Incident 2026-09-02: Поломка прав uid 921/0000 после restore — масштаб и влияния
**Сводный инцидент-документ.** Родитель: `2026-08-31-syncthing-truenas-incident.md` (Syncthing). Здесь документируем подтверждённый масштаб той же поломки прав и её воздействие на git-sync (мак/Eagle) и медиа/arr-стек на TrueNAS.
**Корень (общий для всех):** после восстановления из бэкапа `/mnt/RED_2TB/storage/*` стал принадлежать **uid 921 = `transmission`** с правами `----------`/`d---------` (0000), вместо `truenas_admin` (950). Контейнеры, пользователи и git, работающие под другими uid, теряют доступ.
---
## 1. Git-sync obsidian на маке (Eagle) — СТОИТ (ahead 55)
**Симптом на `~/obsidian`:**
```
git status → ## main...nas/main [ahead 55]
git fetch/push → fatal: '/mnt/RED_2TB/storage/git/obsidian-vault.git' does not appear to be a git repository
```
**Причина (read-only проверка TrueNAS):**
```
/mnt/RED_2TB/storage/git d--------- 4 921 921
/mnt/RED_2TB/storage/git/obsidian-vault.git (permission denied — вложено в storage/git)
```
Папка `storage/git/` (внутри — bare repo `obsidian-vault.git`) с правами 0000 / owner 921. Git на маке (SSH-ключ жив, `CONN_OK` ✅) не может открыть bare repo → fetch/push падают → локальные 55 коммитов не уходят.
**Важно про механизм cron — НЕ Hermes cron, а launchd:**
- Агент: `~/Library/LaunchAgents/com.sync-vault.plist`
- Программа: `/Users/admin/scripts/sync-vault.sh`, `StartInterval = 300` сек (5 мин)
- Состояние: **активен** (`launchctl list``com.sync-vault`), `runs = 3762`, `last exit code = 0`
- `sync-vault-lib.sh` **умышленно глушит** недоступность remote: если `git fetch` падает → логирует и `exit 0`. Поэтому launchd показывает exit code 0 при фактически сломанном sync (`ahead 55`). Это **не** сбой cron — это корректное поведение скрипта, скрывающее dead remote.
- Системный crontab на маке пуст (`crontab -l` нет), `/etc/crontab` нет. Запуск — только через launchd `${LABEL}`.
**Связанные доки:** `family/how-to/vault-git-sync.md`, `family/how-to/obsidian-sync.md`.
---
## 2. Медиа-папки TrueNAS — сломаны (uid 921, d---------/drwx------)
Read-only проверка `ls -ld /mnt/RED_2TB/storage/`:
```
d--------- transmission transmission storage/Cartoons
d--------- transmission transmission storage/Downloads
d--------- transmission transmission storage/Movies
d--------- transmission transmission storage/Music
drwx------ transmission transmission storage/series
d--------- transmission transmission storage/shared
```
(отображается как `transmission` = uid 921 — тот же, что и в инциденте; права 0000/700 сломаны для внешних сервисов.) `Movies-Radarr`, `Series-Sonarr` — не существуют (старая схема, на TrueNAS актуальны только `storage/`-медиа).
Медиа-папки починки не проходили (в отличие от `obsidian`/`obsidian-syncthing`).
---
## 3. Arr/Jellyfin-стек на TrueNAS — выключен + не сможет работать из-за прав
**Факты:**
- В `docker ps -a` НЕТ ни radarr/sonarr/prowlarr/jellyfin контейнеров (ни запущенных, ни остановленных). Стек не пересоздавался после проблемного периода.
- Composes живут в `/mnt/RED_2TB/docker/arr/`: `docker-compose.yml` (prowlarr/radarr/sonarr/jellyfin), подпапки `prowlarr/ radarr/ sonarr/ jellyfin/ media-pipeline/`.
- `docker/arr/docker-compose.yml` монтирует `/mnt/RED_2TB/storage` в radarr/sonarr (rw) и jellyfin (`:ro`). При сломанных правах медиа-папок контейнеры не смогут читать/импортировать → пустая библиотека.
- **Работает только `transmission`** (Up 8 days), его compose отдельный: `/mnt/RED_2TB/docker/transmission/`. config владелец `transdamon`/911. RPC `transmission-remote` вернул `403 Forbidden` — auth вкл., статус торрентов извне без токена не читается.
**Чтобы запустить стек:** восстановить права медиа-папок `storage/` (150 и выше 950/нужный сервисный uid, rwX) → `cd /mnt/RED_2TB/docker/arr && docker compose up -d`.
**Дексо стек** — разделение ролей (см. `family/how-to/arr-stack-taiga.md`):
- Taiga (TrueNAS) = acquisition (transmission качает, arr добавляет)
- Kraken = serving (jellyfin на план-сервире). Jellyfin на TrueNAS — acquisition-side media storage, не primary serving.
---
## 4. Несвязанные находки (не трогала диагностика, для контекста)
- Контейнер `library-app` (`library`) в restart-loop: `FileNotFoundError: '/library/flibusta_fb2_local.inpx'` — это приложение полки книг Flibusta, монтирует `/mnt/RED_2TB/storage/Downloads/fb2.Flibusta.Net → /library`; INPX-файла на пути нет. Не связано с поломкой прав; ручной фикс только по запросу.
---
## Общий план (ИСПРАВЛЕН — НЕ выполнен, требует подтверждения)
> ⚠️ **2026-09-02 УТОЧНЕНО: `/mnt/RED_2TB/storage` — единый ZFS dataset `RED_2TB/storage` с `acltype=nfsv4`. НЕ ПОСIX.** Ранее планировалось `chown -R`/`chmod -R` — это **НЕВЕРНО** для TrueNAS SCALE с NFSv4 ACL. Права управляются **только** через `midclt call filesystem.setacl` (эквивалент TrueNAS UI → Datasets → `RED_2TB/storage` → Edit ACL → Apply recursively). `truenas_admin` = FULL_ADMIN в midclt → **root/sudo для setacl НЕ нужен** (проверено: `midclt call auth.me` → roles `FULL_ADMIN`).
### Диагноз по NFS4 ACL (что именно сломано)
Реальные ACL через `midclt call filesystem.getacl` у `storage`, `git`, `Downloads`, `Movies`, `Cartoons` **структурно ИДЕНТИЧНЫ рабочему `obsidian`**, но:
1. владелец **uid/gid = 921** (`transmission`) вместо правильного **950** (`truenas_admin`);
2. у записи `owner@` **обнулены `READ_DATA / WRITE_DATA / EXECUTE / APPEND_DATA / DELETE_CHILD`** (все в `false`) → POSIX-маска `d---------`.
Рабочий эталон (`obsidian`): uid/gid **950:950**, `owner@` полный, `group@` rwX (без WRITE_ATTRS/ACL/OWNER), `everyone@` — только attrs.
### Проверенная сигнатура midclt
```bash
# Filesystem-методы существуют (40, подтверждены 2026-09-02):
# filesystem.getacl / filesystem.setacl / filesystem.chown / filesystem.setperm
# setacl(schema): {path, uid, gid, dacl, nfs41_flags, acltype, options}
# options: {stripacl:bool, recursive:bool, traverse:bool, canonicalize:bool(default true),
# validate_effective_acl:bool(default true)}
# dacl: массив ACE {tag: owner@|group@|everyone@|USER|GROUP, id, type: ALLOW|DENY, perms, flags}
```
### Применение (скрипт готов на маке: `~/fix-storage-nfs4-acl.sh`)
Скрипт делает 3 этапа; применяется через `filesystem.setacl` с uid/gid + dacl + options.recursive/traverse:
```bash
# скопировать на TrueNAS и запустить (sudo не нужен):
scp ~/fix-storage-nfs4-acl.sh truenas_admin@mallexxx.duckdns.org:/tmp/
ssh truenas_admin@mallexxx.duckdns.org 'bash /tmp/fix-storage-nfs4-acl.sh'
```
Внутри:
1. **Бэкап ACL** каждой папки → `/mnt/RED_2TB/backup/facl_fix_<дата>/<name>.acl.json` (откат — применить сохранённые через `filesystem.setacl`).
2. **Применение** к каждой папке списка (`Cartoons Downloads Edu Movies Music ada3s1 art books cartoons-series documentaries documentaries-series git nas photo_dedup_test seafile series shared singularity sonarr work`):
```bash
midclt call filesystem.setacl <path> \
'{"uid":950,"gid":950,"dacl":[<эталон-ACE obsidian>],"options":{"recursive":true,"traverse":true,"stripacl":false}}'
```
3. **Verify**: все каталоги → uid 950; тест `git --git-dir=<base>/git/obsidian-vault.git log`.
> `obsidian` / `obsidian-syncthing` в список **НЕ включены** — уже рабочие 950:950.
### После фикса прав
- **На маке**: `bash ~/scripts/sync-vault.sh` → 55 коммитов уедут в bare repo (launchd возобновит нормальную работу; см. раздел 1).
- **Arr-стек**: `cd /mnt/RED_2TB/docker/arr && docker compose up -d` → проверить `docker compose ps`.
### Открытые вопросы перед запуском (подтверждение Alex)
- Transmission-контейнер работает **как root** (`docker exec transmission id` → uid 0), поэтому права медиа для него некритичны; но данные Transmission (downloadDir `/mnt/storage/Downloads`) док описывал под `transdamon`/911. Решено ставить единообразно **950** (нужно для git/arr/serving). Если нужен и доступ transdamon/911 — добавить явный ACE `GROUP` на 911.
- Альтернатива владельцу 950 — общая группа `nas_users` (3000, члены: truenas_admin, transmission, nas и др.). Эталон obsidian = 950.
## Связанные заметки
- [[2026-08-31-syncthing-truenas-incident]] — вызвавший инцидент + фикс syncthing
- [[arr-stack-taiga]] — acquisition-стек на TrueNAS
- [[arr-stack-kraken]] — serving-стек (Kraken)
- [[vault-git-sync]] — git-sync алгоритм и скрипты
- [[obsidian-sync]] — общая схема Eagle↔Taiga↔Kraken
- [[syncthing-truenas-android]] — syncthing схема (требует обновления volumes → `obsidian-syncthing`)