NFSv4-Mini-Howto

Aus DebianforumWiki

Wechseln zu: Navigation, Suche
WikiDateiserver ‹ NFSv4-Mini-Howto

Review.png Review: Dieser Artikel ist für das Review freigegeben.


Inhaltsverzeichnis

Einführung

Das Network File System – abgekürzt NFS (auch Network File Service) – ist ein von Sun Microsystems entwickeltes Protokoll, das den Zugriff auf Dateien über ein Netzwerk ermöglicht. Über die Jahre sind verschiedene Versionen des Protokolls entwickelt worden; derzeit ist die Version 4 („NFSv4“) aktuell.

NFS stammt konzeptionell aus einer Zeit zentral administrierter Netze, innerhalb derer alle Clients grundsätzlich vertrauenswürdig sind. Genau so kann man es heute noch einem Heimnetz einsetzen; keinesfalls darf man NFS auf diese Art und Weise aus dem Internet erreichbar machen.

NFSv4 bringt gegenüber den Vorgängerversionen mehrere wesentliche Neuerungen mit sich:

  • User und Gruppen müssen auf Server und Client nicht mehr zwingend übereinstimmende numerische UID und GID haben. Sofern beide Rechner der gleichen Domain angehören, erfolgt eine automatische Übersetzung.
  • NFSv4 nutzt TCP statt UDP.
  • Anstelle zufälliger Ports werden fest 111 und 2049 verwendet.
  • Das Locking von Dateien ist Bestandteil des Protokolls; Hilfsprotokolle wie NLM werden nicht mehr benötigt.

Weitere allgemeine Erklärungen zu NFS und zur Geschichte kann man bspw. auf Wikipedia nachlesen.

Diese Anleitung zeigt die Einrichtung eines NFSv4-Servers und -Clients in einem Heimnetz mit vertrauenswürdigen Clients. Es werden bewusst nur ausgewählte Optionen erklärt. Andere NFS-Versionen, fortgeschrittene Optionen und Tuning sowie die Absicherung mit Kerberos werden nicht betrachtet. Grundlegende Kenntnisse über die Installation von Paketen und die Handhabung von systemd werden vorausgesetzt.

Diese Anleitung wurde für Debian 9 „Stretch“ verfasst, sollte sich in Teilen aber auch für andere Versionen sowie Derivate (Ubuntu usw.) verwenden lassen.

NFSv4-Server einrichten

Exportverzeichnisse aufbauen

Das Bereitstellen von Dateisystemen im Netz wird in NFS-Terminologie „exportieren“ genannt und ein so bereitgestelltes Dateisystem „Export“. Vielfach werden aber auch die Samba-Begriffe „freigeben“ und „Freigabe“ verwendet.

Die Dokumentation spricht eindeutig vom Export von Dateisystemen und nicht von Verzeichnissen, wenngleich es möglich ist, nur einzelne Verzeichnisse eines Dateisystems zu exportieren. Die Dateisysteme werden nicht direkt exportiert; statt dessen wird eine Hierarchie von Dateisystemen bspw. unter /srv (oder /export) aufgebaut. Die zu exportierenden Dateisysteme werden dort eingehängt.

Sind die zu exportierenden Dateisysteme bereits woanders eingehängt oder sollen einzelne Verzeichnisse eines Dateisystems exportiert werden, so werden dafür in /srv Verzeichnisse als Mountpoints angelegt und das zu exportierende Dateisystem oder Verzeichnis dort mit mount -o bind eingehängt.

Installation

Der Server wird mit dem Paket nfs-kernel-server installiert. Das Paket liegt in main.

Einrichten der Exporte

Allgemeines

In der /etc/exports wird jeder Export in einer Zeile definiert, die folgenden Aufbau hat:

Mountpoint_des_Exports Client1(Optionen) Client2(Optionen) …

Ein Client kann ein einzelner Host, ein IP-Netzwerk, Wildcards u.ä. sein.

Kommentare beginnen mit einem #.

Hier als Beispiel eine exports-Datei, bei der /srv ein Verzeichnis auf dem Wurzeldateisystem des Servers ist. Auf die darin liegenden Verzeichnissen sind btrfs-Subvolumes gemountet. Der Server befindet sich im internen Netz 192.168.178.0/24.

