CT-101 Samba + PVE-Host: NFS auf den Host verlagert, Host per Ansible verwaltet
- CT 101 kennt NFS nicht mehr: samba_nfs-Rolle und Ganesha-Artefakte entfernt, kein Podman, keine 2049-Firewall-Regel, kein seccomp-Sondereintrag; live restlos bereinigt und deckungsgleich mit dem Playbook (verify ok=47, Idempotenz changed=0). Dafür neue SMB-Freigabe [Encoding] (Export-Root) für die Kontrolle von anderen Geräten als ghostnet-ki. - Grund: Weder kernel-nfsd noch Ganesha (VFS-FSAL) laufen in einem unprivileged LXC — open_by_handle_at braucht CAP_DAC_READ_SEARCH in der init-userns und liefert dort immer EPERM (verifiziert auf Kernel 7.0.14-14-pve; Web-Recherche: NFS direkt auf dem PVE-Host ist gängige Praxis und anerkannte Ausnahme vom Host-Grundsatz). - Neuer Account ansible-deploy (UID 1001) auf dem PVE-Host 10.0.0.2 nach LXC-Muster: gelocktes Passwort, source-restrictierter passphrase-loser Key (nur pub im Repo), NOPASSWD-Sudoers; Host-Key-Fingerprint verifiziert. - Neues Host-Projekt proxmox/pve-host/ansible (Schema wie die CT-Projekte): preflight/site.yml/verify-production + Rollen pve_nfs_export (Kernel-NFS, /etc/exports nur 10.0.0.90/32, NFSv4-only, Export-Root 100000:970 2775, nft 2049 nur von 10.0.0.90) und pve_lxc_conf (seccomp-Leerzeile aus 101.conf entfernt). Auf dem Host grün: check changed=0, verify ok=15, Idempotenz changed=0. - Abnahme bestanden: NFSv4.2-Mount von ghostnet-ki gegen 10.0.0.2:/media/datenhdd3/Encoding (Export-Root 100000:970 2775 sichtbar), sauberer Unmount. CT 101 nach Reboot: Seccomp 2, keine failed units, 17 Shares, 10 CIFS-Mounts der Workstation hängen. - Doku aktualisiert: GNAI-017 §4.1 und GNAI-019 E2/E3/§15 revidiert, Bereichsindex ergänzt, READMEs angepasst; PVE-Lifecycle-Skripte ohne seccomp-Ausnahme (Hashes aktualisiert). Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
@@ -18,6 +18,7 @@ Hypervisors selbst.
|
||||
| [GNAI-018 / CT 101](lxc/ct-101-samba/GNAI-018-REQ_Encoding-Pipeline-Integration.md) | Requirements der Encoding-Pipeline an CT 101 für den Ansible-Rebuild (Übergabe) |
|
||||
| [GNAI-019 / CT 101](lxc/ct-101-samba/GNAI-019-DEC_Ansible-Migration.md) | Entwurfsentscheidungen der Ansible-Migration: natives Samba, NFS-Ganesha als Quadlet, Fresh-State-Rebuild |
|
||||
| [CT-101-Automation](../../../proxmox/lxc/ct-101-samba/README.md) | produktives Samba-Ansible-Projekt und CT-spezifische PVE-Helfer |
|
||||
| [PVE-Host-Automation](../../../proxmox/pve-host/README.md) | Ansible-Verwaltung des PVE-Hosts selbst (`10.0.0.2`): Deploy-Account, Kernel-NFS-Export, LXC-Conf |
|
||||
|
||||
Die versionierte Quelle für den optionalen, secretfreien
|
||||
Community-Scripts-Post-install-Hook liegt unter
|
||||
|
||||
@@ -59,29 +59,37 @@ guests = yes`, `obey pam restrictions = yes`.
|
||||
|
||||
### 4.1 NFS-Export
|
||||
|
||||
Ursprünglich war `nfs-kernel-server` mit `/etc/exports` geplant. **Überholt
|
||||
durch GNAI-019 Entscheidung 2 und 3:** Der Kernel-NFS-Server ist in einem
|
||||
unprivileged LXC nicht betreibbar; der Export läuft stattdessen als
|
||||
**NFS-Ganesha** in einem rootful Podman-Quadlet-Container
|
||||
(`ghostnet-samba-nfs.service`, Host-Networking, NFSv4-only). Dafür wird in
|
||||
`/etc/pve/lxc/101.conf` ein leerer `lxc.seccomp.profile:`-Eintrag gesetzt
|
||||
(Ganesha braucht `open_by_handle_at`). Umsetzung: Rolle `samba_nfs` plus die
|
||||
PVE-Skripte `scripts/upgrade-ct101-to-debian13.sh` (Adoption) und
|
||||
`scripts/provision-ct101-samba.sh` (Fresh-State-Rebuild).
|
||||
**Korrektur 30.10.2026:** Der Export läuft als **Kernel-NFS
|
||||
(`nfs-kernel-server`) auf dem PVE-Host** — umgesetzt via
|
||||
`Host-Projekt `proxmox/pve-host/ansible/` (Rolle `pve_nfs_export`)` (idempotent, versioniert im Repo).
|
||||
Zuvor war Ganesha-in-CT-101 geplant; das ist in einem unprivileged LXC nicht
|
||||
möglich (`open_by_handle_at` braucht CAP_DAC_READ_SEARCH in der init-userns
|
||||
und liefert dort immer EPERM — verifiziert 30.10.2026 auf Kernel
|
||||
7.0.14-14-pve; der leere `lxc.seccomp.profile:`-Eintrag war dafür nicht
|
||||
ausreichend). Web-Recherche zu Proxmox-Best-Practices (30.10.2026): NFS direkt
|
||||
auf dem Host ist gängige Praxis zum Teilen von Host-Storage und eine
|
||||
anerkannte Ausnahme vom Grundsatz „keine Extra-Services auf dem Host";
|
||||
Reproduzierbarkeit bleibt durch das versionierte Script gewährleistet.
|
||||
|
||||
- Export ausschließlich für `ghostnet-ki` (10.0.0.90), NFSv4.2-only (TCP+UDP),
|
||||
`SecType = sys`, Standard-Squash bleibt aktiv (`Squash = rootid`): Die
|
||||
rootless Container schreiben als UID 982/983, nicht als root. Kein NFSv3,
|
||||
kein mountd/rpcbind — `showmount` gilt nicht; Abnahme ist ein realer
|
||||
NFSv4.2-Mount von `ghostnet-ki` (GNAI-018 Abschnitt 4 Punkt 2, angepasst).
|
||||
- Mount auf `ghostnet-ki`: `/var/lib/ghostnet-encoding` (NFSv4.2, `hard`,
|
||||
`_netdev`, `noatime`) — verwaltet vom Encoding-Ansible (GNENC-001 Abschnitt 6).
|
||||
- Vorab wird nur das Export-Verzeichnis `/media/datenhdd3/Encoding` angelegt
|
||||
(`root:gn-media 2775` — Abweichung von root:root 0755: Die Pipeline erzeugt
|
||||
die Top-Level-Verzeichnisse via NFS als UID 982/983 und braucht group-write
|
||||
plus setgid auf dem Export-Root); die Pipeline-Unterverzeichnisse werden via
|
||||
NFS von `ghostnet-ki` durch die Ansible-Rolle angelegt (Owner/Group gemäß
|
||||
GNENC-002 Abschnitt 4).
|
||||
- Export ausschließlich für `ghostnet-ki` (`10.0.0.90/32`) via `/etc/exports`
|
||||
(`rw,sync,no_subtree_check,root_squash`), **NFSv4-only** (NFSv2/v3 auf dem
|
||||
Host abgeschaltet). `showmount` gilt nicht; Abnahme ist ein realer
|
||||
NFSv4.2-Mount von `ghostnet-ki` gegen die PVE-Host-IP.
|
||||
- Mount auf `ghostnet-ki`: `/var/lib/ghostnet-encoding`
|
||||
(`mount -t nfs -o nfsvers=4.2,hard,noatime <pve-host-ip>:/media/datenhdd3/Encoding …`)
|
||||
— verwaltet vom Encoding-Ansible (GNENC-001 Abschnitt 6; die Mount-Quelle
|
||||
ändert sich von `10.0.0.9` auf die PVE-Host-IP).
|
||||
- Export-Root `/media/datenhdd3/Encoding` auf dem Host: `100000:970 2775`
|
||||
(100000 = CT-101-Gast-root, damit die SMB-Freigabe `[Encoding]` aus CT 101
|
||||
schreiben kann; GID 970 = `gn-media`, group-write + setgid für die Pipeline-
|
||||
Identitäten via AUTH_SYS). Die Pipeline-Unterverzeichnisse entstehen via NFS
|
||||
von `ghostnet-ki` (Owner/Group gemäß GNENC-002 Abschnitt 4).
|
||||
- Host-Firewall: 2049 tcp+udp nur von 10.0.0.90 (nft-Tabelle
|
||||
`ghostnet_host_nfs`, sofern pve-firewall den Host nicht verwaltet).
|
||||
- CT 101 kennt NFS nicht mehr: keine `samba_nfs`-Rolle, kein Podman, keine
|
||||
2049-Regel in der CT-Firewall, kein seccomp-Eintrag in `/etc/pve/lxc/101.conf`.
|
||||
Dafür SMB-Freigaben `[Encode]`, `[Encode-In]` und `[Encoding]` (Root) für die
|
||||
Pipeline und die Kontrolle von anderen Geräten.
|
||||
|
||||
### 4.2 Gruppen- und UID-Abgleich
|
||||
|
||||
|
||||
@@ -66,59 +66,48 @@ ist als Jinja2-Template im Repository gepflegt (Entscheidung 8).
|
||||
Konfigurationsänderung; Post-State-Verifikation per `testparm`, `pdbedit -L`
|
||||
und anonymer `smbclient -L`-Abfrage.
|
||||
|
||||
## 4. Entscheidung 2: NFS-Export via NFS-Ganesha als rootful Podman-Quadlet mit Host-Networking (statt `nfs-kernel-server`)
|
||||
## 4. Entscheidung 2: NFS-Export als Kernel-NFS auf dem PVE-Host (revidiert 30.10.2026)
|
||||
|
||||
**Entscheidung:** Der NFS-Export für die Encoding-Pipeline (GNAI-018 R1) wird
|
||||
nicht mit `nfs-kernel-server`, sondern mit **NFS-Ganesha** als **rootful**
|
||||
Podman-Quadlet-Container (`ghostnet-samba-nfs.service`) mit **Host-Networking**
|
||||
umgesetzt. Dafür wird in `/etc/pve/lxc/101.conf` ein **leerer
|
||||
`lxc.seccomp.profile:`**-Eintrag gesetzt (Deaktivierung des LXC-Seccomp-Filters
|
||||
für den gesamten CT).
|
||||
**Entscheidung (revidiert):** Der NFS-Export für die Encoding-Pipeline
|
||||
(GNAI-018 R1) läuft als **Kernel-NFS (`nfs-kernel-server`) auf dem
|
||||
Proxmox-Host**, exportiert `/media/datenhdd3/Encoding` exklusiv für
|
||||
`ghostnet-ki` (`10.0.0.90/32`), NFSv4-only — umgesetzt durch das idempotente,
|
||||
versionierte Script `Host-Projekt `proxmox/pve-host/ansible/` (Rolle `pve_nfs_export`)` (siehe
|
||||
`scripts/README.md`). CT 101 kennt NFS nicht mehr: keine `samba_nfs`-Rolle,
|
||||
kein Podman, keine 2049-Firewall-Regel, kein `lxc.seccomp.profile:`-Eintrag.
|
||||
Dafür stellt CT 101 die SMB-Freigaben `[Encode]`, `[Encode-In]` und
|
||||
`[Encoding]` (Root) für die Pipeline bzw. die Kontrolle von anderen Geräten.
|
||||
|
||||
**Begründung:**
|
||||
**Begründung:** Weder Kernel-nfsd noch NFS-Ganesha (VFS-FSAL) können in einem
|
||||
unprivileged LXC laufen: `open_by_handle_at` — für Ganesha zwingend nötig —
|
||||
erfordert `CAP_DAC_READ_SEARCH` in der init-userns und liefert im unprivileged
|
||||
LXC immer EPERM (verifiziert 30.10.2026 auf Kernel 7.0.14-14-pve; der leere
|
||||
Seccomp-Eintrag der ursprünglichen Planung war dafür nicht ausreichend).
|
||||
Web-Recherche zu Proxmox-Best-Practices (30.10.2026): NFS direkt auf dem
|
||||
PVE-Host ist gängige Praxis zum Teilen von Host-Storage und eine anerkannte
|
||||
Ausnahme vom Grundsatz „keine Extra-Services auf dem Host“; die
|
||||
Reproduzierbarkeit des Host-Änderung ist durch das versionierte Script im
|
||||
Repository gegeben. virtiofs/9p scheiden aus, weil `ghostnet-ki` eine eigene
|
||||
physikalische Maschine im LAN ist.
|
||||
|
||||
- GNAI-018 R1 verlangte `nfs-kernel-server`. Der Kernel-NFS-Server kann in
|
||||
einem unprivileged LXC nicht betrieben werden (kein Zugriff auf das
|
||||
Kernel-NFS-Subsystem des Hosts). Ganesha ist ein Userspace-NFS-Server (VFS
|
||||
FSAL) und läuft in einem unprivileged LXC.
|
||||
- **Rootful** ist fachlich nötig: Der VFS-FSAL wendet die AUTH_SYS-Credentials
|
||||
der Pipeline (UID 982/983) pro Request an; das erfordert `CAP_SETUID`/
|
||||
`CAP_SETGID` innerhalb der LXC-User-Namespace, was ein rootless Container
|
||||
nicht leisten kann. Standard-Squash bleibt aktiv (`Squash = rootid`, R1).
|
||||
- **Host-Networking** bindet den Listener 2049 im Netz-Namespace von CT 101;
|
||||
die nftables-Input-Chain deckt ihn ab. Die Quadlet-Unit trägt
|
||||
`Requires=nftables.service` — ohne Firewall startet der Export nicht
|
||||
(fail closed).
|
||||
- **Leerer Seccomp-Eintrag:** Ganesha benötigt `open_by_handle_at` (VFS FSAL),
|
||||
das das PVE-Standard-Seccomp-Profil blockiert. Der leere Eintrag deaktiviert
|
||||
den Filter für den gesamten CT. Das ist vertretbar, weil der CT unprivileged
|
||||
bleibt und Samba nativ keine privilegierten Syscalls jenseits der
|
||||
User-Namespace benötigt. Beide PVE-Skripte setzen bzw. verifizieren den
|
||||
leeren Eintrag (`scripts/upgrade-ct101-to-debian13.sh`,
|
||||
`scripts/provision-ct101-samba.sh`).
|
||||
- **Abweichung vom Export-Root aus R1:** Statt `root:root 0755` wird
|
||||
`/media/datenhdd3/Encoding` als `root:gn-media 2775` angelegt. Die Pipeline
|
||||
erzeugt die Top-Level-Verzeichnisse via NFS als UID 982/983 und benötigt
|
||||
group-write plus setgid auf dem Export-Root (GNAI-017 Abschnitt 4.4); die
|
||||
Pipeline-Unterverzeichnisse selbst entstehen weiterhin via NFS durch die
|
||||
Rolle `video_encoding` auf `ghostnet-ki`.
|
||||
|
||||
**Konsequenz:** PVE-seitige Änderung am produktiven CT (Seccomp) — im
|
||||
Upgrade-Skript durch einen `vzdump --mode stop` abgesichert. Die
|
||||
Quadlet-Unit folgt dem CT-100/102-Pattern: digest-gepinntes Debian-13-Basisimage
|
||||
(`debian:trixie-slim`), sha256-gepinntes `Containerfile.ganesha`,
|
||||
`Pull=never`, Runtime-Tag `localhost/ghostnet/ganesha:trixie-ansible1`,
|
||||
Healthcheck, read-only rootfs mit tmpfs `/run` und `/tmp`. Ohne dbus logged
|
||||
Ganesha eine nicht-fatale Admin-Interface-Warnung (dokumentiert in
|
||||
`roles/samba_nfs/README.md`).
|
||||
**Konsequenz:** Host-seitige Änderung (Paket `nfs-kernel-server`,
|
||||
`/etc/exports`, ggf. Host-Firewall 2049 nur von 10.0.0.90), abgesichert durch
|
||||
eine Confirmation-Env-Variable; CT-Upgrades bleiben durch `vzdump` gesichert.
|
||||
Export-Root auf dem Host: `100000:970 2775` (100000 = CT-101-Gast-root für den
|
||||
SMB-Zugriff aus CT 101; GID 970 = `gn-media` group-write + setgid für die
|
||||
Pipeline-Identitäten via AUTH_SYS). Der Ganesha-Ära-Eintrag
|
||||
`lxc.seccomp.profile:` in `/etc/pve/lxc/101.conf` wird entfernt — CT 101 läuft
|
||||
wieder mit Default-Seccomp wie CT 100/102/103. Mount auf `ghostnet-ki`:
|
||||
`/var/lib/ghostnet-encoding` via `<pve-host-ip>:/media/datenhdd3/Encoding`
|
||||
(NFSv4.2; die Mount-Quelle wechselt von `10.0.0.9` auf die Host-IP).
|
||||
|
||||
## 5. Entscheidung 3: NFSv4-only — kein NFSv3, kein `showmount`
|
||||
|
||||
**Entscheidung:** Der Export ist NFSv4-only (`Protocols = 4`, kein NLM, kein
|
||||
RQUOTA, kein mountd/rpcbind), Transport TCP+UDP, `SecType = sys`,
|
||||
`Squash = rootid`, client-beschränkt auf `10.0.0.90`, `Pseudo` identisch zum
|
||||
Export-Pfad (dokumentierter Mount-Pfad `10.0.0.9:/media/datenhdd3/Encoding`
|
||||
bleibt unverändert).
|
||||
**Entscheidung:** Der Export ist NFSv4-only (NFSv2/v3 auf dem Host
|
||||
abgeschaltet, kein mountd/rpcbind), Transport TCP+UDP, `root_squash` (Default),
|
||||
client-beschränkt auf `10.0.0.90/32` in `/etc/exports`. Mount-Pfad auf
|
||||
`ghostnet-ki`: `<pve-host-ip>:/media/datenhdd3/Encoding` (host-seitig seit der
|
||||
Revision 30.10.2026, nicht mehr `10.0.0.9`).
|
||||
|
||||
**Begründung:** NFSv4 benötigt keinen Portmapper und kein mountd — weniger
|
||||
Angriffsfläche und keine Legacy-Protokolle. Die Pipeline mountet NFSv4.2
|
||||
@@ -126,8 +115,9 @@ Angriffsfläche und keine Legacy-Protokolle. Die Pipeline mountet NFSv4.2
|
||||
|
||||
**Konsequenz:** `showmount -e` ist kein zulässiges Abnahmekriterium
|
||||
(NFSv4-only). GNAI-018 Abschnitt 4 Punkt 2 wird als **realer NFSv4.2-Mount-Test
|
||||
von `ghostnet-ki`** interpretiert; dasselbe gilt für Punkt 8 (Dienste nach
|
||||
Reboot: `ghostnet-samba-nfs.service` statt `nfs-kernel-server`).
|
||||
von `ghostnet-ki` gegen den PVE-Host** interpretiert; dasselbe gilt für Punkt 8
|
||||
(Dienste nach Reboot: `nfs-kernel-server` auf dem PVE-Host statt
|
||||
`ghostnet-samba-nfs.service` in CT 101).
|
||||
|
||||
## 6. Entscheidung 4: Identität — `gn-media` GID 970, aufgezeichnete Medien-UIDs, Mitgliedschaft nur `ghost`
|
||||
|
||||
@@ -342,6 +332,12 @@ dieselbe Person auf Medien-/SMB-Ebene ist nicht erforderlich.
|
||||
`smb.conf` (inkl. `admin users` auf elf Shares, `write list` auf
|
||||
`[Dokumente]`/`[Extern]`; `[Serien2]` ohne `force user/group`), damit die
|
||||
Konvergenz keine produktiven Share-Rechte ändert.
|
||||
- **Revision 30.10.2026:** Entscheidung 2/3 revidiert — der NFS-Export läuft
|
||||
als Kernel-NFS auf dem PVE-Host (`Host-Projekt `proxmox/pve-host/ansible/` (Rolle `pve_nfs_export`)`),
|
||||
nicht als Ganesha-Quadlet in CT 101 (`open_by_handle_at` → EPERM im
|
||||
unprivileged LXC, verifiziert). GNAI-017 Abschnitt 4.1 entsprechend
|
||||
aktualisiert; `samba_nfs`-Rolle, Podman, 2049-Regel und seccomp-Eintrag aus
|
||||
CT 101 entfernt; SMB-Freigabe `[Encoding]` (Root) ergänzt.
|
||||
|
||||
## 16. Offene Punkte
|
||||
|
||||
|
||||
Reference in New Issue
Block a user