Die Grundlagen des Network File System

© photocase.com

NFS ist der Klassiker unter den Netzwerkdateisystemen von Linux. Lesen Sie in diesem Artikel, wie das Dateisystem funktioniert und mit welchen Funktionen NFSv4 für höchste Sicherheit sorgt.

Die Idee hinter NFS ist denkbar einfach: Arbeiten mehrere Rechner in einem Netzwerk zusammen, legt man einen Rechner als Dateisystem-Server fest. Er stellt den zentralen Speicherplatz für die Clients bereit, die diesen – wie unter Linux/Unix üblich – per »mount«-Befehl ins lokale Dateisystem einhängen. Von vielen benötigte Daten können so an einem Ort gepflegt und gesichert werden. Davon profitieren die Clients, die weniger Plattenkapazität brauchen, und der Admin, da er sich beim Backup nur auf den Fileserver konzentrieren muss. Die Benutzer merken im besten Fall (kein Ausfall des Fileservers) überhaupt nicht, dass sich Verzeichnisse und Dateien auf einem anderen Rechner befinden.

Nah und fern

Benutzer spüren bei der Arbeit mit NFS keinerlei Unterschied zwischen lokalen und NFS-Verzeichnissen. Hinter den Kulissen spielen sich hierbei indes grundverschiedene Dinge ab: Lokal gespeicherte Dateien, die in untereinander verketteten Datenblöcken eines Filesystems residieren, finden Programme über die Wurzelblöcke der Kette, die so genannten Inodes. Diese speichern neben der Adresse des ersten Datenblocks eine unverwechselbare Nummer, die Größe des Files, die Zugriffsrechte oder verschiedene Zeitstempel. Diese Angaben lassen sich auf der Kommandozeile mit dem Befehl »stat Dateiname« ausgeben.

Dateioperationen auf einem entfernten Dateisystem erledigt dagegen der Server stellvertretend für den Client. Der entfernte Rechner adressiert das gewünschte File über ein Handle, das er vom Server auf Nachfrage erhält. Zusammen mit dem Handle kann er danach eine von 18 Aktionen in Auftrag geben, die zum Leistungsangebot des NFS-Servers gehören.

Protokoll-Suite

Als Sun NFS 1984 auf den Markt brachte, erschienen zeitgleich eine ganze Sammlung verwandter Protokolle unter dem Namen ONC (Open Network Computing). Abbildung 1 zeigt die ONC-Architektur im Vergleich zu anderen Modellen, von denen sich letztendlich lediglich TCP/IP durchgesetzt hat. NFS befindet sich im ONC-Modell mit anderen Protokollen in der Anwendungsschicht. Hierzu gehört das Protokoll für das File-Locking NLM (Network-Lock-Manager) sowie NSM (Network-Status-Monitor). Die Aufgabe des XDR-Protokolls (External Data Representation) eine Schicht darunter ist es, die zu übertragenden Daten in ein einheitliches Format zu konvertieren. So lassen sich Dateien unabhängig von der eingesetzten Hardware und vom Betriebssystem verarbeiten. Wieder eine Schicht tiefer befindet sich das RPC-Protokoll (Remote Procedure Call [1]). Mittels RPC können Programme Funktionen anderer Programme auf einem entfernten Rechnern nutzen.

Abbildung 1: Im ONC-Modell ist das Network File System auf der Anwendungsschicht angesiedelt (OSI-Schicht 7), XDR auf Schicht 6. Das klassische TCP/IP-Modell fasst die Schichten 5 bis 7 zusammen.

Abbildung 1: Im ONC-Modell ist das Network File System auf der Anwendungsschicht angesiedelt (OSI-Schicht 7), XDR auf Schicht 6. Das klassische TCP/IP-Modell fasst die Schichten 5 bis 7 zusammen.

Vermittlerdienste

Jedes Programm, das Funktionen via RPC anbieten will, muss sich bei einem besonderen Service registrieren, dem Portmapper. Der Portmapper fungiert als Vermittler: Er sammelt die Dienst-Angebote inklusive der Informationen zu Protokoll und dynamisch vergebener Portnummer für die Kontaktaufnahme in einer Datenbank und gibt sie auf Anfrage an die Clients weiter. Der Ablauf ist in Abbildung 2 dargestellt.