/srv            192.168.178.0/24(ro,sync,all_squash,no_subtree_check,fsid=root)
/srv/music      192.168.178.0/24(ro,sync,all_squash,no_subtree_check) ugly(rw,sync,root_squash,no_subtree_check)
/srv/photo      192.168.178.0/24(ro,sync,all_squash,no_subtree_check) ugly(rw,sync,root_squash,no_subtree_check)
/srv/public     192.168.178.0/24(rw,sync,all_squash,no_subtree_check)
/srv/video      192.168.178.0/24(ro,sync,all_squash,no_subtree_check) ugly(rw,sync,root_squash,no_subtree_check)
/srv/VirtualBox ugly(rw,sync,root_squash,no_subtree_check)

Im folgenden werden die oben angegebenen Optionen erläutert. Ein Weglassen einer Option bewirkt die Nutzung einer Vorgabe. Das Weglassen von Optionen wird mitunter in den Logs protokolliert. Wenn man diese Hinweise nicht sehen möchte, empfiehlt es sich, die Option explizit (wie oben geschehen) anzugeben. Außerdem können sich Vorgaben im Zeitablauf ändern; durch die Festlegung stellt man ein gleichbleibendes Verhalten sicher.

Eine vollständige Erläuterung der Syntax und der Optionen findet sich in der Manpage 5 exports. Beim Lesen der Manpage sollte man aufmerksam unterscheiden zwischen den verschiedenen NFS-Versionen. Nicht alle Optionen sind für alle NFS-Versionen anwendbar.

Die Auswahl der NFS-Version geschieht nicht in der /etc/exports, sondern am Client.

Nach Änderungen an der /etc/exports muss diese über systemctl reload nfs-kernel-server neu geladen werden.

Option ro/rw

Mit dieser Option wird gesteuert, ob das Dateisystem lesbar (rw) oder nicht (ro) exportiert wird.

Vorgabe: ro

Option sync/async

Diese Option steuert, wie der Server der Server auf Requests antwortet bzw. wann er die Kontrolle an die Userspace-Anwendung zurückgibt. Bei async antwortet der Server sofort und nicht erst, wenn die Daten auf Platte geschrieben wurden. Das kann den Datentransfer signifikant beschleunigen, birgt aber des Risiko des Datenverlusts bei Absturz des Servers in sich.

Das Weglassen dieser Option erzeugt eine Warnmeldung.

Vorgabe: sync

User-ID-Mapping („Squashing“)

Mit Squashing kann der auf dem Client verwendete Nutzer/Gruppe „gesquasht“, d.h. auf dem Server durch einen anderen (i.d.R. den anonymen) Nutzer/Gruppe ersetzt werden. Es gibt drei Möglichkeiten:

  • root_squash: Zugriffe von root werden auf den anonymen Nutzer/Gruppe gesquasht. root bedeutet hier UID/GID 0; die Zugriffe weiterer administrativer User und Gruppen (sudo, adm usw.) werden nicht gesquasht.
  • no_root_squash: Zugriffe von root werden nicht gesquasht.
  • all_squash: alle Zugriffe werden durch den anonymen Nutzer/Gruppe ersetzt.

Vorgabe: root_squash

Die UID/GID, auf die gesquasht wird, kann über die Optionen anonuid und anongid je Export eingestellt werden. Die globale Voreinstellung findet sich in der Datei /etc/idmapd.conf.

„Squashing“ hat nichts mit der Sportart zu tun, sondern bedeutet im Englischen u.a. „unterdrücken“.

Subtree Checking

Unter Subtree Checking versteht man die Prüfung, ob eine Datei tatsächlich in dem exportierten Dateisystem liegt. Das Abschalten dieser Option hat geringfügige Auswirkungen auf die Sicherheit, kann aber Geschwindigkeitsvorteile bringen. Weitere Details stehen in der Manpage.

Das Weglassen dieser Option erzeugt eine Warnmeldung.

Vorgabe: no_subtree_check

Option fsid

