Nfs3 Server Grundlagen
NFS Server Version 3
Allgemeines
NFS (Network File System) ist ein Protokoll, mit dem ein Server Verzeichnisse über das Netz freigibt, die Clients wie ein lokales Dateisystem einhängen. Es stammt ursprünglich von Sun Microsystems und ist im Unix-/Linux-Umfeld der Standard für Dateifreigaben.
NFS Version 3 (RFC 1813, 1995) ist trotz NFSv4 weiterhin weit verbreitet, z.B. als Storage für Virtualisierungsplattformen wie Proxmox VE oder VMware, und auf vielen NAS-Systemen.
Eigenschaften von NFSv3
- Zustandslos - der Server merkt sich nicht, welche Clients welche Dateien geöffnet haben. Fällt der Server aus und startet neu, machen die Clients einfach weiter.
- Basiert auf RPC (Remote Procedure Call) - die Funktionen sind auf mehrere Dienste verteilt, die teilweise dynamische Ports benutzen.
- Locking ist ausgelagert - Dateisperren laufen über ein eigenes Protokoll (NLM, Network Lock Manager) und nicht über NFS selbst.
- TCP und UDP - beides möglich, heute wird praktisch nur noch TCP verwendet.
- Authentifizierung über UID/GID (AUTH_SYS) - der Server vertraut den Benutzer- und Gruppennummern, die der Client mitschickt. Es gibt keine echte Benutzeranmeldung.
- 64-Bit-Dateigrößen und asynchrone Schreibvorgänge mit COMMIT - das waren die großen Neuerungen gegenüber NFSv2.
Beteiligte Dienste
| Dienst | Port | Aufgabe |
|---|---|---|
| rpcbind (portmapper) | 111 tcp/udp | Vermittelt, welcher RPC-Dienst auf welchem Port läuft |
| nfsd | 2049 tcp/udp | Der eigentliche NFS-Dienst (Lesen, Schreiben, Verzeichnisse) |
| mountd | dynamisch | Nimmt Mount-Anfragen entgegen und prüft die Exports |
| lockd (NLM) | dynamisch | Dateisperren |
| statd (NSM) | dynamisch | Benachrichtigt nach einem Neustart, damit Sperren wiederhergestellt werden |
| rquotad | dynamisch | Quota-Abfragen (optional) |
Ablauf beim Einhängen:
- Der Client fragt rpcbind auf Port 111, wo mountd läuft.
- Der Client fragt mountd nach dem Export und bekommt ein Filehandle.
- Mit diesem Filehandle spricht der Client nfsd auf Port 2049 an.
Unterschiede zu NFSv4
| Merkmal | NFSv3 | NFSv4 |
|---|---|---|
| Zustand | zustandslos | zustandsbehaftet |
| Ports | 111, 2049 und mehrere dynamische | nur 2049 |
| Locking | separat (NLM) | im Protokoll integriert |
| Authentifizierung | UID/GID | UID/GID oder Kerberos (krb5, krb5i, krb5p) |
| Benutzerzuordnung | numerisch | über Namen (user@domain, idmapd) |
| Firewall | aufwendig | einfach |
| Namensraum | jeder Export einzeln | Pseudo-Dateisystem mit gemeinsamer Wurzel |
Installation
Debian
apt install nfs-kernel-server systemctl enable --now nfs-server
Rocky Linux
dnf install nfs-utils systemctl enable --now nfs-server
Freigaben definieren
Die Freigaben stehen in der Datei /etc/exports. Jede Zeile enthält ein Verzeichnis, gefolgt von den berechtigten Clients mit ihren Optionen in Klammern.
mkdir -p /srv/nfs/daten vi /etc/exports
/srv/nfs/daten 192.168.10.0/24(rw,sync,no_subtree_check) /srv/nfs/iso 192.168.10.0/24(ro,sync,no_subtree_check)
Wichtig: Zwischen Client und Klammer darf kein Leerzeichen stehen. 192.168.10.0/24 (rw) bedeutet etwas völlig anderes: Das Netz bekommt Standardrechte und alle anderen Rechner bekommen rw.
Wichtige Optionen
| Option | Bedeutung |
|---|---|
| rw / ro | Lesen und Schreiben / nur Lesen |
| sync | Server bestätigt Schreibvorgänge erst, wenn sie auf der Platte sind (Standard, sicher) |
| async | Server bestätigt sofort - schneller, aber Datenverlust bei Absturz möglich |
| root_squash | root des Clients wird auf nobody abgebildet (Standard) |
| no_root_squash | root des Clients bleibt root auf dem Server |
| all_squash | alle Benutzer werden auf nobody abgebildet |
| anonuid / anongid | UID/GID, auf die abgebildet wird |
| no_subtree_check | keine Prüfung, ob die Datei im exportierten Unterbaum liegt (empfohlen) |
Exports aktivieren und prüfen
exportfs -ra exportfs -v
NFS auf Version 3 festlegen
In /etc/nfs.conf kann der Server auf bestimmte Versionen beschränkt werden:
[nfsd] vers3=y vers4=n
systemctl restart nfs-server
Ohne diese Einstellung bietet der Server v3 und v4 gleichzeitig an, der Client handelt dann die höchste Version aus.
Feste Ports für die Firewall
Weil mountd, statd und lockd standardmäßig dynamische Ports benutzen, ist NFSv3 hinter einer Firewall unhandlich. Die Ports lassen sich in /etc/nfs.conf festlegen:
[mountd] port=20048 [statd] port=32765 outgoing-port=32766 [lockd] port=32768 udp-port=32768
systemctl restart nfs-server rpc-statd
Kontrolle:
rpcinfo -p
firewalld (Rocky)
firewall-cmd --permanent --add-service={nfs3,mountd,rpc-bind}
firewall-cmd --permanent --add-port={32765-32768/tcp,32765-32768/udp}
firewall-cmd --reload
nftables (Debian)
tcp dport { 111, 2049, 20048, 32765-32768 } ip saddr 192.168.10.0/24 accept
udp dport { 111, 2049, 20048, 32765-32768 } ip saddr 192.168.10.0/24 accept
Client
Paket
apt install nfs-common # Debian dnf install nfs-utils # Rocky
Freigaben anzeigen
showmount -e 192.168.10.20
showmount fragt mountd und funktioniert deshalb nur, wenn der Server NFSv3 anbietet.
Manuell einhängen
mkdir -p /mnt/daten mount -t nfs -o vers=3 192.168.10.20:/srv/nfs/daten /mnt/daten
Kontrolle
nfsstat -m mount | grep nfs
Dauerhaft in /etc/fstab
192.168.10.20:/srv/nfs/daten /mnt/daten nfs vers=3,_netdev 0 0
hard und soft
- hard (Standard) - ist der Server weg, wartet der Client unbegrenzt. Prozesse hängen, aber es gehen keine Daten verloren.
- soft - nach einer Zeitüberschreitung gibt der Client einen Fehler zurück. Kann bei Schreibzugriffen zu kaputten Dateien führen.
Für Daten und VM-Images immer hard verwenden.
NFSv3 als Storage für Proxmox VE
Proxmox erzeugt und bearbeitet die Images als root. Mit root_squash landen die Dateien als nobody und Proxmox bekommt Rechteprobleme. Der Export für Proxmox braucht daher in der Regel no_root_squash:
/srv/nfs/pmx 192.168.10.0/24(rw,sync,no_subtree_check,no_root_squash)
Auf einem Proxmox-Knoten einbinden (gilt für den ganzen Cluster):
pvesm add nfs nfs-daten --server 192.168.10.20 --export /srv/nfs/pmx --content images,iso,backup --options vers=3
Alternativ in der GUI unter Rechenzentrum -> Storage -> Hinzufügen -> NFS, NFS-Version unter Erweitert.
Sicherheit
- NFSv3 hat keine Verschlüsselung - alle Daten gehen im Klartext über das Netz.
- Die Authentifizierung beruht nur auf der IP-Adresse des Clients und den mitgeschickten UID/GID. Wer root auf einem berechtigten Client ist, kann jede UID annehmen.
- no_root_squash nur dort einsetzen, wo es nötig ist (z.B. Hypervisor-Storage), und nur für einzelne Hosts oder ein eigenes Storage-Netz freigeben.
- NFS gehört in ein eigenes, abgeschottetes Netz bzw. VLAN und nie ins Internet.
- Wenn Verschlüsselung oder echte Benutzerauthentifizierung gebraucht wird: NFSv4 mit Kerberos (krb5p).
Fehlersuche
| Befehl | Zweck |
|---|---|
| rpcinfo -p SERVER | welche RPC-Dienste laufen auf welchen Ports |
| showmount -e SERVER | welche Exports bietet der Server an |
| exportfs -v | aktive Exports mit allen Optionen (auf dem Server) |
| nfsstat -m | eingehängte NFS-Freigaben mit Optionen (auf dem Client) |
| journalctl -u nfs-server | Meldungen des Servers |
| tcpdump -n port 2049 or port 111 | Verkehr mitschneiden |
Typische Fehler:
- access denied by server - Client-IP passt nicht zum Eintrag in /etc/exports oder exportfs -ra vergessen.
- Permission denied beim Schreiben - root_squash greift oder UID/GID auf Client und Server passen nicht zusammen.
- Mount hängt - Firewall blockiert 111 oder einen der dynamischen Ports.
- Stale file handle - Export wurde auf dem Server geändert oder neu angelegt, während der Client noch eingehängt war. Client neu einhängen.