Abbildung 2: Der Portmapper fungiert als Kontaktvermittler zwischen RPC-Server und -Client. Der Client erfragt den Port, über den er sich direkt mit dem Server verbinden kann.

Abbildung 2: Der Portmapper fungiert als Kontaktvermittler zwischen RPC-Server und -Client. Der Client erfragt den Port, über den er sich direkt mit dem Server verbinden kann.

Besonders ältere Versionen des Portmapper können leicht Sicherheitsprobleme heraufbeschwören. Neuere lassen sich zumindest darauf verpflichteten, nur Anfragen aus dem lokalen Netz zu beantworten. Diese Einstellung ist auf jeden Fall angeraten. Dazu dienen Einträge im Format »portmap: hosts« in den Dateien »/etc/hosts.deny« sowie »/etc/hosts.allow«. Welche Programme genau der Portmapper kennt und vermittelt, zeigt der Befehl »rpcinfo -p«.

Teamarbeit

Die Arbeit des NFS-Servers teilt sich für gewöhnlich das Duett »mountd« und »nfsd«. Der erste Daemon prüft die Mount-Requests der Clients auf Machbarkeit und Zulässigkeit; Letzterer startet im Wesentlichen eine konfigurierbare Anzahl Kernel-Threads, die dann die eigentlichen NFS-Operationen übernehmen. Fakultativ unterstützt sie der »rquotad«-Daemon bei der Arbeit. Er überwacht die Höchstgrenzen für den belegbaren Plattenplatz pro User. Normalerweise übernimmt ein Init-Skript »nfs« oder »nfsserver« das Starten dieser Dienste. Abhängig von Distribution, NFS- und Kernel-Version müssen unter Umständen auch die beiden Daemonen für das Locking – »lockd« und »statd« – separat gestartet werden.

Ob alle Dienste ordnungsgemäß funktionieren, zeigt die Ausgabe der Befehle »ps -A | grep rpc« und »ps -A | grep nfs«.

Bei aktuellen Distributionen ist der NFS-Daemon Teil des Kernels. Die Ausgabe von »lsmod | grep nfs« muss deshalb ungefähr folgende Module anzeigen, damit der NFS-Sever richtig funktioniert:

nfsd         196624  9
exportfs       4992  1 nfsd
lockd         60008  2 nfsd
nfs_acl        3584  1 nfsd
sunrpc       130364  9 nfsd,lockd,nfs_acl

Neben dem »nfsd« in Form eines Kernel-moduls gibt es auch eine Version, die komplett im Userspace läuft. Ihre Performance ist jedoch wesentlich schlechter als die des Kernelmoduls, und sie unterstützt weder die Protokolle des Network-Status-Managers (NSM) und Network-Lock-Managers (NLM) noch Dateien größer als 2 GByte.

Dienstleister

Damit ein Client ein Verzeichnis importieren – in den lokalen Dateibaum einhängen – kann, muss dieses auf der Serverseite zum Export freigegeben sein. Die Einstellungen dafür liegen in der Datei »/etc/exports«, die der »mountd« und der »nfsd« auslesen. Über den Befehl »exportfs« ist es auch möglich, Verzeichnisse vorübergehend freizugeben:

exportfs -o ro,sync server1.example.com /var/ftp/pub 

Ein anschließendes »exportfs -u« macht diese Freigaben wieder rückgängig:

exportfs -u server1.example.com:/var/ftp/pub

Aktive Freigaben zeigt auf dem NFS-Server der Befehl »showmount« an. Für den Rechner Tiffy produziert »showmount -e tiffy« im Beispiel:

Export list for tiffy:
/var/ftp/pub/rhel4-es 192.168.0.0/255.25U 5.255.0

Showmount zeigt zwar die exportierten Verzeichnisse und die zugelassenen Clients an, es fehlt allerdings eine genaue Übersicht der gesetzten Export-Optionen. Diese finden sich auf dem Server in der Datei »/var/lib/nfs/etab«:

