# DAN-25 — zamknięcie dostępu do baz na NFS (TrueNAS SCALE) Bazy interpretacyjne leżą na `192.168.1.34:/mnt/Tank1/astrololo`. Dziś udział jest osiągalny z całej sieci, więc **kto ma dostęp do LAN, bierze kompletne bazy w oryginale — z pominięciem logowania, limitów, audytu i canary**. Żadne zabezpieczenie w kodzie tego nie zamyka: to najkrótsza droga do wycieku. Cel: udział `astrololo` widoczny **tylko dla trzech węzłów k3s**, **tylko do odczytu**, z **root_squash**. ## ⚠️ Zasada nadrzędna: ruszamy WYŁĄCZNIE udział astrololo Tank1 obsługuje cały homelab — Proxmox (`proxmox-NFS`), conjurera (`conjurer_swap`, z **zapisem**), media, LXC-e, stację roboczą. **Nie dotykamy globalnych ustawień usługi NFS ani innych udziałów** — inaczej wywalimy VM-y, bota i bibliotekę mediów. Każda komenda niżej celuje w jeden konkretny udział. Druga zasada: **w TrueNAS SCALE nie edytuje się `/etc/exports` ręcznie.** Plik generuje middleware i nadpisze każdą ręczną zmianę. Wszystko robimy przez `midclt` (albo GUI: *Shares → Unix (NFS) Shares*). ## Ustalone dane | Co | Wartość | |---|---| | NAS | `192.168.1.34` (TrueNAS SCALE / Community Edition) | | Udział do zamknięcia | `/mnt/Tank1/astrololo` | | Węzły k3s (jedyni uprawnieni) | `192.168.1.73` (server), `192.168.1.80` (agent2), `192.168.1.81` (agent1) | | Kto montuje astrololo | wyłącznie pod `data` w ns `astrololo`, **read-only** | --- ## Faza 0 — rozpoznanie (nic nie zmienia) ```bash ssh admin@192.168.1.34 ``` Wersja systemu (potwierdza, że komendy niżej pasują): ```bash midclt call system.version ``` Lista udziałów NFS z ich obecnymi ustawieniami — **stąd bierzemy ID udziału astrololo**: ```bash midclt call sharing.nfs.query | python3 -m json.tool ``` > W wyniku poszukaj wpisu ze ścieżką `/mnt/Tank1/astrololo` i zapamiętaj jego `id`. > **Sprawdź też, jak nazywają się pola** (`path` vs `paths`, `hosts`, `networks`, > `ro`, `maproot_user`, `mapall_user`) — middleware zmieniało ich nazwy między > wersjami SCALE. Dalsze komendy używają nazw z Twojego wyniku. Kto jest teraz podłączony (żeby nie odciąć czegoś w trakcie pracy): ```bash ss -tn state established '( sport = :2049 )' ``` ## Faza 1 — dowód dziury (zrób PRZED zmianą) Na **stacji roboczej** (Mac mini, czyli host spoza klastra): ```bash mkdir -p /tmp/nfs-test && sudo mount -t nfs -o ro,vers=3 192.168.1.34:/mnt/Tank1/astrololo /tmp/nfs-test ``` ```bash ls -la /tmp/nfs-test | head ``` Jeśli widzisz pliki baz — **to jest dokładnie problem, który zamykamy**. Odmontuj: ```bash sudo umount /tmp/nfs-test ``` ## Faza 2 — kopia obecnej konfiguracji (możliwość cofnięcia) Na NAS-ie, podstaw `` z Fazy 0: ```bash midclt call sharing.nfs.query '[["id","=",]]' > /root/astrololo-nfs-share.backup.json && cat /root/astrololo-nfs-share.backup.json ``` ## Faza 3 — zawężenie udziału Jedna komenda ustawia wszystkie trzy zabezpieczenia naraz: listę hostów, tylko odczyt i root_squash. Podstaw ``: ```bash midclt call sharing.nfs.update '{"hosts": ["192.168.1.73", "192.168.1.80", "192.168.1.81"], "ro": true, "maproot_user": null, "maproot_group": null, "mapall_user": null, "mapall_group": null}' ``` Co robi każdy element: | Ustawienie | Znaczenie | |---|---| | `hosts` | eksport **tylko** dla trzech węzłów k3s — reszta LAN przestaje widzieć udział | | `ro: true` | tylko odczyt; aplikacja i tak montuje read-only, więc niczego nie łamie | | `maproot_*`, `mapall_*` = `null` | **root_squash**: root z klienta nie jest rootem na udziale | Zastosuj i sprawdź, że middleware przepisał eksporty: ```bash midclt call service.reload nfs && exportfs -v | grep -A1 astrololo ``` > Jeśli Twoja wersja nie ma `service.reload`, użyj GUI (*Shares → NFS → zapisz*), > co wymusi to samo. ## Faza 4 — weryfikacja (wszystkie cztery testy) **1. Spoza klastra ma NIE działać.** Na Macu: ```bash sudo mount -t nfs -o ro,vers=3 192.168.1.34:/mnt/Tank1/astrololo /tmp/nfs-test ``` Oczekiwane: `access denied` / `Operation not permitted`. **Jeśli montuje się dalej — zmiana nie zadziałała, nie idź dalej.** **2. Z węzła klastra ma działać.** ```bash ssh 192.168.1.73 'sudo mount -t nfs -o ro 192.168.1.34:/mnt/Tank1/astrololo /mnt/test && ls /mnt/test | head -3 && sudo umount /mnt/test' ``` **3. Aplikacja żyje.** Pody muszą wstać i realnie czytać bazy: ```bash kubectl -n astrololo rollout restart deploy/data && kubectl -n astrololo rollout status deploy/data ``` ```bash kubectl -n astrololo exec deploy/data -- ls /app/data_files | head -3 ``` **4. Reszta homelabu nietknięta** — conjurer (zapis!) i pozostałe udziały: ```bash kubectl -n conjurer get pods ``` ```bash midclt call sharing.nfs.query | python3 -c "import sys,json;[print(s.get('path') or s.get('paths'), '| hosts:', s.get('hosts'), '| ro:', s.get('ro')) for s in json.load(sys.stdin)]" ``` Oczekiwane: **tylko** astrololo ma zawężone `hosts` i `ro: true`; reszta bez zmian. ## Faza 5 — wycofanie (gdyby coś padło) ```bash midclt call sharing.nfs.update '{"hosts": [], "ro": false}' ``` ```bash midclt call service.reload nfs ``` To przywraca poprzedni stan (pełna kopia w `/root/astrololo-nfs-share.backup.json`). --- ## Pułapki, o których warto wiedzieć **Hookscript Proxmoxa.** Na Proxmoxie działa `wait-truenas.sh`, który przed startem VM czeka w pętli na `showmount -e 192.168.1.34`. Zawężamy tylko udział astrololo, więc `showmount` nadal zwróci pozostałe eksporty i pętla przejdzie. Mimo to sprawdź po zmianie: ```bash ssh root@pve2 'showmount -e 192.168.1.34' ``` **Aktualizacja baz przestanie działać przez NFS.** Po `ro: true` nikt nie wgra nowych plików baz przez ten udział — również Ty. Do wgrywania użyj GUI TrueNAS, SMB albo SSH bezpośrednio na NAS-ie. To celowe: udział ma być drogą tylko do czytania przez aplikację. **`hosts` przyjmuje adresy IP, nie nazwy** — świadomie, żeby dostęp nie zależał od DNS-u (AdGuard na `.57`). Gdyby doszedł czwarty węzeł k3s, trzeba dopisać jego IP, inaczej pod `data` na nim nie wstanie. **To nie jest uwierzytelnianie.** Lista IP zatrzymuje przypadkowy i oportunistyczny dostęp, ale adres da się podszyć w tej samej sieci. Docelowo (poza zakresem tego kroku): NFSv4 + Kerberos albo przeniesienie plików na wolumen nieosiągalny poza klastrem — tak mówi samo wymaganie DAN-25. ## Po wykonaniu Zaktualizuj status DAN-25 w `docs/astrololo_wymagania.xlsx` na **Zrobione** (albo **W trakcie**, jeśli zostawiasz Kerberosa jako etap docelowy).