NFS - Network File System

ArticleCategory:

System Administration

AuthorImage:

TranslationInfo:

Original in fr Frédéric Raynal

fr to en Philippe Trbich and Emmanuel Bonnel

en to de Katja Socher

AboutTheAuthor:

Frédéric Raynal schreibt an seiner Diplomarbeit in Informatik über Bildertätowierung an der INRIA. Er liest gerade einen sehr guten Detektivroman, der auf Th. Roosevelt zu Beginn des letzten Jahrhunderts anspielt, als er Polizeipräfekt war. Die Atmosphäre ist sehr dunkel. Es geht um die Untersuchung einer Gruppe von Personen, um einen Serienmörder zu finden, der Kinder verletzt. Die Gruppe wird von neuen Technologien unterstützt (Psychologie, Fingerabdrücke, etc...), um die Lösung zu finden. Der Roman von Caleb Carr, L'ange des ténèbres, zeichnet ein überraschendes Bild über den Beginn des letzten Jahrhunderts.

Abstract:

A Ein Network File System (NFS) erlaubt das Verwalten von Dateien auf mehreren Computern innerhalb eines Netzwerkes so, als ob sie auf der lokalen Festplatte gespeichert wären. Dadurch ist es nicht nötig zu wissen, wo die Dateien physikalisch gespeichert sind, um auf sie zuzugreifen.

ArticleIllustration:

ArticleBody:

Einführung

NFS erlaubt auf einfache Weise, Daten zwischen mehreren Computern zu teilen. Zum Beispiel muß sich ein Benutzer, der in einem Netzwerk eingeloggt ist, nicht auch noch auf einem speziellen Computer einloggen: über NFS hat er Zugriff auf sein home directory (wir sagen exportiert) auf der Maschine, auf der er gerade arbeitet.

NFS ist kein sehr effizientes Protokol und deshalb sehr langsam über eine Modemverbindung. Es wurde für ein lokales Netzwerk entwickelt und ist sehr flexibel. Es bietet eine Menge Möglichkeiten für Benutzer und Administratoren.

Du mußt diesen Dienst mit Vorsicht verwalten. Jedem zu erlauben, Daten in dein Netz zu schreiben, wäre keine gute Politik ;-) Einige essentielle Maßnahmen reduzieren dieses Risiko.

Dieser Artikel beginnt mit einer sehr kurzen Einführung zu Dateisystemen. Dann schauen wir uns das NFS Protokol an. Danach geht es zum weniger theoretischen Teil und wir führen eine NFS Server und eine Client Installation durch. Wir werden uns auch die minimalen Sicherheitsvorkehrungen anschauen, die man treffen sollte. Dann illustrieren wir an einem Beispiel, wie man NFS, NIS und autofs kombinieren kann.
 

Allgemeine und nicht-erschöpfende Darstellung von Dateisystemen

Bevor wir über NFS reden, sollte man den Ausdruck Dateisystem verstehen. Ein Dateisystem ist ein Weg, um Daten auf einem Medium zu speichern, der Weg, wie es organisiert und verwaltet wird. Es gibt viele davon, einige sehr oft, andere weniger oft benutzt (New Technology FileSystem (NTFS), High Performance FileSystem (HPFS), DOS, FAT 12/16/32, VFAT, Macintosh Hierarchical Filesystem (HFS), ISO 9660 (für CD-ROM), extended file systems (Ext, Ext2, Ext3),und viele andere).

Zum Beispiel können wir jedes physikalische Medium für Daten (eine Festplatte z.B.) als Feld von kleinen Einheiten, die Informationen speichern, betrachten: wir reden über Blöcke. Jedes Dateisystem verwaltet diese Blöcke auf verschiedene Weise. Zum Beispiel versuchen wir in Abbildung 1 eine Datei einzufügen, die zwei Blöcke benutzt. Auf der oberen Illustration wurde die Datei hinter den letzten besetzten Block gesetzt, wobei leere Stellen am Anfang auftreten. Im unteren Teil des Bildes (ein anderes Dateisystem) wurde es an die erste freie Stelle gesetzt. Diese Politik hat Einfluß darauf, wie stark eine Platte fragmentiert wird. Einige Dateisysteme vermeiden Fragmentierung automatisch, während andere von Hand defragmentiert werden müssen.
 
 