/var/ftp/pub/rhel4-es
192.168.0.0/255.255.255.0(ro,sync,wdelay,hide,nocrossmnt,secure, 
root_squash,no_all_squash,subtree_check,secure_locks,anonuid=-2,anongid=-2)  

Nummern statt Namen

Ein Linux-System verwaltet User intern nicht anhand von User- oder Gruppennamen, sondern anhand von IDs. Gehört eine Datei auf dem NFS-Server beispielsweise dem User »tscherf« mit der UID 500 und hat dieser User Lese-/Scheibberechtigung für die Datei, dann hat nach dem Importieren der Datei via NFS ein Client-Benutzer, der ebenfalls die UID 500 besitzt, dieselben Rechte an der Datei. Um dieses Problem zu umgehen, setzen aktuelle Systeme NFS zusammen mit einer zentralen Benutzerverwaltung wie LDAP oder NIS ein. Für den Benutzer Root ist dies aber keine Lösung.

Einen Ausweg bietet das so genannte Squashing, das schon im Zusammenhang mit den Export-Einstellungen erwähnt wurde. Die Option »root_squash« bewirkt, dass jeder Zugriff vom Benutzer Root auf ein mit diesem Flag exportiertes Filesystem tatsächlich unter der UID des Benutzers »nobody« oder »nfsnobody« erfolgt. Mit der Option »allsquash« setzt NFS alle Zugriffe von beliebigen Usern auf »nobody« oder »nfsnobody« um. Greift der Client auf eine freigegebene Datei zu, dann läuft im Hintergrund eine ganze Kette aufeinander aufbauender Aktionen ab.

Prozesskette

Zunächst muss der Client beim ersten Zugriff auf den NFS-Server ermitteln, unter welchen Ports er »mountd« und »nfsd« erreichen kann. Diese Informationen erfragt er beim Portmapper. Möchte er die Datei exklusiv bearbeiten, dann benötigt er ebenfalls die Adressen von »lockd« und »statd«.

Im nächsten Schritt benutzt der Client die eben erfragte Portnummer, um sich nun direkt an den Mountd auf dem Server zu wenden. Dieser durchsucht die Datei »/var/lib/nfs/etab« danach, ob das angefragte Verzeichnis überhaupt exportiert wurde und ob der Client berechtigt ist, auf das Verzeichnis zuzugreifen. Gehen beide Prüfungen positiv aus, dann besorgt »mountd« vom »nfsd« ein Dateihandle, das die vom Client gewünschte Datei eindeutig referenziert. Das Handle schickt der »mountd« zurück an den anfragenden Client. Er kann nun direkt Handle und Arbeitsanweisung an den »nfsd« auf Serverseite senden und damit die fragliche Datei lesen, schreiben oder löschen. Der komplette Vorgang ist in Abbildung 4 dargestellt. Das Kommando »mount« dient anschließend dazu, die gewünschte Freigabe einzubinden. Ein Beispiel dafür wäre:

mount -t nfs -o ro tiffy:/var/ftp/pub/rhel4-es/ /mnt/daten/ 

Dazu muss der lokale Mountpoint allerdings existieren. Eine Liste der Verzeichnisse, die der Server exportiert, kann sich der Client mit Hilfe des Kommandos »showmount -e« besorgen.

Für das automatische Einbinden von NFS-Dateisystemen trägt man diese einfach in die Datei »/etc/fstab« ein. Eine weitere Möglichkeit bietet der Automounter. Er initiiert den Mount-Vorgang, sobald auf den lokalen Mountpoint zugegriffen wird. Die Konfiguration findet sich in den Dateien »/etc/auto.master« sowie »/etc/auto.misc«. Die möglichen Mount-Parameter sind in dem Kasten “Mount-Optionen” zusammengestellt.

Abbildung 3: Wer seinen Server gerne grafisch konfigurieren möchte, kann bei Fedora auf »system-config-nfs« zurückgreifen. Suse bietet ähnliche Tools.

Abbildung 3: Wer seinen Server gerne grafisch konfigurieren möchte, kann bei Fedora auf »system-config-nfs« zurückgreifen. Suse bietet ähnliche Tools.