Diese Option hat zwei Aufgaben:

  • NFS unterscheidet die zu exportierenden Dateisysteme anhand ihrer UUID. Falls ein Dateisystem keine UUID besitzt, kann hier eine vorgegeben werden.
  • Das „Wurzelverzeichnis“ der Exporte, in diesem Beispiel /srv, muss in der /etc/exports mit fsid=root (alternativ: fsid=0) gekennzeichnet werden.

Optionen crossmnt und nohide

Bei Angabe von crossmnt werden unterhalb der Wurzel eingehängte Dateisysteme mit identischen Optionen automatisch exportiert. Dies kann unerwünscht sein, wenn Dateisysteme eingehängt sind, die nicht oder mit anderen Optionen exportiert werden sollen.

  • Wenn man alle unterhalb der Wurzel eingehängten Dateisysteme identisch exportieren möchte, ist es ausreichend, die Wurzel mit der Option crossmnt zu exportieren.
  • Ansonsten lässt man die Option weg und exportiert neben der Wurzel die weiteren Dateisysteme mit ihren jeweiligen Optionen. Die Mountpoints nicht exportierter Dateisysteme sind am Client als leere Verzeichnisse sichtbar.

Die Option nohide ist unter NFSv4 ohne Wirkung.

Interpretation der Beispiel-exports-Datei

/srv            192.168.178.0/24(ro,sync,all_squash,no_subtree_check,fsid=root)

/srv wird mit fsid=root als Wurzel gekennzeichnet. Grundsätzlich sind alle Exporte, d.h. der Inhalt des Verzeichnisses /srv mit den dort gemounteten Dateisystemen für alle Clients im lokalen Netzwerk nur lesbar sichtbar. Da die Option crossmnt nicht zur Anwendung kommt, sind die Mountpoints der untergeordneten Dateisysteme, nicht aber deren Inhalt, sichtbar, sofern diese Dateisysteme nicht explizit exportiert werden. Sämtliche Zugriffe werden auf die anonyme UID/GID gesquasht.

/srv/music      192.168.178.0/24(ro,sync,all_squash,no_subtree_check) ugly(rw,sync,root_squash,no_subtree_check)

Dieses Dateisystem wird im lokalen Netzwerk nur lesbar exportiert. So können bspw. Medienserver darauf zugreifen. Sämtliche Zugriffe werden auf die anonyme UID/GID gesquasht. Der Rechner ugly darf auch schreiben; hier wird nur root gesquasht.

/srv/public     192.168.178.0/24(rw,sync,all_squash,no_subtree_check)

Dieses Dateisystem wird im lokalen Netzwerk schreibbar exportiert. Sämtliche Zugriffe werden gesquasht.

/srv/VirtualBox ugly(rw,sync,root_squash,no_subtree_check)

Dieses Dateisystem wird für den Client ugly exportiert. Alle anderen Clients sehen ein leeres Verzeichnis.

NFSv4-Client einrichten

Im folgenden wird beschrieben, wie man per NFS exportierte Dateisysteme an einem Client per systemd-automount einbindet.

Installation

Für die Nutzung von NFS-Exporten muss das Paket nfs-common aus main installiert werden.

Automount à la systemd

Ein systemd-Automount bewirkt, dass das tatsächliche Einhängen erst in dem Moment passiert, in dem auf den Mountpoint zugegriffen wird. Das ist bei NFS-Mounts durchaus gewünscht: wenn der Mountversuch im Bootvorgang zu früh, d.h. vor Bestehen der Netzwerkverbindung durchgeführt wird, kann der Bootvorgang hängen. (systemd und NetworkManager können leider nicht wirklich gut miteinander.) Umgekehrt kann man über einen Automount steuern, dass nach einer bestimmten Zeitspanne ohne Zugriff ein automatischer Umount erfolgt.

Mount und Automount lassen sich in der /etc/fstab auch in einer Zeile definieren, die Definition über separate Units ist jedoch übersichtlicher.