Fig. 1 : 2 different ways to place blocks





Das bekannteste Dateisystem unter Linux ist ext2fs (extended 2 file system). Jede Datei wird durch eine Inode1 dargestellt. Verzeichnisse speichern die Dateiliste und der Zugriff geschieht durch Operationen wie lesen/schreiben auf besondere Dateien.

Die Aufgabe des NFS Servers ist es, seinen Clienten die Inoden zu geben, auf die sie zugreifen möchten. Allerdings würde ein Client nur allein mit den Dateiinoden nicht sehr gut arbeiten. Ein NFS Server gibt eine zusätzliche Netzschicht, die es remote-Rechnern erlaubt, Inoden zu handhaben.

Das NFS Protokol

Was wir gewöhnlich NFS nennen, setzt sich aus 4 verschiedenen Protokollen zusammen. Jedes hängt von Remote Procedure Calls(RPC) und portmap (auch rpc.portmap genannt) ab. Ein portmapper wandelt RPC Programmnummern in Portnummern um. Wenn ein RPC Server startet, erzählt er portmap , welchen Port er benutzen wird und die verwaltete RPC Programmnummer. Wenn ein Client eine RPC Abfrage an eine gegebene Programmnummer senden möchte, kontaktiert er zuerst den Server portmap, um die Portnummer zu bekommen, die ihm Zugang zu dem gewünschten Programm gibt. Dann adressiert er die RPC Pakete an den korrespondierenden Port.

Die 4 Dienste, die es NFS erlauben zu arbeiten, sind:
 
Protokol
Beschreibung
Daemon
nfs Dieses Protokol ist die Basis und erlaubt das Erzeugen von Dateien, Suche, Lesen oder Schreiben. Dieses Protokol verwaltet auch die Autentifizierung und die Dateistatistiken.
nfsd
mountd Dieser ist verantwortlich für das Mounten exportierter Systeme, um auf sie mit nfs zugreifen zu können. nfs.Der Server empfängt Anfragen wie mount und umount und muß auf diese Weise Informationen über exportierte Dateisysteme behalten.
mountd
nsm
(Network Status Monitor) 
Es wird benutzt, um Netzwerknodes zu überwachen, um den Zustand einer Maschine (Client oder Server) zu kennen. Es informiert, z.B. über einen Neustart.
statd
nlm
(Network Lock Manager) 
Um Datenänderungen durch mehrere Clienten zur gleichen Zeit zu vermeiden, verwaltet dieses Protokol ein Locksystem. Es weiß, welche Dateien benutzt werden. Auf diese Weise ist es mit Hilfe des Nsm Protokols möglich zu wissen, wenn ein Client erneut startet. Nsm befreit alle Locks des Clienten, bevor sie zurückgegeben werden.
lockd

Der Daemon knfsd, verfügbar mit den neuesten Kernelversionen, unterstützt direkt die nfs und nlm Protokolle. Andererseits werden mountd und nsm noch nicht unterstützt. Wenn der NFS Server installiert und gestartet wird, können wir mit dem folgenden Befehl verifizieren, daß alles läuft:
 

