NFS-Server ########## Ziel: Dateitransfer mit dem Network File System (NFS) durchführen, Bereitstellung eines Netzwerkdateisystemes, das Unix-Clients bequem mounten können. (Freie Windows-Clients sind rar, eine Möglichkeit ist unter http://nekodrive.software.informer.com/ zu finden.) Ein paar wichtige Eckpunkte: * NFS stammt von der 1982 gegründeten Firma SUN Microsystems, 1984 gelang ihr mit diesem Protokoll der Durchbruch in der Unix-Welt * Es wird als verteiltes Dateisystem bezeichnet; wenn ein beteiligter Server wegbricht, können allerdings automatische Failover-Aktionen nicht wie bei Ceph oder DFS stattfinden * Client/Server-Anwendung: der Server exportiert einen Teil seines Dateisystemes, der Client importiert es durch einen klassischen Mountvorgang * Transparente Arbeitsweise: auf die entfernte Ressource wird über einen lokalen Ordner zugegriffen (--> systemweit einheitlicher Namensraum) * Bis Version 3 benutzt NFS das verbindungslose UDP, die aktuelle Version 4 verwendet TCP und behebt damit kleinere Probleme, ist aber dadurch nicht mehr ganz so schnell * Bis Version 3 authentifizieren sich Benutzer via User-ID-Mapping, ab Version 4 ist außerdem Authentifizierung mittels Kerberos möglich * NFS benötigt Remote Procedure Calls (RPC), die sich auf OSI-Schicht 5 um das Zuordnen von lokalen und entfernten UDP/TCP-Ports kümmern und ein initiales Filehandle einrichten * RPC wird bis NFSv3 mit dem Dienst 'portmap' realisiert (UDP/2049), ab NFSv4 über 'rpcbind' (TCP/2049) * Die NFSv3-Daemons rpc.mountd, rpc.lockd und rpc.statd werden von NFSv4 nicht mehr verwendet (feste Integration im Kernel), dafür aber gibt es jetzt ein Listening am TCP-Port 2049 * Rollen: - Server = der Exporteur (Datei: '/etc/exports', Tool: ``exportfs``) - Client = der Importeur (Kommando ``mount -t nfs Server:Pfad Mountpunkt``) Installation unter Debian ************************* Die Installation ist schnell durchgeführt. Falls nicht schon vorhanden, wird der zugrundeliegende Portmapper (Paket 'rpcbind') automatisch mit installiert, ebenso wie der NFS-Client (Paket 'nfs-common'): ``apt-get install nfs-kernel-server`` Der NFS-Daemon startet sich aber nicht automatisch, wie sonst unter Debian üblich, es sei denn, es existiert bereits in der Konfigurationsdatei eine gültige Freigabe. Als weitere Voraussetzung muss der Kernel NFS unterstützen; das Dateisystem wird dann in der Datei ``/proc/filesystems`` mit aufgelistet. Bei selbst kompilierten Kerneln fehlt diese Option oft! NFSv3-kompatible Freigaben ************************** Die Konfigurationsdatei bearbeitet man mit ``vi /etc/exports`` Für NFSv3 reicht im einfachsten Fall nur eine Zeile, die das Verzeichnis '/srv/pub' für alle Rechner '*' schreibfähig (rw) freigibt, wobei Änderungen sofort auf die Festplatte geschrieben werden (sync), außerdem sollen Dateirechte nicht rekursiv geprüft werden (no_subtree_check), was sich nur bei reinen Heimatverzeichnissen lohnt:: /srv/pub *(rw,sync,no_subtree_check) Nach dem Anlegen des Verzeichnisses mit ``mkdir -m 777 /srv/pub`` muss der NFS-Dienst gestartet werden: ``/etc/init.d/nfs-kernel-server start`` **Eine Freigabe mit NFSv3 clientseitig einbinden** Ob der Server erreichbar ist und was er exportiert, kann auf dem Client via Netzwerk mittels ``showmount -e server`` überprüft werden. Das Mounten in den normalerweise leeren Ordner '/mnt' gelingt dann mit ``mount -o vers=3 server:/srv/pub /mnt`` Für NFSv3 ist hierbei die Option 'vers=3' ausschlaggebend, was bedeutet, dass als Transportprotokoll das schnellere UDP verwendet wird. Zum automatischen Mounten beim Bootvorgang editieren wir die Datei '/etc/fstab': ``vi /etc/fstab`` Als Mountpunkt legt man z.B. vorher einen Ordner '/media/pub' an und schreibt:: server:/srv/pub /media/pub nfs soft,bg 0 0 Die Option 'soft' verhindert ein Hängenbleiben des Clients beim Bootvorgang, falls der Server nicht erreichbar ist; mit 'bg' versucht er es im Hintergrund weiter. Nach dem Abspeichern der Änderungen kann ein Reboot mittels ``mount -a`` simuliert werden. Freigaben mit NFSv4 ******************* Grundsätzlich kann die bisherige Konfiguration mit der einen Zeile in der '/etc/exports' beibehalten werden. Ein moderner NFS-Client benutzt dann automatisch NFSv4, wenn er beim Mounten die Versions-Option 'vers=3' weglässt. Damit kann man allerdings nicht alle Features des neuen Protokolls ausnutzen, wie z.B. das automatische Einhängen aller Freigaben unter einem bestimmten NFS-Wurzelverzeichnis. Die Konfigurationsdatei ist zuerst einmal wieder die alte: ``vi /etc/exports`` Idealerweise deklariert man für NFSv4 zuerst in einer extra Zeile einen Ordner als NFS-Wurzelpunkt; das wichtigste Kennzeichen ist 'fsid=0'. Die zweite Zeile definiert dann die eigentliche Freigabe, auf die der Client später in relativer Schreibweise beim Mounten zugreift (im Beispiel einfach nur mit 'pub', ohne führenden Slash):: /srv/nfs4 *(rw,sync,fsid=0,crossmnt,no_subtree_check) /srv/nfs4/pub *(rw,sync,no_subtree_check) Nach dem Anlegen des Verzeichnisses mit ``mkdir -p -m 777 /srv/nfs4/pub`` muss der NFS-Dienst neu gestartet werden: ``/etc/init.d/nfs-kernel-server restart`` **Eine Freigabe mit NFSv4 clientseitig einbinden** Ob der Server erreichbar ist und was er exportiert, kann auf dem Client wiederum mittels ``showmount -e server`` überprüft werden. Das Mounten in den Ordner '/mnt' gelingt dann in kürzerer Schreibweise mit ``mount server:pub /mnt`` Für NFSv4 ist hierbei zu beachten, dass lediglich der betreffende Freigabeordner als RELATIVER PFAD (hier: 'pub') zur NFS-Wurzel (hier: '/srv/nfs4') direkt nach dem Doppelpunkt angegeben wird! Zum automatischen Mounten beim Bootvorgang editieren wir wieder die Datei 'fstab': ``vi /etc/fstab`` Als Mountpunkt verwenden wir nach einem 'umount /media/pub' wieder den selben Ordner, die betreffende Zeile sieht jetzt so aus:: server:pub /media/pub nfs4 soft,bg 0 0 Nach dem Abspeichern der Änderungen kann ein Reboot mittels ``mount -a`` simuliert werden. Freigaben mit 'exportfs' erstellen ********************************** Das Kommando 'exportfs' ist das eigentliche Tool im Backend, was die Freigaben erzeugt. Voraussetzung ist aber, dass bereits einige Daemons am Start sind: :: $ ps aux | grep -E 'nfsd|mountd' root 3969 0.0 0.6 12748 2136 pts/1 S+ 20:21 0:00 grep -E nfsd|mountd $ $ rpc.nfsd $ rpc.mountd $ $ ps aux | grep -E 'nfsd|mountd' root 3973 0.0 0.0 0 0 ? S< 20:21 0:00 [nfsd4] root 3974 0.0 0.0 0 0 ? S< 20:21 0:00 [nfsd4_callbacks] root 3978 0.0 0.0 0 0 ? S 20:21 0:00 [nfsd] root 3979 0.0 0.0 0 0 ? S 20:21 0:00 [nfsd] root 3980 0.0 0.0 0 0 ? S 20:21 0:00 [nfsd] root 3981 0.0 0.0 0 0 ? S 20:21 0:00 [nfsd] root 3982 0.0 0.0 0 0 ? S 20:21 0:00 [nfsd] root 3983 0.0 0.0 0 0 ? S 20:21 0:00 [nfsd] root 3984 0.0 0.0 0 0 ? S 20:21 0:00 [nfsd] root 3985 0.0 0.0 0 0 ? S 20:21 0:00 [nfsd] root 3987 0.0 1.5 40956 5416 ? Ss 20:21 0:00 rpc.mountd root 3989 0.0 0.6 12748 2132 pts/1 S+ 20:21 0:00 grep -E nfsd|mountd $ $ rpcinfo -p | grep 2049 100003 2 tcp 2049 nfs 100003 3 tcp 2049 nfs 100003 4 tcp 2049 nfs 100227 2 tcp 2049 100227 3 tcp 2049 100003 2 udp 2049 nfs 100003 3 udp 2049 nfs 100003 4 udp 2049 nfs 100227 2 udp 2049 100227 3 udp 2049 $ Im Beispiel soll nun das Verzeichnis /tmp lesend und schreiben freigegeben werden: :: $ exportfs -o rw *:/tmp Zur Kontrolle geben wir dann folgendes ein: :: $ showmount -e localhost Export list for localhost: /tmp * Will man alle Exporte mit einem Mal entfernen, schreibt man einfach: :: $ exportfs -ua Clientseitge Einbindung *********************** Mit der Option 'vers=3' nutzen wir explizit die zwar alte, aber dank UDP schnellere Version 3: :: $ showmount -e d8squid Export list for d8squid: /tmp * $ $ mount -o vers=3 d8squid:/tmp /tmp/mnt/ $ $ echo 123 > /tmp/mnt/datei-von-root $ $ su - tux $ echo 123 > /tmp/mnt/datei-von-tux ACHTUNG: Der Benutzer root wird immer auf *nobody* gequetscht (Default Option: *root\_squash*): :: $ ls -ltrc /tmp/ | tail -5 insgesamt 2 -rw-r--r-- 1 nobody nogroup 4 Nov 21 20:27 datei-von-root -rw-r--r-- 1 tux tux 4 Nov 21 20:28 datei-von-tux $ Fehlersuche *********** Fehler können sich natürlich an vielen Stellen ergeben, z.B. durch nicht vorhandene Verzeichnisse oder nicht laufende bzw. nicht neu gestartete Daemons. Zu Diagnosezwecken kommt neben dem bereits bekannten Kommando 'showmount' das speziell für RPC geeignete Kommando 'rpcinfo' in Frage: ``rpcinfp -p client`` ``rpcinfp -p server`` Damit lässt sich kontrollieren, ob die Remote Procedure Calls auf dem Client (ca. 8 Prozesse sichtbar, vor allem 'portmapper') sowie auf dem Server (ca. 30 Prozesse, neben 'portmapper' auch 'nfs' und 'mountd') zur Verfügung stehen. Probleme treten oft durch Firewalls auf, insbesondere mit NFSv3. Dank der NFS-Wurzel-Option 'fsid=0' wird das zu importierende Dateisystem nicht als lokales Blockgerät mit Major- und Minor-Nummer bzw. UUID betrachtet, sondern einfach mit der Dateisystem-ID 0 ausgestattet. Dadurch werden nervende "stale NFS mounts" vermieden, deren Ursache in nicht mehr erreichbaren NFS-Servern liegen.