Abbildung 4: Auf seine Mount-Anforderung erhält der Client ein Dateihandle, welches er zusammen mit Arbeitsanweisungen (etwa Lesen oder Schreiben) an den NFS-Daemon schickt.

Abbildung 4: Auf seine Mount-Anforderung erhält der Client ein Dateihandle, welches er zusammen mit Arbeitsanweisungen (etwa Lesen oder Schreiben) an den NFS-Daemon schickt.

Mount-Optionen

rw, ro: Schreib- und Lesezugriff beziehungsweise Nur-Lese-Zugriff. Wichtig dabei ist, dass die Rechte höchstens weiter eingeschränkt werden können, das heißt, ein vom Server nur lesend exportiertes Verzeichnis kann lokal nicht zum Schreiben freigegeben werden; umgekehrt kann die Schreibberechtigung lokal verboten werden, selbst wenn der Server diese zuließe.

fg: Jeder gescheiterte Mountvorgang wird eine Fehlermeldung erzeugen; der Vorgang läuft im Vordergrund (foreground).

bg: Scheitert der Mount-Vorgang im ersten Versuch, wird er im Hintergrund (background) so lange wiederholt, bis er erfolgreich war oder Rsize erreicht wurde.

retrans=zahl: Anzahl der Mount-Versuche. Der Default-Wert liegt bei 5.

hard: Ein Programm wird während des Zugriffs auf ein NFS-Verzeichnis hängen bleiben, falls der Server zusammenbricht. Nach Wiederanlaufen des Servers fährt das Programm mit seiner Arbeit fort. Ein hängendes Programm, kann nur unterbrochen werden, wenn die Option »intr« angegeben wurde.

soft: Der Kernel wird, falls der Server eine bestimmte Zeit lang (»retrans x timeo«) nicht antwortet, einen Fehler generieren und die auf den Server wartenden Prozesse informieren. Die Zeitdauer zwischen den Versuchen kann mit »timeo=Sekunden« eingestellt werden.

intr, nointr: Schafft oder verhindert die Möglichkeit, eine hängende Clientaktion über eine Tastenkombination abzubrechen. Vor allem bei Hard-Mounts wichtig.

remount: Aushängen eines Verzeichnisses, um es sofort wieder einzuhängen. Wird in der Regel benutzt, um neue Einstellungen zu testen.

suid, nosuid: SUID-Bits dürfen oder dürfen nicht auf dem eingehängten Dateisystem verwendet werden.

retry=Zahl: Anzahl der erfolglosen Mount-Versuche (Voreinstellung ist 10000), bis endgültig abgebrochen wird.

wsize=Zahl: Setzt die Blockgröße beim Schreiben über NFS auf Bytes. Die Voreinstellung ist 1024, sollte aber auf 8192 gesetzt werden.

rsize=Zahl: Setzt die Blockgröße beim Lesen über NFS auf Bytes. Die Voreinstellung ist 1024, sollte aber auf 8192 gesetzt werden.

timeo=Zahl: Intervall für Wiederholungen, angegeben in Zehntelsekunden.

proto=Protokoll: Angabe des Protokolls (UDP oder TCP).

Exklusivrechte

In einem verteilten Dateisystem können mehrere Clients gleichzeitig auf dieselbe Datei zugreifen. In der Regel möchte man diese problematischen Aktionen verhindern, indem man die Datei oder Teile von ihr für einen Client reserviert. Unter Linux wird diese Aufgabe durch den Kernel gelöst – auf Anwendungsebene über den Systemaufruf »fcntl()« (file control).

Möchte ein Client einen exklusiven Zugriff auf eine Datei haben, sendet er diese Anforderung an der Kernel. Wenn sich die zu sperrende Datei innerhalb einer NFS-Freigabe befindet, leitet der Kernel die Anforderung an den lokalen Network-Lock-Manager (NLM, »rpc.lockd«) weiter. Von dort geht die Anfrage an den »lockd« auf dem NFS-Server. Dieser bearbeitet sie und schickt das Ergebnis an den NLM des Clients zurück. Der Kernel kann die Sperre schließlich ausführen. Voraussetzung ist, dass der NLM sowohl auf dem Client wie auch auf dem Server gestartet ist.