Zusammengefasst: wir brauchen

  • eine Mount-Unit, die beschreibt, wie und wo der NFS-Export eingehängt wird,
  • und eine Automount-Unit, die bei Zugriff auf den Mountpoint die Mount-Unit startet. Das bedeutet, dass die Automount-Unit, nicht aber die Mount-Unit enabled wird.

Mount-Unit

Eine Mount-Unit hat nicht die Endung .service, sondern .mount. Der Name der Unit muss dem Namen des Mountpoints entsprechen, wobei die / durch - zu ersetzen sind. Um einen NFS-Export unter /mnt/proliant einzuhängen, muss dieser in einer Mount-Unit namens mnt-proliant.mount definiert werden. Damit der Mount tatsächlich stattfindet, muss die Unit per systemctl enabled bzw. gestartet werden.

Der Aufbau von Mount-Units wird in der Manpage 5 systemd.mount beschrieben.

Im Beispiel hier wird die Mount-Unit nicht enabled, da sie bei Bedarf von der Automount-Unit gestartet werden soll.

Um auf einem Client die zuvor eingerichteten Exporte zu mounten, reicht eine Datei /etc/systemd/system/mnt-proliant.mount mit dem folgenden Inhalt:

[Unit]
Description=Mount /mnt/proliant via NFS

[Mount]
What=proliant:/
Where=/mnt/proliant/
Type=nfs
Options=soft,nfsvers=4,async

Über Type wird das Dateisystem angegeben; hier wird gelegentlich nfs4 genannt, was auch das erwartete (einen Mount via NFSv4) bewirkt. Tatsächlich gibt man hier aber nur nfs an; die Angabe nfs4 ist lt. Manpage veraltet. Die Vorgabe der NFS-Version erfolgt über die Option nfsvers, siehe unten.

Die für einen NFS-Mount vorhandenen Optionen werden in der Manpage 5 exports beschrieben. Auch hier sollte man auf die verwendete NFS-Version acht geben.

Option soft/hard

Über diese Option steuert man, wie der Client auf einen nicht erreichbaren NFS-Server reagiert. Bei hard versucht es der Client unendlich oft, was in einem unendlich lang eingefrorenen Dateimanager resultieren kann. Bei soft lässt der Client seine Versuche nach einer gewissen Zeitdauer fehlschlagen. Das Verhalten lässt sich über die Optionen retrans und timeo (siehe Manpage) genauer steuern.

Für einen Desktop-Rechner empfiehlt es sich, soft zu verwenden und den Parameter timeo nach dem Grad der persönlichen Ungeduld zu setzen.

Vorgabe: hard

Option: nfsvers

Über diese Option lässt sich die Verwendung einer bestimmten NFS-Version erzwingen. Ohne Vorgabe handeln Client und Server die Version beim Mountvorgang aus, wobei sie zunächst Version 4, danach 3 und zum Schluss 2 versuchen. Wenn man eine Protokollversion vorgibt, die der Server nicht unterstützt, so schlägt der Mountversuch fehl.

Die Option vers ist gleichbedeutend zu nfsvers und lt. Manpage für die Kompatibilät mit anderen Betriebssystemen vorgesehen.

Option sync/async

Auch beim Mounten gibt es die Optionen sync und async, die aber etwas ganz anderes bewirken als bei der Definition des Exports. Beim Mount wird über diese Option gesteuert, wann Schreibanforderungen an den Server gesendet werden. Bei sync werden Schreibanforderungen sofort gesendet, bei async dagegen erst zeitverzögert beim Eintreten bestimmter Ereignisse, bspw. beim Schließen der Datei.

Mit sync kann man sicherstellen, dass die Daten auf dem Server stets aktuell sind („größere Datenzwischenspeicherkohärenz“), was nützlich sein kann, wenn mehrere Clients auf den gleichen Datenbestand zugreifen. Allerdings sind damit signifikante Leistungseinbußen verbunden.

Vorgabe: async

Zeitstempel

Allgemeine Mount-Optionen für Zeitstempel wie atime/noatime usw. werden von NFS ignoriert. Angaben bspw. in der /proc/mounts sind unzutreffend. Details zum Umgang mit Zeitstempeln werden in der Manpage 5 nfs erklärt.

Locking