>> ps auxwww | egrep "nfs|mount|lock|stat"
root      1370  0.0  0.2  1176  580 ?        S    22:28   0:00 rpc.mountd --no-nfs-version 3
root      1379  0.0  0.0     0    0 pts/0    SW   22:28   0:00 [nfsd]
root      1380  0.0  0.0     0    0 pts/0    SW   22:28   0:00 [nfsd]
root      1381  0.0  0.0     0    0 pts/0    SW   22:28   0:00 [nfsd]
root      1382  0.0  0.0     0    0 pts/0    SW   22:28   0:00 [nfsd]
root      1383  0.0  0.0     0    0 pts/0    SW   22:28   0:00 [nfsd]
root      1384  0.0  0.0     0    0 pts/0    SW   22:28   0:00 [nfsd]
root      1385  0.0  0.0     0    0 pts/0    SW   22:28   0:00 [nfsd]
root      1386  0.0  0.0     0    0 pts/0    SW   22:28   0:00 [nfsd]
root      1399  0.0  0.0     0    0 pts/0    SW   22:28   0:00 [lockd]
root      1409  0.0  0.2  1156  560 ?        S    22:28   0:00 rpc.statd
root      1652  0.0  0.1  1228  484 pts/3    S    22:49   0:00 egrep nfs|mount|lock|stat
Momentan sind 2 NFS Versionen verfügbar (Versionen 2 und 3 - sie werden NFSv2 bzw. NFSv3 genannt, um sie zu unterscheiden). Linux's NFS Server unterstützen nur Version 2 (daher die Option auf der mountd Zeile im vorhergehenden Beispiel).

Bei NFS geht es um eine Datenstruktur, die file handle genannt wird. Es ist eine Bitserie, die auf eindeutige Weise erlaubt, jedes Dateisystemobjekt (wie eine Datei, aber nicht nur Dateien) zu identifizieren. Es enthält z.B. die Dateiinode, aber auch einen Eintrag, der das Gerät, wo die Datei sich befindet, enthält. Daher können wir NFS als ein Dateisystem betrachten, das in ein Dateisystem eingebettet ist.

Installation

Der Server

Das erste, was wir tun müssen, wie wir bereits gesehen haben, ist portmap zu starten, da dieses Protokol von NFS gebraucht wird.
root >>/usr/sbin/rpcinfo -p
rpcinfo: can't contact portmapper: RPC: Remote system error - Connection refused
root >>/sbin/portmap
root >>/usr/sbin/rpcinfo -p
   program vers proto   port
    100000    2   tcp    111  portmapper
    100000    2   udp    111  portmapper
Der rpcinfo Befehl zeigt die auf der Maschine laufenden RPC Dienste, spezifiziert als das Argument (-p option). Wir bemerken, daß portmap noch nicht läuft: wir starten es (die meisten Linuxdistributionen enthalten Skripte, um dies beim Starten zu automatisieren) und wir überprüfen, ob es läuft. Ein anderer oft vorkommender Grund für eine negative Antwort auf rpcinfo ist, daß der portmapper nicht antworten darf aufgrund von Sicherheitsrestriktionen in den /etc/hosts.{allow, deny} Verzeichnissen. In diesem Fall füge einen "portmap: hosts" Eintrag zu der hosts.allow Datei hinzu.

Vor dem Starten von NFS selbst, muß es konfiguriert werden. Es gibt nur eine Konfigurationsdatei und sie heißt /etc/exports. Jede Zeile zeigt einen Verzeichnisbaum der exportiert werde soll gefolgt von einer Liste von Clienten, die auf ihn zugreifen dürfen. Es ist möglich, am Ende jedes Clientennamens Optionen hinzuzufügen. Die man exports page erklärt die Syntax für Clientennamen und Optionen.

Die akzeptierten Formen für Clientennamen sind:

Wir werden hier nicht detailliert alle verfügbaren mount Optionen beschreiben, aber hier sind die wichtigesten: Wir müssen jetzt rpc.mountd und rpc.nfs daemons starten, um einen laufenden NFS Server zu bekommen. Wir überprüfen nochmal mit dem rpcinfo Befehl, daß alles läuft. Wir können den Server sogar für die nsm und nlm Protokolle initalisieren ( rpc.statd bzw. rpc.lockd). Sie sind aber nicht unbedingt notwendig, um einen NFS Server laufen zu lassen... aber stark empfohlen im Fall, daß eine Maschine ausfällt, von selbst rebootet, etc...