Wenn der Client oder der Server rebooten, kommt der Network-Status-Manager (NSM, »rpc.statd«) ins Spiel. Hat der »lockd« des Servers eine Datei gesperrt, wird diese Information an den NSM weitergegeben und im Verzeichnis »/var/lib/nfs/sm« der Name des Clients vermerkt. Auf der Clientseite wird der Name des Servers vermerkt, der die Sperre durchgeführt hat. Verantwortlich dafür ist erneut der NSM des Clients.

Fällt nun ein Client aus, wird unmittelbar der Network-Status-Monitor des Servers kontaktiert, der die Information an den NLM weiterleitet. Dieser hebt die Sperre auf. Fällt der Server aus, läuft das Spiel andersherum ab. Die Clients werden informiert und erhalten nach dem Neustart des Servers die Möglichkeit, ihre Sperren erneut anzufordern und zu aktualisieren. Findet keine Aktualisierungsanfrage statt, werden die Locks aufgehoben.

Ein Problem ist der Einsatz von Dateisperren immer noch in Cluster-Umgebungen. Da die Locking-Informationen in lokalen Dateien abgelegt werden und diese im Falle eines Failovers nicht auf einen anderen Cluster-Knoten übertragen werden, stehen sie anschließend nicht mehr zur Verfügung.

NFSv4

NFS in der Version 4 [2] unterstützt neben der Authentifizierung »AUTH_SYS«, die lediglich auf UID/GID-Daten beruht, auch die Kerberos-basierte Authentifizierung »RPCSEC_GSS« [3]. Daraus resultiert nicht nur eine sichere Authentifizierung der auf den Server zugreifenden Clients, sondern es dient auch zur Verschlüsselung und Integritätswahrung der übertragenen Daten. In der Regel wird NFSv4 mit Kerberos-Authentifizierung zusammen mit LDAP als zentraler Benutzerverwaltung eingesetzt. Der Artikel geht deshalb im Folgenden von einer bereits existierenden zentralen Benutzerverwaltung mittels LDAP aus. Details zu Kerberos entnehmen Sie dem Kasten “So funktioniert Kerberos”.

Abbildung 5: Über das Tool »authconfig-tui« lassen sich sehr leicht die für die Authentifizierung notwen-digen Informationen eintragen.

Abbildung 5: Über das Tool »authconfig-tui« lassen sich sehr leicht die für die Authentifizierung notwen-digen Informationen eintragen.

So funktioniert
Kerberos

Abbildung 6 zeigt die Funktionsweise von Kerberos. Der Client baut eine Verbindung zu einem Key Distribution Center (KDC) auf. Das geschieht entweder für den User transparent durch das Anmeldeprogramm »login« oder mit Hilfe von »kinit«. Das KDC besteht aus zwei Teilen: einem Authentication Server (AS) und einem Ticket Granting Server (TGS). Der Authentication Server empfängt die Anfrage des Clients und überprüft seinen Namensraum (Realm) auf den angefragten Usernamen (User-Principal). Taucht der Principal in der Kerberos Datenbank auf, dann erzeugt der AS einen zufälligen Session Key und ein so genanntes Ticket Granting Ticket (TGT). Dieses TGT beinhaltet verschiedene Informationen, unter anderem den Clientnamen und IP, eine Gültigkeitsdauer, einen Zeitstempel und den eben erzeugten Session Key.

Abbildung 6: Der Ablauf einer Kerberos-Session. 1 Der User meldet sich am System an und sendet eine Anfrage an den AS. 2 Der AS antwortet mit einem TGT. 3 Der Client möchte eine Verbindung zu einem Kerberos-Dienst aufbauen und verlangt deshalb ein Service-Ticket. 4 Der TGT stellt das ST aus. 5 Der Client reicht das Service-Ticket an den Kerberos-Dienst weiter. 6 Der User ist authentifiziert – die Verbindung ist aufgebaut.