Optionen wie lock/nolock steuern das Locking über das Seitenbandprotokoll NLM. Da NFSv4 dieses nicht nutzt, da das Locking Bestandteil des Protokolls ist, ist diese Option für NFSv4 wirkungslos.

Option intr/nointr

intr wird in vielen älteren Erläuterungen genannt, um ein Einfrieren des Clients bei nicht erreichbarem NFS-Server zu vermeiden. Tatsächlich wird diese Option seit Kernel 2.6.25 ignoriert.

Das Einfrieren kann mit der Option soft (s.o.) nicht verhindert, aber zumindest zeitlich begrenzt werden.

Automount-Unit

Die Automount-Unit startet eine Mount-Unit, wenn der Mountpoint betreten wird. Sie muss den gleichen Namen wie die zugehörige Mount-Unit haben, jedoch mit der Endung .automount. Diese Unit muss enabled und gestartet werden.

Der Aufbau von Mount-Units wird in der Manpage 5 systemd.automount beschrieben.

Für die obige Mount-Unit kann eine Automount-Unit wie folgt aussehen:

[Unit]
Description=Automount /mnt/proliant
Requires=NetworkManager.service
After=network-online.target
Wants=network-online.target

[Automount]
Where=/mnt/proliant
TimeoutIdleSec=10min

[Install]
WantedBy=multi-user.target

Die Angaben entsprechen im Wesentlichen denen einer „normalen” systemd-Unit, weshalb hier nicht weiter darauf eingegangen werden soll.

  • Über Where wird der Mountpoint angegeben, der überwacht werden soll.
  • Über die optionale Angabe TimeoutIdleSec kann man angeben, dass ein Umount versucht werden soll, wenn innerhalb der angebenen Zeitdauer keine Zugriffe stattgefunden haben.

Ergebnis

Die obige Mount-Unit bindet am Server definierte Wurzel der Exporte (also das Verzeichnis /srv) unter /mnt/proliant ein. Die darunter definierten weiteren Exporte werden beim Betreten der entsprechenden Verzeichnisse eingehängt, was man bspw. über df nachverfolgen kann.

Nach dem Systemstart taucht der NFS-Export nicht in der Liste der Mounts auf; erst nach dem ersten Zugriff wird er unter df angezeigt:

jan@ugly:~$ df
Dateisystem           1K-Blöcke   Benutzt Verfügbar Verw% Eingehängt auf
…
proliant:/            109374464  31696384  76109312   30% /mnt/proliant
…

Untergeordnete Exporte werden bei Bedarf eingehängt:

jan@ugly:~$ ls /mnt/proliant/public/
…
jan@ugly:~$ df
Dateisystem            1K-Blöcke    Benutzt Verfügbar Verw% Eingehängt auf
…
proliant:/             109374464   31701504  76104192   30% /mnt/proliant
…
proliant:/public      3907017728 3271205888 635655680   84% /mnt/proliant/public
jan@ugly:~$ 

Nach etwas Leerlauf wird /mnt/proliant/public wieder ausgehängt (TimeoutIdleSec):

jan@ugly:~$ df
Dateisystem           1K-Blöcke   Benutzt Verfügbar Verw% Eingehängt auf
…
proliant:/            109374464  31696384  76109312   30% /mnt/proliant
…
jan@ugly:~$ 

Ein umount von /mnt/proliant bewirkt einen umount aller untergeordneten Exporte.

Sonstiges und Problemlösungen

Rechner hängt beim Runterfahren

Beim Runterfahren des Rechners kommt es leider oftmals zu einem „Hänger“, da NetworkManager die Netzwerkverbindung vor dem Umount der NFS-Exporte trennt. Der Hänger wird nach einiger Zeit von systemd per Timeout beendet und der Rechner fährt weiter runter.

User und Gruppen unterschiedlich auf Client und Server

Dies geschieht, wenn Client und Server unterschiedlichen Domains angehören, nachprüfbar anhand von hostname --fqdn. Die Domain, die NFSv4 annimmt, kann bei Bedarf explizit in der /etc/idmapd.conf festgelegt werden.

Weblinks

Meine Werkzeuge