mirror of
https://github.com/oqyude/nixos.git
synced 2026-10-07 20:47:14 +03:00
docs arch begin
This commit is contained in:
@@ -0,0 +1,396 @@
|
||||
# Карта архитектуры
|
||||
|
||||
Полная карта репозитория: per-host детали, сетевая топология, инвентарь сервисов.
|
||||
Слои 0–8 проработаны; слои 9–11 (home-manager, deploy, формат) см. в
|
||||
`docs/arch/invariants.md`.
|
||||
|
||||
## Содержание
|
||||
|
||||
1. [Реестр хостов](#реестр-хостов)
|
||||
2. [Идентичность и xlib](#идентичность-и-xlib)
|
||||
3. [Диспетчеризация модулей](#диспетчеризация-модулей)
|
||||
4. [Пользователь, SSH, секреты](#пользователь-ssh-секреты)
|
||||
5. [Хранилище](#хранилище)
|
||||
6. [Сеть и firewall](#сеть-и-firewall)
|
||||
7. [Сервисы](#сервисы)
|
||||
8. [Неотвеченные вопросы](#неотвеченные-вопросы)
|
||||
|
||||
---
|
||||
|
||||
## Реестр хостов
|
||||
|
||||
Единственная точка добавления/изменения хоста — `configurations/default.nix:13-39`.
|
||||
Имя атрибута **равно** hostname; отдельное `hostname = …` только у `default`
|
||||
(где attr = `default`).
|
||||
|
||||
| Attr | hostname | device.type | description |
|
||||
|---|---|---|---|
|
||||
| `default` | nixos | minimal | Шаблон, hostname `"nixos"`, `device = "minimal"` |
|
||||
| `atoridu` | atoridu | primary | Основной десктоп, `xanmod` |
|
||||
| `rydiwo` | rydiwo | secondary | Chuwi MiniBook, `xanmod`, NTFS-том `lamet-drive` |
|
||||
| `otrecа` | otreca | vds | VPS, SSH только через Tailscale, `grub` без EFI |
|
||||
| `sapphira` | sapphira | server | Домашний сервер, `firewall.enable = false` намеренно |
|
||||
| `wsl` | wsl | wsl | WSL NixOS на Windows-хосте `vetymae` |
|
||||
| `epral` | epral | termux | Android (`nix-on-droid`), отдельный путь конфигурации |
|
||||
|
||||
`device.type` ∈ { minimal, primary, secondary, server, vds, wsl, termux }.
|
||||
Машина `vetymae` (Windows + WSL) фигурирует в `coredns`, `nginx`, `modules/server/systemd.nix`,
|
||||
но **не** в реестре хостов — это внешний хост, через который заходят на WSL.
|
||||
|
||||
### Per-host summary
|
||||
|
||||
- **`atoridu`** (`primary/mini-pc`): без `nixos-hardware` (мини-ПК). Linux `xanmod_stable`,
|
||||
`systemd-boot`, EFI. `stateVersion 26.05`. → `configurations/mini-pc.nix`.
|
||||
- **`rydiwo`** (`secondary/mini-laptop`): `nixos-hardware: chuwi-minibook-x`, xanmod,
|
||||
`systemd-boot`, EFI. **NTFS-том `xlib.dirs.lamet-drive`** с `mask = "0000"` —
|
||||
world-readable/writable по дизайну [?]. `stateVersion 26.05`.
|
||||
- **`otrecа`** (`vds`): qemu-guest, GRUB без EFI, `disko` + `hardware/vds.nix`.
|
||||
`firewall.enable = true` + ручной `nftables.ruleset` без финального правила.
|
||||
`firewall.interfaces.tailscale0.allowedTCPPorts = [22]`. `stateVersion 25.05`.
|
||||
- **`sapphira`** (`server`): systemd-boot, EFI, ext4 на UUID `37e53ebc-…-a8de`.
|
||||
bind-mount `/mnt/services` ← `/home/oqyude/External/Services`. `stateVersion 25.05`.
|
||||
- **`wsl`**: `nixos-wsl` + NixOS-стек, IPv6 on, `firewall.enable = false`.
|
||||
`stateVersion 24.11`. Реальный Windows-хост — `vetymae`, `192.168.1.100`.
|
||||
- **`epral`** (`mobile.nix`): не NixOS, **nix-on-droid**. `stateVersion 24.05`.
|
||||
|
||||
---
|
||||
|
||||
## Идентичность и xlib
|
||||
|
||||
`lib/xlib/` собирает чистые данные (без модулей):
|
||||
|
||||
```
|
||||
xlib = {
|
||||
device = { hostname, type, username, uid, gid };
|
||||
isDesktop, isHeadless; # ← от device.type через devices.<type>.{desktop,headless}
|
||||
dirs = mkDirs username; # ← well-known пути, зависят только от username
|
||||
helpers = { mkBindMount, mkSystemdBind, mkServiceStorage, mkNtfsMount,
|
||||
mkExfatMount, mkTmpDirs, mkSymlinks };
|
||||
}
|
||||
```
|
||||
|
||||
- **`mkXlib`** (`lib/xlib/default.nix:38-77`) — единственная точка сборки; вызывается
|
||||
в `configurations/default.nix:50`. Прокидывается в каждый модуль как
|
||||
`xlib = …` через `lib/mkSystem.nix:specialArgs`.
|
||||
- **`devices`** (`lib/xlib/device.nix:12-41`) — закрытое множество device.types.
|
||||
Неизвестный тип → throw со списком валидных. Добавление типа = новая папка
|
||||
`modules/<type>/` + `home/<type>.nix` + запись в `devices`.
|
||||
- **`uid/gid`** зашиты как `?` `1000`/`1000` в `mkXlib`. Менять = инвентаризация
|
||||
во всех хостах, иначе расходятся владельцы файлов на NTFS/exFAT.
|
||||
- **`sapphira`** — исключение: `users.nix:66` ставит `uid = 1001` для сохранения
|
||||
совместимости со старым `uid-map` (`yuyus` = 1000). `TODO: delete once
|
||||
sapphira migrated to 1000`. Цена: exFAT на sapphira получает `uid=1000` от
|
||||
`xlib.device.uid`, поэтому пользователь не может писать в `/mnt/archive` и
|
||||
`/mnt/mobile` до миграции.
|
||||
|
||||
---
|
||||
|
||||
## Диспетчеризация модулей
|
||||
|
||||
### `nixosModules.default` (`modules/default.nix:9-39`)
|
||||
|
||||
Импортирует на **каждый** NixOS-хост (включая `minimal`):
|
||||
|
||||
```
|
||||
./essentials → packages, services, settings, ssh, shell, systemd-routines
|
||||
./options.nix → host.builder.*, host."3x-ui".*
|
||||
./users.nix → пользователь, sops-секреты
|
||||
home-manager.nixosModules.home-manager
|
||||
sops-nix.nixosModules.sops
|
||||
justray.nixosModules.default
|
||||
disko.nixosModules.disko
|
||||
grub2-themes.nixosModules.default
|
||||
self.homeConfigurations.default.nixosModule
|
||||
```
|
||||
|
||||
Плюс `lib.optional xlib.isDesktop ./desktop` (primary, secondary).
|
||||
Плюс `lib.optional (!isDesktop && type != "minimal") (./. + "/${type}")`
|
||||
(server, vds, wsl, termux). **termux** попадает сюда только в path nix-on-droid,
|
||||
не как NixOS-хост (см. `mobile.nix`).
|
||||
|
||||
### `nixosModules.strict` (`modules/default.nix:40-53`)
|
||||
|
||||
Используется только `mobile.nix:22`. Импортирует `options.nix` +
|
||||
`./<device.type>`; **всё** остальное NixOS-специфичное (essentials, users,
|
||||
home-manager, sops, disko, grub2-themes) **выключено**, потому что nix-on-droid
|
||||
не имеет `services.*`, `users.*`, `sops.*`, `disko.*` в своей модульной системе.
|
||||
|
||||
### Правило для кросс-модульных опций
|
||||
|
||||
Опция живёт в `modules/options.nix`, если её **устанавливает** один модуль,
|
||||
а **читает** другой. `host.reader.X.enable` живёт в `essentials/ssh.nix`, потому
|
||||
что его объявляет и использует один модуль.
|
||||
|
||||
---
|
||||
|
||||
## Пользователь, SSH, секреты
|
||||
|
||||
### Пользователь `oqyude`
|
||||
|
||||
- `uid` = `1000` на всех хостах, кроме `sapphira` (=`1001`, см. выше).
|
||||
- `home = /home/oqyude`, `homeMode = "700"`.
|
||||
- `linger = true` на всех хостах — user-services (opencode-web) переживают logout.
|
||||
Следствие: user-сервисы стартуют и потребляют ресурсы без активной сессии.
|
||||
- `extraGroups`: `audio disk gamemode networkmanager pipewire wheel libvirtd qemu-libvirtd`.
|
||||
|
||||
### SSH
|
||||
|
||||
- `essentials/ssh.nix`: `services.openssh` включается через `host.ssh.enable`,
|
||||
`PermitRootLogin = "yes"` (намеренно для deploy), `PasswordAuthentication = false`,
|
||||
hostKey = `/etc/ssh/id_ed25519`.
|
||||
- `authorizedKeys` для `oqyude` зашит в `users.nix:87` (`ssh-ed25519 AAAA…`).
|
||||
Чей — `[?]` (см. вопрос 4.1).
|
||||
- `users.nix` определяет `root`-authorizedKeys **отсутствует** [?] — root как-то
|
||||
попадает на хост; deploy-rs использует `sshUser = "oqyude", user = "root"`.
|
||||
|
||||
### Циклическая зависимость ключа
|
||||
|
||||
`/etc/ssh/id_ed25519` одновременно:
|
||||
- `hostKeys` для sshd (`essentials/ssh.nix:22`)
|
||||
- `sops.age.sshKeyPaths` для расшифровки (`users.nix:95-97`)
|
||||
- цель `ssh_key_private_known` (`users.nix:147-152`)
|
||||
- цель `ssh_key_public_host` (`users.nix:159`)
|
||||
|
||||
Как разворачивается на чистой машине — **одноразовый bootstrap** [?].
|
||||
Должен быть задокументирован, иначе при переустановке хоста агент не выведет.
|
||||
|
||||
### `.sops.yaml`
|
||||
|
||||
- Один age-ключ (`*default`), `path_regex: secrets/[^/]+\.(yaml|json|env|ini)$`.
|
||||
- Покрывает только плоские файлы в `secrets/` (без подкаталогов).
|
||||
- Добавление секрета = `secrets/<имя>.<yaml|json|env|ini>` строго в корне.
|
||||
- Дополнительные секреты dotenv/json — через `mkUserSecret` (`users.nix:33-41`).
|
||||
|
||||
### Инвентарь секретов (`users.nix:100-162`)
|
||||
|
||||
| Секрет | Формат | Назначение |
|
||||
|---|---|---|
|
||||
| `hashed_password` | yaml | Пароль пользователя |
|
||||
| `age_key_private` | yaml | `~/.config/sops/age/keys.txt` |
|
||||
| `opencode_server` | dotenv | `~/.config/opencode/server.env` |
|
||||
| `opencode_auth` | json | `~/.local/share/opencode/auth.json` (`key=""`) |
|
||||
| `opencode_account` | json | `~/.local/share/opencode/account.json` (`key=""`) |
|
||||
| `ssh_key_private` | yaml | `~/.ssh/id_ed25519` |
|
||||
| `ssh_key_public` | yaml | `~/.ssh/id_ed25519.pub` |
|
||||
| `ssh_key_private_root` | yaml | `/root/.ssh/id_ed25519` |
|
||||
| `ssh_key_public_root` | yaml | `/root/.ssh/id_ed25519.pub` |
|
||||
| `ssh_key_public_host` | yaml | `/etc/ssh/id_ed25519.pub` |
|
||||
|
||||
---
|
||||
|
||||
## Хранилище
|
||||
|
||||
### `/home/oqyude/External` (ext4)
|
||||
|
||||
- `sapphira`: UUID `37e53ebc-5343-a94d-9fe2-0ca39e13a8de`, fsType `ext4`,
|
||||
**без `nofail`**, **без automount** — обычный mount, без `x-systemd.automount`,
|
||||
не помечен как `requiredBy local-fs.target` явно, но NixOS добавляет это для
|
||||
всех `fileSystems` без `nofail` [?].
|
||||
- `rydiwo`: не смонтирован (у ноутбука есть только NTFS `lamet-drive`).
|
||||
- На других NixOS-хостах — не заявлен (нет внешнего диска).
|
||||
|
||||
### `/mnt/services` (bind)
|
||||
|
||||
- `server.nix:49-52`: `mkBindMount` от `xlib.dirs.services-folder`
|
||||
(= `/home/oqyude/External/Services`) к `/mnt/services`, `bind,nofail`.
|
||||
- `server.nix:61-63`: tmpfiles `z /mnt/services 0777 root root`.
|
||||
- `vds/default.nix:23`: tmpfiles создаёт `/mnt/services` с правами `0755`.
|
||||
- Используется сервисами на sapphira для bind-mount сервисных данных
|
||||
(`mkServiceStorage`) и как прямой `stateDir` для gitea/memos/calibre-web/
|
||||
immich/nextcloud/step-ca/trilium/uptime-kuma/3x-ui/tape-rotation.
|
||||
|
||||
### `/mnt/archive`, `/mnt/mobile`, `/mnt/lamet`, `/mnt/therima`, `/mnt/vetymae`, `/mnt/soptur`
|
||||
|
||||
- `archive` и `mobile` смонтированы на sapphira через `mkExfatMount`
|
||||
(`nofail`+uid=1000).
|
||||
- `lamet` — NTFS на rydiwo (`mask = "0000"`).
|
||||
- `therima`, `vetymae`, `soptur` — **не** смонтированы нигде в репозитории
|
||||
(см. вопрос 2.2).
|
||||
- `dirs.nix` объявляет их все; `dirs.nix` **не** читать как список дисков этой
|
||||
системы — там имена, часть из которых не существует.
|
||||
|
||||
### Потребители External-диска и порядок защиты
|
||||
|
||||
Включённые на sapphira сервисы с данными на `/mnt/services` или `/home/oqyude/External`:
|
||||
|
||||
- `postgresql`, `samba-smbd`, `homebox` (+setup), `gitea` (+dump),
|
||||
`navidrome`, `syncthing`, `uptime-kuma`, `immich-server` (+ML),
|
||||
`nextcloud`, `calibre-web`, `podman-3xui_app`, `podman-tape-rotation`
|
||||
|
||||
Все они обязаны иметь guard на `requiresMountsFor` (задача **B1** в `todo.md`).
|
||||
Сейчас guard есть **только** у rsync-юнитов (`modules/server/systemd.nix:14,36`),
|
||||
которые используют `--delete` и потенциально самые опасные при отсутствующем
|
||||
диске.
|
||||
|
||||
---
|
||||
|
||||
## Сеть и firewall
|
||||
|
||||
### Топология
|
||||
|
||||
```
|
||||
Интернет (роутер, белый IP)
|
||||
├── router NAT/proxy → sapphira: 443, 80, 22000, 8443, 22 (5 портов)
|
||||
│
|
||||
└── otreca (VPS): SSH только через Tailscale, не пробрасываем
|
||||
|
||||
LAN (192.168.1.0/24)
|
||||
├── 192.168.1.20 = sapphira (домашний сервер)
|
||||
├── 192.168.1.1 = роутер (gateway)
|
||||
├── 192.168.1.100 = vetymae (Windows-хост; на нём — WSL NixOS = `wsl`)
|
||||
├── 192.168.1.101, .102 = соседние машины (rsync/таблица в `termux.nix`)
|
||||
└── ...
|
||||
|
||||
Tailscale (CGNAT 100.64.0.0/10)
|
||||
├── 100.64.0.0 = sapphira (назначен вручную)
|
||||
├── 100.64.1.0 = ещё один узел [?]
|
||||
├── 100.86.62.4 = opencode на vetymae
|
||||
└── 100.106.21.39 = miniflux на другом узле
|
||||
```
|
||||
|
||||
`192.168.1.20` зашит в ~30 местах: `modules/server/{nginx,coredns,nfs,open-webui}.nix`,
|
||||
`configurations/*`. `100.64.0.0` — в `nginx.nix`, `nextcloud.nix`,
|
||||
`modules/vds/{nginx,systemd}.nix`.
|
||||
|
||||
### DNS (`modules/server/coredns.nix`)
|
||||
|
||||
Зоны `zeroq.su` (~17 записей) и `home.arpa` (~17) определены вручную.
|
||||
Дублируют инвентарь сервисов: добавление сервиса = правка `coredns.nix` +
|
||||
`nginx.nix` + самого модуля.
|
||||
|
||||
### Firewall
|
||||
|
||||
| Хост | `firewall.enable` | Фильтрация |
|
||||
|---|---|---|
|
||||
| sapphira | **false** (намеренно) | Роутер пробрасывает 5 портов: **443, 80, 22000, 8443, 22** |
|
||||
| otreca | true | Самописанный nftables **без финального правила** → неявный accept; `firewall.interfaces.tailscale0.allowedTCPPorts = [22]` |
|
||||
| wsl | false | WSL — не сетевой периметр |
|
||||
| rydiwo, atoridu | default | `desktop` правила |
|
||||
|
||||
Следствия:
|
||||
- На `sapphira` `openFirewall`/`allowedTCPPorts` не имеют эффекта.
|
||||
- `nginx.nix:225` (`allowedTCPPorts = [80 443]`) — **мёртвое** правило.
|
||||
- Допустимо `0.0.0.0` на любом сервисе sapphira — он не открывается в интернет
|
||||
без проброса на роутере.
|
||||
- На `otrecа` ruleset требует финальной политики (задача A3).
|
||||
|
||||
### SSH
|
||||
|
||||
`otreca` достижима только через Tailscale: `services.openssh.openFirewall = false`,
|
||||
`firewall.interfaces.tailscale0.allowedTCPPorts = [22]`. Но при `nftables.enable`
|
||||
с ручным ruleset это правило может не дойти до файрвола — проверить
|
||||
`nft list ruleset` на otreca до правок (задача A3).
|
||||
|
||||
---
|
||||
|
||||
## Сервисы
|
||||
|
||||
### Системные (sapphira, в `modules/server/default.nix:imports`)
|
||||
|
||||
Сервисы в `imports` + `state` + `roles`:
|
||||
|
||||
| Сервис | Файл | Порт | Данные | Guard? |
|
||||
|---|---|---|---|---|
|
||||
| acme (Let's Encrypt) | `modules/server/acme.nix` | — | `/var/lib/acme` | — |
|
||||
| bentopdf | `bentopdf.nix` | — | — | — |
|
||||
| builder (remote) | `builder.nix` | — | — | — (опция выключена) |
|
||||
| calibre-web | `calibre-web.nix` | 8083 | `services-mnt-folder/calibre-web(-library)` | нужен B1 |
|
||||
| chrony | `chrony.nix` | — | — | — |
|
||||
| coredns | `coredns.nix` | 53 | inline zone | — |
|
||||
| gitea | `gitea.nix` | 3000 | `services-mnt-folder/gitea` | нужен B1 |
|
||||
| glances | `glances.nix` | — | — | — |
|
||||
| homebox | `homebox.nix` | 7745 | `mkServiceStorage` | нужен B1 |
|
||||
| immich | `immich.nix` | 2283 | `services-mnt-folder/immich` | нужен B1 |
|
||||
| miniflux | `miniflux.nix` | 6061 | — | — |
|
||||
| navidrome | `navidrome.nix` | 4533 | `server-home/Music` | нужен B1 |
|
||||
| nextcloud | `nextcloud.nix` | 10000 | `services-mnt-folder/nextcloud` | нужен B1 |
|
||||
| nginx | `nginx.nix` | 80/443 | proxy-only | — |
|
||||
| nix-serve | `nix-serve.nix` | 5000 | — | — |
|
||||
| onlyoffice | `onlyoffice.nix` | (через nginx) | — | — |
|
||||
| postgresql | `postgresql.nix` | (local) | `mkServiceStorage` | нужен B1 |
|
||||
| power | `power.nix` | — | — | — |
|
||||
| samba | `samba.nix` | ? | `mkServiceStorage` | нужен B1 |
|
||||
| syncthing | `syncthing.nix` | 8384 (gui), 22000 (data) | `server-home`, `storage/persist/...` | нужен B1 |
|
||||
| systemd (rsync oneshots) | `systemd.nix` | — | источник/приёмник — оба на External | **уже есть guard** |
|
||||
| uptime-kuma | `uptime-kuma.nix` | 4001 | `services-mnt-folder/uptime-kuma` | нужен B1 |
|
||||
|
||||
Закомментированы в `imports` (всё ещё живой код, потенциальный шум):
|
||||
`remnawave, coturn, mealie, memos, minecraft, n8n, netdata, nfs, open-webui,
|
||||
rsync, step-ca, stirling-pdf, transmission, trilium, zerotier` — см. задачу **E3**.
|
||||
|
||||
### Контейнеры (`modules/containers/`)
|
||||
|
||||
| Контейнер | Файл | Данные | Примечание |
|
||||
|---|---|---|---|
|
||||
| 3x-ui | `3x-ui.nix` | `services-nodes-folder/<host>/3x-ui/{db,cert}` | **Заморожен**, см. ниже |
|
||||
| tape-rotation | `tape-rotation.nix` | `services-nodes-folder/<host>/tape-rotation` | — |
|
||||
| remnawave | `remnawave.nix` | `/mnt/services/containers/remnawave` | **закомментирован** в `server/default.nix` |
|
||||
| remnanode | `remnanode.nix` | `/mnt/services/containers/remnanode` | — |
|
||||
| kokoro-tts | `kokoro-tts.nix` | — | — |
|
||||
| openhands | `openhands.nix` | — | — |
|
||||
| remnawave-examples | `remnawave-examples/*.nix` | docker-compose | шаблоны |
|
||||
|
||||
### 3x-ui — замороженное состояние
|
||||
|
||||
Образ: `ghcr.io/mhsanaei/3x-ui:latest` (**не запинен**). Ядро Xray — на 26.7.x,
|
||||
миграция на 26.9.x провалена. Панель может обновиться из upstream — поэтому:
|
||||
- `podman-update-3xui_app` (`3x-ui.nix:80-90`) с `podman pull …:latest`
|
||||
+ `systemctl restart` — **таймер закомментирован**.
|
||||
- `podman.autoPrune.flags = ["--all"]` (`3x-ui.nix:45-47`) — потенциальный риск:
|
||||
авто-prune может смести панель без коммита в репозиторий.
|
||||
|
||||
`reality443Forwarding = true` (`modules/vds/default.nix:19`) — следствие отката
|
||||
`c8d4a12`; смысл утрачен, см. задачу **C5**.
|
||||
|
||||
### Nginx (`modules/server/nginx.nix`)
|
||||
|
||||
~12 vhost'ов через `mkProxy` для обратного проксирования сервисов на 192.168.1.20.
|
||||
Плюс несколько hand-written:
|
||||
|
||||
- `nextcloud.private` — слушает на `100.64.0.0:10000` (= Tailscale sapphira),
|
||||
`192.168.1.20:10000`, `127.0.0.1:10000`.
|
||||
- `office.zeroq.su` — проксирует на nextcloud onlyoffice.
|
||||
- `pdf.private` — слушает `0.0.0.0:80`, `100.64.0.0:8446`, `192.168.1.20:8446`,
|
||||
`127.0.0.1:8446` (для Nextcloud PDF).
|
||||
- `x.zeroq.su` — 3x-ui controller panel + `/subs/`, `/subsjs/`, `/clash/`.
|
||||
- `zeroq.su` — корневой, заглушка + `/guest/` → LAN `:80`.
|
||||
- `vetymae.opencodes.zeroq.su` → `100.86.62.4:4096`.
|
||||
- `lamet.opencodes.zeroq.su` → `100.106.21.39:6061` — **порт miniflux**; либо
|
||||
ошибка, либо так задумано [?] (см. вопрос 8.2).
|
||||
- `opencode.zeroq.su` → `127.0.0.1:4096` (opencode-web на самом sapпира).
|
||||
- `nextcloud.zeroq.su` → `192.168.1.20:10000`, `/whiteboard` → `:3002`.
|
||||
|
||||
`networking.firewall.allowedTCPPorts = [80 443]` (строка 225) — **мёртвое** правило
|
||||
при `firewall.enable = false`.
|
||||
|
||||
---
|
||||
|
||||
## Неотвеченные вопросы
|
||||
|
||||
Слои 9–11 (home-manager, deploy, формат) оставлены для прочтения в
|
||||
`docs/arch/invariants.md`. Неотвеченные вопросы слоёв 1–8:
|
||||
|
||||
| ID | Вопрос |
|
||||
|---|---|
|
||||
| 2.2 | `vetymae` / `lamet` / `therima` / `soptur` — те же машины или хосты вне репозитория? |
|
||||
| 2.5 | `stateVersion` дрейфует 24.05 / 24.11 / 25.05 / 26.05 — намеренно? |
|
||||
| 2.6 | Есть ли escape hatch для per-host отличий в `xlib`? |
|
||||
| 3.2 | `any.nix` (minimal) действительно нуждается в home-manager + sops + disko? |
|
||||
| 4.1 | Как root получает доступ по SSH — `authorizedKeys` для root в коде нет |
|
||||
| 4.2 | Как разрешается цикл «ключ в секрете, а нужен для расшифровки»? |
|
||||
| 4.3 | Все файлы в `secrets/` покрыты `path_regex`? |
|
||||
| 4.4 | Как подключается вторая машина / второй человек при одном age-ключе? |
|
||||
| 4.5 | `users.nix:87` — личный ключ или общий «ключ от деплоя»? |
|
||||
| 5.1 | `/mnt/services` в режиме 0777 — осознанно? |
|
||||
| 5.3 | NFS выключен, Samba работает — миграция? |
|
||||
| 5.4 | NTFS-том `lamet-drive` с `mask = "0000"` — что на нём лежит? |
|
||||
| 5.5 | `therima` / `vetymae` / `soptur` — несуществующие остатки или сетевые шары? |
|
||||
| 5.6 | Где бэкапы БД и 3x-ui? |
|
||||
| 6.6 | `192.168.1.20` зашит в 30 мест — считаем константой? |
|
||||
| 6.7 | DNS дублирует инвентарь сервисов — как проверяем рассинхрон? |
|
||||
| 6.8 | Публичные IP и SSH-алиасы в `home/termux.nix` — карта «хост → адреса» нужна? |
|
||||
| 6.9 | Какой путь REALITY считается правильным? (→ C5) |
|
||||
| 7.4 | Почему не публиковать весь диапазон 14380-15379? |
|
||||
| 8.2 | `lamet.opencodes` → `:6061` — ошибка или так задумано? |
|
||||
| 8.4 | `onlyoffice` — работает после трёх регрессов? |
|
||||
| 8.5 | Что слушает `:3002` (`/whiteboard` в nextcloud)? |
|
||||
Reference in New Issue
Block a user