Abbildung 6: Der Ablauf einer Kerberos-Session. 1 Der User meldet sich am System an und sendet eine Anfrage an den AS. 2 Der AS antwortet mit einem TGT. 3 Der Client möchte eine Verbindung zu einem Kerberos-Dienst aufbauen und verlangt deshalb ein Service-Ticket. 4 Der TGT stellt das ST aus. 5 Der Client reicht das Service-Ticket an den Kerberos-Dienst weiter. 6 Der User ist authentifiziert – die Verbindung ist aufgebaut.

Ticket Granting Ticket

Das TGT wird mit einem Schlüssel codiert, welcher nur dem Authentication Server und dem Ticket Granting Server bekannt ist. Zusammen mit dem eben erzeugten Session Key wird dieses Ticket nun an den Client gesendet: natürlich nicht im Klartext, sondern mit einem Schlüssel codiert, der aus dem Passwort des Clients berechnet wurde. Nachdem der Client die Antwort des Authentication Servers erhalten hat (codiertes TGT und Session Key), wird der User aufgefordert, sein Passwort einzugeben. Dieses Passwort wandelt Kerberos zu einem DES-Schlüssel um. Es dient gleichzeitig zur Decodierung des eben empfangenen TGTs. Der Client speichert das TGT in seinem Credential-Cache und löscht das eingegebene Passwort aus dem Speicher. Mit Hilfe des TGTs kann der User nun für die Gültigkeitsdauer des Tickets seine Identität nachweisen, ohne sich noch einmal mit einem Passwort authentifizieren zu müssen.

Service-Tickets

Die Workstation verifiziert die Echtheit des Benutzers mit dem TGT. Möchte der User jedoch auf einen weiteren Netzwerkdienst, wie beispielsweise NFS zugreifen, muss er erneut ein Ticket vom KDC anfordern, diesmal vom Ticket-Granting Server. Dieses Service-Ticket (ST) ist für genau diesen einen Dienst zuständig, wofür es angefordert wurde. Ein Service-Ticket anzufordern ist um einiges komplexer: Der Client sendet eine Anfrage an den TGS. Diese Anfrage besteht aus dem Namen des Diensts, auf den der Client zugreifen möchte, einem so genannten Authenticator und dem gespeicherten TGT. Der Authenticator besteht aus dem Namen des Clients, seiner IP-Adresse sowie einem Zeitstempel (aktuelle Zeit des Clients).

Das verschlüsselte TGT wird zusammen mit dem Authenticator an den Ticket Granting Server geschickt. Der Authenticator wird mit dem Session Key, der mit dem TGT empfangen wurde, ebenfalls codiert. Der Ticket Granting Server decodiert den Authenticator und das TGT und vergleicht Inhalt, IP-Adresse des anfragenden Clients und die aktuelle Uhrzeit. Passt alles zusammen, generiert der KDC einen neuen Session Key, der in Zukunft vom Client und dem involvierten Server (hier der NFS-Server) benutzt wird. Dieser Session Key ist Bestandteil des Service-Tickets, welches nun vom Ticket Granting Server ausgestellt und verschlüsselt (mit dem Session Key des TGT) an den anfragenden Client gesendet wird. Das Spiel beginnt nun wieder von vorne.

Der Client empfängt das Service-Ticket und reicht es an den gewünschten Server (NFS) weiter, um seine Identität nachzuweisen. Zusätzlich zum Service-Ticket wird ebenfalls wieder ein Authenticator generiert und an den Server geschickt. Stimmen wieder alle Informationen des Service-Tickets und des Authenticators überein, dann wird der Client als echt eingestuft und akzeptiert, ohne dass sich dieser noch einmal mit Usernamen sowie Passwort authentifizieren muss. Der Authenticator schützt davor, das jemand den Netzwerk-Verkehr mitliest, ein Service-Ticket abfängt und dieses zu einem späteren Zeitpunkt einem Server anbietet, um Zugang zu erhalten. Diese Vorgehensweise ist unter dem Namen Replay-Attacke bekannt. Damit die Authentifizierung des Clients funktioniert, muss folglich die Uhrzeit auf allen beteiligten Systemen korrekt eingestellt sein. Das lässt sich am einfachsten mit dem Network-Time-Protocol sicherstellen.

