Audit repa + infrastruktury 2026-07-06 — checklist remediace
Kompletní nálezy z pětioblastního auditu (HA config, dokumentace, zálohy/DR, síť/Proxmox, monitoring/observabilita) + živé nálezy z incidentu 2026-07-05/06. Pracovní checklist — po dokončení všech položek soubor smazat, trvalé závěry přesunout do decision_log.md.
Kontext — incident 2026-07-05/06:
- pmx2 náhle umřel ~23:31 (poslední logy v Loki = cleanup SSH session, pak ticho bez shutdown sekvence → hang/HW, softdog tentokrát nepomohl).
- Ráno failover kritických VM (pfSense 100, HA 102, PBS 105) na pmx1 ze ZFS replik — runbook
disaster_recovery.mdfungoval. pvecm expected 1nepřežilo reboot pmx1 → guests nenastartovaly → celý dům ~25 min offline (pfSense = DNS/DHCP/routing).- Po startu LXC 107 selhal NFS mount
/mnt/data(exit 32),docker.servicespadl na „Dependency failed" a bez retry zůstal ležet — celý docker stack (Loki, Grafana, nginx, n8n, InfluxDB) vstal až ručním dotykem docker socketu v 09:13. Nikdo nebyl notifikován. - Souběžně: Storj sync PBS dat selhával od 3. 7. (viz P3) — v nejhorší možný moment (replikace mimo provoz, PBS = jediná záložní vrstva).
Rozhodnutí uživatele (2026-07-06):
- pmx2 se neopravuje — Amazon vrací peníze (NiPoGi). Třetí plnohodnotný node nebude.
- Quorum device (corosync-qnetd) bude na TrueNAS — výslovně NE na debian-services (běží na pmx1, arbitr uvnitř clusteru je k ničemu).
P — Akutní (dny)
- [ ] P1 (P0) Secure wipe SSD pmx2 před vrácením Amazonu. Data rescue není potřeba (upřesněno 2026-07-06): Jellyfin ct/110 bylo prázdné LXC (budoucí projekt), veškerá Immich data (media) leží na TrueNAS NFS, žádná lokální metadata → na novém nodu čistá instalace + mount síťového disku = plnohodnotná obnova. Na SSD ale zůstaly ZFS repliky HA/pfSense/PBS (vč. secrets) → před odesláním disk bezpečně smazat.
- [ ] P2 (P1) Nová Immich instalace (nový node): rovnou do PBS backup jobu (
/etc/pve/jobs.cfg, dnesvmid 100,102,103,106,107,109). Obecné pravidlo: každý nový guest při vzniku zařadit do backup jobu (dnes žádný proces nehlídá, že guest zálohu má — Immich měl jedinou z 2/2026). - [~] P3 (P0) Storj sync
pbs-dataselhával od 2026-07-03 — root cause nalezen + opraveno 2026-07-06. Chyba: rcloneerror reading source directory: directory not foundna top-level.chunks/ct/vm. Skutečná příčina: task másnapshot: true→ sync jede z dočasného ZFS snapshotu přes.zfs/snapshot/automount, který mázfs_expire_snapshot=300 s. Walk přes 65536 chunk adresářů proti 433k objektům na pomalé Storj gateway přeroste 5min okno → ZFS snapshot odmountuje → zdroj zmizí uprostřed běhu. (Dřívější 14min běhy se pod okno vešly; jak objem narostl, začalo padat.) Slepá ulička:fast_list: true(zkoušeno ráno) nepomohl — spadl stejně, jen dřív; vrácen na false. Fix (na příčinu):zfs_expire_snapshot300 → 86400 s (živěecho+ persist přes TrueNAS POSTINIT init script id 3, přežije reboot). Zachovává point-in-time konzistenci. Navíc uklizen stuckcloud_sync-3snapshot z 2026-01-21 (nedouklizený pozůstatek). OVĚŘENO 2026-07-06: sync job 438419 SUCCESS po 185 min, plný march (153948 checks) proběhl bez „directory not found", CloudSyncTaskFailed alert se sám vyčistil. Offsite kopie PBS dat je zase aktuální. Pozn.: běh trvá ~3 h (bez fast_list, listing 65k chunk dirs po pomalé gateway) — u nočního jobu 04:00 (dokončení ~07:00) OK; fast_list by zrychlil, ale za cenu RAM (~0,5 GB) → ponecháno. Follow-up: propojit na M2/P6 (alert na failure — dnes selhání 3 dny nikdo neviděl). - [x] P4 (P0) Kvórum — vyřešeno 2026-07-06:
pvecm delnode pmx2→ jednouzlový cluster,expected=1trvale (reboot přežije, na rozdíl od runtimepvecm expected 1). Vizdecision_log.md2026-07-06. Zbývá po stavbě nového nodu:pvecm add→ 2 uzly → corosync-qnetd na TrueNAS (samostatné železo mimo cluster) +corosync-qdevicena obou nodech = 3 hlasy, výpadek kteréhokoli nodu zůstane quorate. To je vlastní fix incidentu (viz M5, N3). Pozn.: stará todos „Proxmox qdevice" navrhovala debian-services — špatně, arbitr nesmí stát uvnitř clusteru (na pmx1). - [ ] P5 (P0) debian-services boot resilience:
/mnt/datapřevést nax-systemd.automount(nebo mount unit s retry) +docker.servicedrop-inRestart=on-failure/StartLimitIntervalSectak, aby jednorázové selhání NFS při bootu neznamenalo trvale ležící stack. Květnový fix (_netdev,nofail+ dependency) řeší pořadí, ne retry — 2026-07-06 empiricky selhal. - [ ] P6 (P1) Alert na selhání TrueNAS Cloud Sync — selhávalo 3 dny bez povšimnutí. Nejjednodušší: TrueNAS Alert Services (e-mail) + Uptime Kuma push monitor (post-script tasku pinguje URL po úspěchu → Kuma alarmuje při absenci). Uzavírá i starý dluh ze
zalohy/strategie.md:49(„alert osiřel po odchodu CheckMK").
Z — Zálohy & disaster recovery
- [ ] Z1 (P1) První reálný restore test. Kandidát: PBS restore ct/106 (Scrypted) nebo ct/107 do scratch VMID na pmx1 (bez startu sítě / jiná IP). Změřit reálné RTO, zapsat do
disaster_recovery.md. Následně aspoň jednou otestovat pull ze Storj (stáhnout část bucketu a ověřit čitelnost chunků v PBS). - [ ] Z2 (P2) Storj bucket immutabilita + lifecycle. Oprava předpokladu (ověřeno 2026-07-06): bucket
pbsmá object versioning zapnutý (rclone backend versioning→Enabled) — takže i přitransfer_mode: SYNC(zrcadlo) jsou smazané/přepsané objekty obnovitelné z historie verzí; hlavní obava (koruptní data propsaná offsite bez návratu) je tím z velké části pokrytá. Zbývá: (a) Object Lock (WORM/governance) pro tvrdou anti-ransomware neměnnost — versioning sám o sobě nechrání proti kompromitovanému S3 klíči, který umí verze smazat / versioning vypnout (neověřeno,rclone backend versioningObject Lock neukazuje); (b) lifecycle pravidlo na expiraci non-current verzí (jinak verze narůstají — náklad/růst, ne bezpečnost). - [ ] Z9 (P2, odloženo uživatelem 2026-07-06) Rotace Storj S3 credentialu (id 3).
secret_access_keybyl 2026-07-06 nechtěně vypsán do agent transcriptu + shell historie TrueNAS (dotaz nacloudsync.queryprovider bits). Storj je client-side šifrovaný a klíč dává přístup jen k bucketupbs, ale správně rotovat: nový access grant / S3 credentials v Storj → přepsat credential id 3 v TrueNAS → revokovat starý. Váže se na Z2 (dokud běží starý klíč, immutabilita přes Object Lock má o důvod víc). - [ ] Z3 (P1) secrets.yaml → Bitwarden (šifrovaná kopie / secure note). Dnes existuje jen uvnitř PBS zálohy HA VM; standalone recovery cesta chybí (Storj/PBS/TrueNAS klíče v Bitwardenu jsou, HA secrets ne).
- [ ] Z4 (P1) TrueNAS config export — pravidelný
Export Config(vč. secret seed) mimo TrueNAS (např. do$HOMELAB_BACKUP_DIR+ kopie k PBS zálohám). TrueNAS je nejcentrálnější SPOF záložní architektury a vlastní konfig nemá zálohovaný vůbec. - [ ] Z5 (P2) PBS verify job — ověřit aktuální stav (poslední generovaný doc z 2026-02-07 ukazoval ❌ failed) + přegenerovat
pbs_generated.md+ zapojit do alertingu (M2). - [ ] Z6 (P2) Mirror
tankpoolu — všechny tři TrueNAS pooly jsou single-disk vdev; na tanku (1× NVMe) leží PBS datastore = zálohy celého clusteru. Druhý NVMe + attach do mirroru. - [ ] Z7 (P2) Po obnově clusteru znovu nastavit ZFS replikaci (teď disabled, otočená pmx1→pmx2) dle re-promotion postupu; zvážit kratší interval pro pfSense (už je
*/30) a sjednotit RPO údaje v docs (viz D6). - [ ] Z8 (P2)
backup_unifi.py+backup_configs.py: migrace na UniFi OS Server (tracked v todos), naplánovat (timer) a monitorovat — dnes ruční, bez rozvrhu, UniFi větev zálohuje prázdný legacy controller.
H — HA config (bezpečnost fyzického HW)
- [ ] H1 (P0) Závlaha fail-safe: (a) automatizace na
homeassistant.start→ force-off všechswitch.zavlaha_*(ventil nesmí přežít restart HA sepnutý); (b) nezávislý watchdog „kterýkoli zavlaha switch on > 30 min → vypnout + notifikace". Dnes drží ventil otevřený jendelayvescript.zavlaha_spust_okruh— pád HA uprostřed = relé sepnuté do příštího plánovaného běhu. - [ ] H2 (P1) Read-back verifikace kritických Modbus zápisů podle vzoru
ftv_export_apply(zpožděné přečtení +persistent_notificationpři mismatch): minimálněatrea_zapis_vykonu_ventilatoru,atrea_zapis_rezimu_sezony,ftv_tc_boost,ftv_tc_nocni_reset. - [ ] H3 (P1) Climate entity:
availability_templatepro všech 10 jednotek vclimate.yaml— dnesint(0)/float(0)fallback maskuje výpadek Modbusu jako „off / 0,0 °C" místounavailable. - [ ] H4 (P2)
recorder.excludezrcadlící logikuinfluxdb.exclude(surové Modbus polling entity, command_line senzory, history_stats) — dnes recorder bez filtru při ~100 registrech á 30 s. - [ ] H5 (P2)
binary_sensor.ha_gitops_stale(template.yaml:614) — komentář slibuje alert automatizaci, která neexistuje (zrušena 2026-06-15). Buď postavit (30 min debounce → push), nebo komentář opravit. - [ ] H6 (P2) Watchdog dlouho sepnutých relé mimo závlahu:
switch.topeni_bazen,switch.ftv_do_akumulacky,switch.ftv_do_boileru— „on > 4 h → notifikace". - [ ] H7 (low) Doorbell TTS repeat větev (
automations.yaml,doorbell_ring): doplnit vlastní timeout narepeat, ať nezávisí jen na sesterské větvi vypínajícíinput_boolean.zvonek_zvoneni_aktivni. - [ ] H8 (low) Závlaha: sdílený mutex (input_boolean) pro
zavlaha_rano/zavlaha_zahony_*/zavlaha_test_okruhmísto párových state-kontrol (TOCTOU race, porušuje „max 1 okruh"). - [ ] H9 (low)
rest_command.doorbell_open_gate+ carport pulse — bez failure feedbacku; ověřit HTTP status / stavový kontakt, notifikace při selhání. - [x] H10 (low) ~~
check_buttons.pyzapojit do CI~~ — bezpředmětné:button_manager+buttons.yaml+check_buttons.pyodstraněny 2026-07-23 (přechod na nativnífoxtron_dali_button_action, vizdecision_log.md2026-07-22).
M — Monitoring & alerting
- [ ] M1 (P0) TČ + VZT alerting: automatizace na
binary_sensor.ecoforest_alarm(dnes ho nikdo nesleduje!) + „Ecoforest/Atrea Modbus entityunavailable> 10 min → push" podle vzorubazen_aseko_offline. Topení je nejkritičtější systém domu a dnes je slepý. - [ ] M2 (P1) Externí dead-man's switch (healthchecks.io, free tier): pingy po úspěchu z (a)
log-monitor.timer, (b) PBS verify jobu, (c) Storj cloud sync post-scriptu. Jediná vrstva, kterou stack strukturálně nemá — všechen alerting dnes žije uvnitř domu a umře s debian-services / internetem (2026-07-06 empiricky). - [ ] M3 (P1) Uptime Kuma → notifikace („Fáze 3" z
monitoring.md): dotáhnout push kanál (nativní Telegram v Kumě stačí), doplnit hosty (unifi-os — tracked). Bez toho Kuma pinguje do prázdna. - [ ] M4 (P1) Disk usage alerty: pool
archive84,8 %,nvr-truenas~89 %, InfluxDB retence ∞ (migrace 1.8→2.x tracked). TrueNAS alert threshold + Grafana pravidlo. - [ ] M5 (P1) Grafana alert kernel soft lockup / hung_task (tracked todos) — po smrti pmx2 priorita ↑; přidat i pattern „node syslog zmlkl" (Loki freshness per hostname pmx1/pmx2, stejný vzor jako journal/syslog rules).
- [ ] M6 (P2) systemd timery pro
doc_gen_*.py— generované docs stárnou (pbs 5 měsíců, proxmox ukazoval ghost node); po stabilizaci clusteru přegenerovat všechny. - [ ] M7 (P2) Ověřit, zda 2026-07-05 ~23:41 vystřelil Grafana alert „Log source silent: journal" (HA journal zmlkl se smrtí pmx2). Pokud ne / zapadl v Telegramu → kalibrovat (severity, repeat) a řešit „critical" kanál (HA companion critical push přes M3).
- [ ] M8 (low) Cert expiry monitor (Uptime Kuma umí nativně) pro
*.marada.name.
D — Dokumentace
- [ ] D1 (P0) Naplnit
docs/navod_pro_rodinu/nouze.md— incident 2026-07-05 je přesný use-case. Obsah: výpadek internetu / proudu / celé sítě („nesvítí nic ze sítě → koukni na rack, tady je co zkusit, tady je koho volat"), HA nejede, topení v zimě nejede, únik vody + poloha hlavního uzávěru, kontakty (Veskom, Multi Klima, elektrikář, soused), „co funguje offline" matice (Zigbee/Modbus/kamery ano; TaHoma žaluzie, OTE, remote access ne — viz N3). - [ ] D2 (P1) Naplnit
komfort.md(přeložit „co dělat když" tabulky ztepelne_cerpadlo.md/rekuperace.md/klimatizace.mddo plain language) amedia.md— vzor:energie.md,tiskarna.md. - [ ] D3 (P1)
studna.md— doplnit reálný obsah (čerpadlo: kde je, jistič, co dělat když neteče voda); dnes stránka popisuje jen budoucí vodoměr projekt. - [ ] D4 (P2)
bazen_vzt.md— dotáhnout stub (tracked i v audit_2026-06 D13). - [ ] D5 (P2) Incident 2026-07-05/06 →
decision_log.mdentry po uzavření (root cause pmx2 pokud zjistitelná, refund, plán náhrady, qdevice rozhodnutí, Storj fix). - [ ] D6 (P2) Sjednotit RPO údaje:
proxmox.mdtvrdí 15 min,disaster_recovery.md*/01:30(pfSense nově*/30). Po Z7 aktualizovat podle reality. - [ ] D7 (P2)
audit_2026-06.md— zbývající open položky (A5, A6, D1, D3, D13, D17, …) přenést sem/do todos a soubor smazat dle jeho vlastního lifecycle (ať neexistují dva konkurenční backlogy). - [ ] D8 (low)
docs/index.md„zeptej se správce (táty)" → po D1 odkázat nanouze.md.
HW — co domu chybí
- [ ] HW1 (P1) Zigbee leak senzory (pračka, myčka, bojler/AK, TČ + rozdělovače, bazénová technologie) + automatizace „leak → critical push". Největší nepokryté fyzické riziko za pár stovek. Návazně zvážit motorizovaný hlavní uzávěr (Zigbee/Modbus kulový ventil) — leak → zavřít.
- [~] HW2 (P1) Náhradní node za pmx2 — vybrán 2026-07-06: ASUS ExpertCenter PN54-S1 (Ryzen 7 260, 32 GB DDR5, dual 2.5GbE, 2× M.2). Viz
decision_log.md+ todos „Nový uzel PN54-S1". Do doručení jednonodový provoz pmx1 — vědomě akceptovaný stav bez failoveru; nerestartovat pmx1 zbytečně (i kdyžexpected=1teď reboot přežije, guests naběhnou sériově = krátký výpadek sítě). - [ ] HW3 (P2) Druhý NVMe do TrueNAS (= Z6 mirror).
- [ ] HW4 (P2) Freeze-protection teploměry (technická místnost, přívod studny) + anomálie alert (vazba M1 vzor).
- [ ] HW5 (info) Už tracked v todos, nezdvojovat: WS90 meteostanice (nákup odblokován), fyzický dešťový senzor, LTE WAN fallback, WiCAN Pro.
N — Síť
- [ ] N1 (P1) Tailscale hardening: nasadit reálné ACL (dnes any→any na všechny VLANy vč. kamer a IoT —
vpn.mdACL jsou jen ukázka), ověřit non-expiring key na pfSense uzlu (default 180 dní = tichá smrt remote přístupu) a MFA na účtu. - [ ] N2 (P2) TaHoma/Overkiz offline chování — ověřit, jestli žaluzie/okna fungují bez internetu (lokální API vs cloud), výsledek zapsat do
velux.md+ promítnout do D1 matice. - [ ] N3 (P2) Po obnově clusteru zvážit Proxmox
ha-managergroup pro VM 100 (pfSense) — auto-start na přeživším nodu místo ručního runbooku (vyžaduje funkční kvórum = po P4/qdevice). - [ ] N4 (info) Už tracked: MEDIA block rule no-op (todos), SNMP
public(audit-06 A5), pfSense LTE failover (todos), USW-48 flapping porty — doplnit do todos i porty racku (8, 9, 16, 33, 48), dnes tracked jen dílna.
Co audit potvrdil jako silné (nechat být): decision_log kultura, CI + pre-commit + gitleaks, config-as-code (Grafana provisioning), VLAN segmentace vč. kamer bez internetu, Victron místo UPS (otestováno), lokální integrace kritických systémů (Modbus TČ/VZT, Aseko local, Victron MQTT, Hikvision NVR), ZFS replikace kritických VM — 2026-07-06 reálně zachránila provoz domu, bazen_* alert automatizace jako vzor, log_monitor.py honest-failure design, ftv_export_apply read-back vzor.