Wenn wir die /etc/exports Konfigurationsdatei ändern, müssen wir die betroffenen Daemons informieren, daß Änderungen gemacht wurden. Der exportfs Befehl übermittelt diese Information an unsere Server. Die -r Option synchronisiert die /etc/mtab2 Datei mit der /etc/exports Datei. Die -v Option zeigt die exportierten Dateisysteme zusammen mit ihren Optionen.

Nach dem Start enthalten die folgenden Dateien wichtige Informationen:

Wenn ein Client auf ein Dateisystem zugreifen möchte, fängt er damit an, mountd zu fragen. Er sucht dann in etab, ob die Abfrage verfügbar ist. Er überprüft den Kernel, um zu wissen, ob der Client zu dieser Abfrage berechtigt ist (check hosts.{allow, deny}, firewall rules, ...). Der Kernel benutzt exportfs für die Überprüfung, er ist berechtigt die /var/lib/nfs/etab Datei upzudaten. Wenn in dieser Datei das exportierte System berechtigt ist, zu der Gruppe, zu der der Client gehört, exportiert zu werden, dann informiert mountd den Kernel, der daraufhin xtab mit dem neuen host updatet.

Der Client

Hier gibt es nichts zu tun ... normalerweise. Der Zugriff auf ein Dateisystem, das von NFS exportiert wurde, wird direkt vom Kernel verwaltet. Es muß mit Unterstützung für NFS kompiliert worden sein. Die Datei /proc/filesystems listet alle Dateisysteme auf, die direkt vom Kernel unterstützt werden. Man muß dann nur dem Kernel sagen, daß man Zugriff auf ein von NFS exportiertes System haben möchte.

Der mount Befehl berechtigt zum Zugriff auf verschiedene Dateisysteme. Es informiert den Kernel, daß ein neues Dateisystem verfügbar ist, mit Angabe seines Typs, des device und seinem Mountpunkt. Die -t  Option kann dazu benutzt werden, um den Typ des benutzten Dateisystems zu spezifizieren. Für NFS schreiben wir: -t nfs.

mount hat seine eigenen Optionen für NFS. Zum Beispiel können die Optionen rsize und wsize dazu benutzt werden, um die Blockgrößen für Lesen und Schreiben zu ändern. Man kann NFS spezifische Optionen mit allgemeineren Optionen wie intr, noexec oder nosuid verbinden. Die mount man page listet alle diese Optionen auf.

Laßt uns annehmen, der Rechner charly hat einen NFS Server und exportiert sein /usr/local Verzeichnis. Wenn man darauf vom Rechner jill aus zugreifen will, dann muß man nur das exportierte Vrzeichnis von charly zu jill mounten:

root@jill >> mount -t nfs -o nosuid,hard,intr charly:/usr/local /usr/local
Der Befehl zeigt an, daß wir ein NFS Dateisystem mounten (-t nfs), mit den nosuid, hard und intr Optionen. Die beiden letzten Argumente sind die interessantesten. Das erste spezifiziert das zu mountende device. Für NFS ist die Syntax anders als in der gewöhnlichen mount Befehlszeile, wo man den device und das Verzeichnis spezifiziert. Hier spezifizieren wir server:exported_directory anstelle von einem device. Das letzte Argument zeigt die Stelle des Dateisystems auf der Clientenseite an. Wir teilen einfach charlys /usr/local mit jill und können dadurch vermeiden, Programme mehr als einmal in /usr/local zu installieren. Um dies permanent zu machen, können wir es auf jill in der /etc/fstab Datei spezifizieren. fstab enthält alle devises, die beim Start gemounted werden müssen. Die Syntax für /etc/fstab lautet:
 
#    device           mount point   file system   options     dump  fsckorder
charly:/usr/local    /usr/local       nfs       nosuid,hard,intr    0      0