Der Kerberos-Server

Der Kerberos-Server beinhaltet die eigentliche Datenbank, in welcher die Principals gespeichert sind. Dieser Server muss besonders gesichert sein, und er sollte keine zusätzlichen Dienste anbieten. Es existieren sowohl Principals für Benutzer wie auch für die Kerberos-basierten Dienste und Hosts. Ein Principal hat folgenden Aufbau: »primary/instance@REALM« – wobei »instance« optional ist und lediglich zur Gruppierung dient. Beispielsweise könnte ein User-Principal folgendermaßen aussehen: »thorsten/admin@EXAMPLE.COM«. Ein Beispiel für einen NFS-Server: »nfs/nfs.example.com@ EXAMPLE.COM«. Der Realm fasst alle Principals eines Bereichs zusammen und entspricht dem groß geschriebenen DNS-Domänennamen. Mit den Principals speichert der Server auch die Passwörter der User und der Dienste in der Kerberos-Datenbank.

Der Server ist relativ leicht zu konfigurieren: In der Datei »/etc/krb5.conf« ist der Kerberos-Realm einzutragen. Mit dem Kommando »kdb5_util create« wird die eigentliche Datenbank im Verzeichnis »/var/kerberos/krb5kdc« erzeugt. Die Administration der Datenbank erfolgt entweder lokal mit dem Tool »kadmin.local« oder remote mittels »kadmin«. Allerdings muss hierfür auf dem KDC der Kadmin-Dienst aktiv sein, und es muss ein gültiger Admin-Principal in der Datei »/var/kerberos/krb5kdc/kadm5.acl« existieren. Wird eines der VerwaltungsTools aufgerufen, kann mittels »add_principal« ein neuer Principal der Datenbank hinzugefügt werden – beispielsweise »add_principal -pw password thorsten«. Für einen Service oder eine Workstation sieht es ähnlich aus: »add_principal -randkey nfs/nfs.example.com«. Die Passwörter der Service-Principals müssen natürlich auf den entsprechenden Servern bekannt sein. Dies wird erreicht, indem das Passwort für einen Service mit folgendem Befehl aus der Kerberos-Datenbank extrahiert wird: »ktadd -k /etc/krb5.keytab nfs/nfs.example.com«. Die Datei »/etc/krb5.keytab« ist anschließend sicher auf den entsprechenden Service-Rechner zu kopieren, beispielsweise über SSH. Nach dem Start des KDC über den Befehl »service krb5kdc start« ist die Kerberos-Authentifizierung betriebsbereit.

Server-Setup

Damit der LDAP-Server seine Benutzer via Kerberos authentifizieren kann, müssen einige Kriterien erfüllt sein. Als Erstes ist für den LDAP-Host ein Kerberos-Principal einzurichten; das geht am einfachsten über »kadmin.local« auf dem LDAP-Host. Dort wird ein Principal mittels »add_principal -randkey ldap/ldap.example.com« erzeugt und per »ktadd -k /etc/openldap/ldap.keytab ldap/ldap.example.com« in der Datei »/etc/openldap/ldap.keytab« abgelegt.

Damit der LDAP-Server beim Systemstart weiß, wo er seine Keytab-Datei findet, teilen wir ihm dies über die Datei »/etc/sysconfig/ldap« mit. Hierein gehört die Anweisung »export KRB5_KTNAME=/etc/open-ldap/ldap.keytab«. Nach einem Neustart des Servers sollte nun bereits eine Authentifizierung mittels LDAP möglich sein. Testen Sie dies am einfachsten mit dem Tool »ldapsearch« und lassen Sie die Option »-x« für die normale Anbindung weg. Der Client versucht dann automatisch die Authentifizierung mittels des Kerberos-Protokolls.

Um NFS mitzuteilen, dass die Authentifizierung der Clients mit Hilfe von Kerberos funktioniert, setzen Sie in der Datei »/etc/sysconfig/nfs« die Variable für »SECURE_NFS«:

# This entry should be "yes” if you are using RPCSEC_GSS_KRB5 
# (auth=krb5,krb5i, or krb5p)
SECURE_NFS=”yes”
# This entry sets the number of NFS server processes.  8 is the default 
RPCNFSDCOUNT=8

Je nach Distribution weicht die Bezeichnung der Variablen leicht ab. Als Nächstes sollten Sie Ihr System auf die richtige Library (aktuell »libgssapi_krb5.so«) stoßen. Das ist in der Datei »/etc/gssapi_mech.conf« meistens schon richtig eingestellt. Über die Datei »/etc/idmapd.conf« lässt sich der Daemon konfigurieren, welcher für das Mapping zwischen UID und Username zuständig ist. Dieser Service muss sowohl auf dem Client als auch auf dem Server laufen. Die Konfigurationsdatei zeigt Listing 1.

Über die Datei »/etc/exports« lassen sich nun wie gewohnt die Freigaben einrichten. Ein Beispiel zeigt Listing 2.

Über die erste Zeile ist jeder authentifizierte Kerberos-User in der Lage, auf die Freigabe zuzugreifen. Die zweite Zeile lässt ebenfalls NFSv3-Clients auf den Server zugreifen.

Listing 1:
»/etc/idmapd.conf«

01 [General]
02 
03 Verbosity = 0
04 Pipefs-Directory = /var/lib/nfs/rpc_pipefs
05 Domain = example.com
06 
07 [Mapping]
08 
09 Nobody-User = nfsnobody
10 Nobody-Group = nfsnobody

Listing 2: /etc/exports für
NFSv4

01 # NFSv4
02 /dokumente  gss/krb5(sync,rw,fsid=0,insecure,no_subtree_check,
          anonuid=65534, anongid=65534)
03 
04 # NFSv3
05 /dokumente 192.168.0.0.0/255.255.255.0(sync,rw,nohide,insecure,
          no_subtree_check,anonuid=65534, anongid=65534,no_root_squash)

Die Clients

Jeder Client benötigt ein Host-Principal. Dieses legt der Admin über den Aufruf von »kadmin.local« auf dem Client und mit dem Befehl »add_principal -randkey host/client.example.com« an. Anschließend schreibt er über »ktadd -k host/client.example.com« die Keytab-Datei. Wenn die NFS-Clients bereits derart konfiguriert sind, dass sie für die Authentifizierung LDAP benutzen, so sind mittels »authconfig-tui« lediglich die Kerberos-relevanten Informationen einzugeben. Abbildung 5 zeigt einen entsprechenden Eintrag.

Falls der Client noch nicht für eine LDAP-Authentifizierung konfiguriert ist, so kann dies ebenfalls mittels »authconfig-tui« nachgeholt werden. Danach startet Root den Daemon über »/etc/init.d/rpcgssd start«.

Per »mount«-Kommando lässt sich nun die Freigabe des Servers einbinden. Für NFSv4 müssen Sie dabei als Filesystem-Type »nfs4« sowie die Authentifizierung »krb5« (anstatt »sys«) angeben:

[root@tiffy ~]# mount -t nfs4 -o sec=krb5 nfs.example.com/export /mnt/nfs 

Überprüfen Sie beim Auftreten von Problemen noch einmal in der Datei »/etc/sysconfig/nfs«, ob die Kerberos-Authentifizierung überhaupt eingeschaltet ist. Wenn außerdem eine Integritätsprüfung der übertragenden Daten stattfinden soll, so geben Sie als Mount-Option »sec= krb5i« an. Die Option »sec= krb5p« verschlüsselt die zu übertragenden Daten zusätzlich. (mhi)

Infos

[1] RFC 1050: [http://www.faqs.org/rfcs/rfc1050.html]

[2] RFC zu NFSv4: [http://www.faqs.org/rfcs/rfc3550.html]

[3] RFC zu RPCSEC_GSS: [http://www.faqs.org/rfcs/rfc2204.html]

Der Autor


Thorsten Scherf arbeitet für die Firma Red Hat, bei welcher er unter anderem Trainings sowie Projekte in dem Bereich Netzwerksicherheit durchführt.

E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Nach oben