Sei jedoch mit permanenten Einträgen vorsichtig. Man kann es nur benutzen, wenn der Server (charly) immer an ist oder vor jill eingeschaltet wird.

Vorsicht

Ein großes Problem mit NFS rührt aus der Tatsache, daß per default ein vertrauensvolles Verhältnis zwischen Client und NFS Server besteht. In dem Fall, daß der root account des Servers kompromittiert wird, wird auch der des Clienten kompromittiert. Das NFS-HOWTO beschreibt einige essentielle Maßnahmen, die aus Sicherheitsgründen ergriffen werden müssen.

Ein Client darf nicht blind einem Server trauen und umgekehrt, deshalb müssen wir einschränkende Optionen spezifizieren, wenn wir den mount Befehl benutzen. Wir haben die erste schon erwähnt: nosuid. Es macht den SUID und SGID bits Effekt rückgängig. Das heißt, eine als root eingeloggte Person auf dem Server muß sich zuerst als Benutzer auf dem Clienten einloggen und wird erst dann root. Eine andere, restriktivere Option ist noexec. Es verbietet das Ausführen von Programmen auf exportierten Dateisystemen. Diese Option ist nur auf Systemen nutzbar, die nur Daten enthalten.

Auf der NFS Serverseite können wir ebenso spezifizieren, daß wir dem root account des Clienten nicht trauen. Wir müssen dies in /etc/exports mit der root_squash Option spezifizieren. Dann, wenn ein Benutzer mit UID 0 (root) auf dem Clienten auf das Dateisystem, das vom Server exportiert wurde, zugreift, wird er der nobody UID für Abfragedateien. Diese Option ist per default unter Linux aktiv, kann aber mit der no_root_squash Option abgeschaltet werden. Eine Menge von UIDs kann spezifiziert werden, auf die diese Option angewendet werden soll. Erinnere dich auch, daß die anonuid und anongid Optionen es erlauben, die Benutzer UID/GID von nobody zu einer anderen ID zu ändern.

Einige Aktionen sind allgemeiner und haben Auswirkungen auf den portmapper. Zum Beispiel verbieten wir den Zugriff zu allen Rechnern mit der folgenden Zeile in der /etc/hosts.deny Datei:

# hosts.deny :
#              use the portmap
portmap: ALL


Die /etc/hosts.allow Datei stellt das Gegengewicht zu diesem strikten Verbot dar und erlaubt den Zugriff auf die gewünschten Maschinen.

Gute Firewallregel tragen auch zu einem besseren Schutz bei. Beobachte die Ports, die von verschiedenen Diensten genutzt werden und die genutzten Protokolle:
 

Service RPC Port Protocols
portmap 111 upd / tcp
nfsd 2049 udp
mountd variable udp / tcp

Benutzen von NIS, NFS und autofs

Jetzt betrachten wir ein kompliziertes Netzwerk wie man es z.B. in einem Unternehmen findet. In einem kleinen Netzwerk zu Hause wirst du wahrscheinlich in der Lage sein, ohne NIS zu leben. NIS Network Information Service ist ein Weg, um Konfigurationsdateien (z.B. in /etc) auf andere Maschinen zu veteilen.
Der Hauptserver in unserem Netzwerk ist "charly" und 3 andere Maschinen des Netzwerkes sind "sabrina", "jill" und "kelly". Wir konfigurieren charly als NIS Server für die Domain bosley. Die anderen Maschinen sind nur NIS Clienten von charly (wir sollten einen NIS Slave Server haben, aber dies ist heute nicht unser Thema).

Laß uns zuerst die Konfiguration unseres Servers charly anschauen. Wir beginnen mit dem Definieren einiger NIS maps, die alle notwendigen Informationen enthalten.

Die /etc/netgroup Datei enthält Maschinengruppen mit gemeinsamen Charakteristiken (z.B. dieselbe Architektur). Eine NIS map ist für NFS sehr nützlich. Wir müssen nur alle Maschinen sammeln, die berechtigt sind, auf dasselbe exportierte Dateisystem zuzugreifen. Diese Gruppe wird dann in der /etc/exports Datei benutzt, anstatt alle Clienten einzeln zu spezifizieren:

# /etc/netgroup
charlysangels (sabrina,,) (jill,,) (kelly)
 Soweit wie es NFS betrifft, wissen wir, daß die Konfiguration sehr eingeschränkt ist. Die /etc/exports Datei von charly enthält:
# /etc/exports
/usr/local    @charlysangels(ro)
Wir entscheiden uns automount zu benutzen, um auf das exportierte /usr/local Verzeichnis zuzugreifen. Anstatt dieses System zur Boot-Zeit zu mounten, geschieht es automatisch, wenn ein Benutzer auf eine Datei in diesem Verzeichnis zugreift.  Wir erzeugen die /etc/auto.map Datei, um zu definieren, was zugreifbar sein wird, sowohl durch automount als auch durch NIS:
# /etc/auto.map
charly          charly:/usr/local
Da wir diese Informationen (die neuen auto.map und netgroup Dateien) in die NIS Datenbank integrieren wollen, müssen wir das Makefile ändern, bevor wir es erneut bauen. Wir müssen sicher sein, daß netgroup in die Datenbank hinzugefügt wird. Was auto.map betrifft, so wird diese Datei nicht per default definiert. Wir müssen nur einfach einen neuen Eintrag in das Makefile hinzufügen, mit der assoziierten Regel (benutzen der existierenden als ein Modell):
#To be added in the Yellow Pages Makefile
AUTO_MAP    = $(YPSRCDIR)/auto.map
# ...
#...
auto.map: $(AUTO_MAP) $(YPDIR)/Makefile
            @echo "Updating $@..."
            -@sed -e "/^#/d" -e s/#.*$$// $(AUTO_MAP) | $(DBLOAD) \
            -i $(AUTO_MAP) -o $(YPMAPDIR)/$@ - $@
            -@$(NOPUSH) || $(YPPUSH) -d $(DOMAIN) $@
Diese Produktionsregel entfernt nur Kommentare, fügt einen neuen Eintrag in die Datenbank hinzu und übermittelt dann die Information zu jedem Server.

Wir müssen nur make aus dem /var/yp Verzeichnis laufen lassen.

Jetzt zu unseren drei Clienten sabrina, jill und kelly. Here, Hier gibt es nichts zu tun :) Wir müssen autofs sagen, daß es eine neue map, die von YP gegeben wird, verwalten soll. In jeder /etc/auto.master Datei des Clienten informiert die folgende Zeile über die Anwesenheit von einem map auto.map , erhalten durch die YP Dienste.

#/etc/auto.master
/usr/local    yp auto.map    --intr,nosuid,nodev
Dann müssen wir autofs erneut starten, damit die neue map wirksam wird.

Jetzt haben wir ein einziges /usr/local physikalisches Verzeichnis auf charly. Dann, wenn spezifische Programme auf charly installiert werden, können alle Maschinen sie nutzen.

Dieses Beispiel könnte weitergehen mit der Installation nur eines /usr Systems, /usr/doc oder anderem, aber die Praxis zeigt, daß dies keine gute Idee ist. Installationen müssen oft Dateien im /etc Verzeichnis oder anderes verändern. Wir müßten dann alle Maschinen ändern, um nicht exportierte Dateien upzudaten und das wird schnell langweilig.
 

Referenzen

Dateisysteme


NFS



Fußnoten

... inode1
Es ist ein File-descriptor (eine Anreihung von Bits), der u.a. Dateizugriffsberechtigungen, Eigentümer, physikalische Blockadressen, die Daten speichern, etc... enthält
... /etc/mtab2
Diese Datei enthält eine Liste aller Dateisysteme, die vom Kernel gemountet werden, ob hart (via mount, wie die Einträge in fstab) oder über den Automounter (autofs/automount).