NFS und Brandschutzmauern
Ende der 80er Jahre nahm sich Sun durch Einführung eines Secure RPC getauften Systems der Authentifizierungsproblematik an, bot damit aber immernoch keine Verschlüsselung auf NFS-Protokoll-Basis. Secure RPC selbst fand relativ wenig Verbreitung, so dass gerade in heterogenen UNIX-Netzen inkompatible Implementierungen einem Einsatz auf breiter Front im Wege standen. Die aktuelle Version 4 (RFC 3530) des Netzwerkdateiprotokolls bringt nun neben zahlreichen anderen Verbesserungen im Rahmen ihrer Spezifikation eine Verschlüsselung der übertragenen Daten sowie die Möglichkeit zur Benutzerauthentifizierung via Kerberos mit.
Dank Sharity existiert eine gangbare Alternative zu NFS, die eine Kommunikation zahlreicher - auch älterer - UNIX-Dialekte über das SMB- und CIFS-Protokoll erlaubt und somit Verschlüsselungs- und Authentifizierungsmechanismen bietet. In manchen Fällen aber dürfte das problematische Handling vieler Implementierungen mit Dateien von über 2GB Größe sowie das kommerzielle Lizensierungsmodell abschreckend wirken - für Studierende allerdings gibt es limitierte, kostenfreie Lizenzen.
Wer also aufgrund der genannten Einschränkungen Sharitys sowie eines ans Herz gewachsenen Sammelsuriums museumsreifer UNIX-Workstations oder des Einsatzes der tatsächlich stabil zu nennenden Linux-Kernelserie 2.4 wegen auf NFS 3 angewiesen ist, muss sich mehr oder weniger zwangsläufig mit den Mängeln der alten Implementierung auseinandersetzen. Ohne den Einsatz von Secure RPC geschieht die “Authentifizierung” in diesem Fall ausschließlich über die IP-Adresse des Clients, als Nebeneffekt des NFS-eigenen “Sicherheitsmodells” hat der Administrator eines lokalen Clients Zugriff auf alle für seinen Rechner freigegebenen Shares, unabhängig von deren Zugriffsrechten. You get the point.
Eine straff konfigurierte Firewall ist also das Mindeste, was man einem solchen Setup an Gutem tun kann. Leider zeigt sich NFS in Version 3 gerade auch in dieser Disziplin durch eine zufällige Vergabe von wichtigen Server-Ports gewohnt zickig, was sich aber beim Einsatz einer auf Linux basierenden Implementierung mit ein paar Handgriffen leicht umschiffen läßt:
NFS 3 selbst basiert auf mehreren Daemons, denen teils feste Ports zugewiesen sind, und anderen, die ihre jeweilige Portnummer nach dem Zufallsprinzip durch den portmap-Daemon zugeteilt bekommen:
Daemon Name Standard Port ----------- ------------- portmap 111 nfsd 2049 statd zufällig lockd zufällig mountd zufällig
Alle nicht statisch zugewiesenen Ports lassen sich durch etwas Handarbeit festen Ports zuweisen. Als Beispielplattform dient ein Debian Sarge, andere Distributionen sind geeignet anzupassen - die entsprechenden init-Skripte geben hier oft einen Hinweis darauf, wo. Gentoo-User finden die äquivalenten Einstellungen unter /etc/conf.d/nfs. Folgende Änderungen lassen NFS ausschliesslich auf statisch festgelegten Ports lauschen und ermöglichen damit ein engmaschiges Firewall-Setup:
Für den statd, im Beispiel auf Port 4000 festgelegt:
/etc/default/nfs-common # Options for rpc.statd. STATDOPTS=’-p 4000’
Für den mountd, im Beispiel auf Port 4002 festgelegt:
/etc/default/nfs-kernel-server # Options for rpc.mountd RPCMOUNTDOPTS=’-p 4002’
Das Festzurren des lockd-Daemons ist etwas aufwändiger, stellt aber auch keine große Hürde da. Je nach Kernelkonfiguration ist eine unterschiedliche Herangehensweise notwendig. Wurde die Unterstützung für den NFS-Server in Module ausgelagert, so ist an geeigneter Stelle in /etc/modultils/ (Gentoo: /etc/modules.d/) folgender Eintrag für das lockd-Modul hinzuzufügen:
options lockd nlm_udpport=4001 nlm_tcpport=4001
Ein in den Kernel selbst kompilierter NFS-Server-Support macht einen Reboot notwendig, da die Modulparameter hier als Kernelparameter von LILO oder Grub weitergegeben werden müssen. Im jeweiligen Konfigurationsfile ist dementsprechend folgendes hinzuzufügen:
/etc/lilo.conf image=/vmlinuz label = “Debian Woody GNU/Linux” [...] append = “lockd.udpport=4001 lockd.tcpport=4001” [...]
/boot/grub/menu.lst title = Debian Woody GNU/Linux root (hd0,0) kernel /vmlinuz root=/dev/hda1 lockd.udpport=4001 lockd.tcpport=4001
Nach erfolgreicher Konfiguration bleibt das neue Setup abschliessend zu prüfen:
> rpcinfo -p
program vers proto port
100000 2 tcp 111 portmapper
100000 2 udp 111 portmapper
100024 1 udp 4000 status
100024 1 tcp 4000 status
100003 2 udp 2049 nfs
100003 3 udp 2049 nfs
100003 2 tcp 2049 nfs
100003 3 tcp 2049 nfs
100021 1 udp 4001 nlockmgr
100021 3 udp 4001 nlockmgr
100021 4 udp 4001 nlockmgr
100021 1 tcp 4001 nlockmgr
100021 3 tcp 4001 nlockmgr
100021 4 tcp 4001 nlockmgr
100005 1 udp 4002 mountd
100005 1 tcp 4002 mountd
100005 2 udp 4002 mountd
100005 2 tcp 4002 mountd
100005 3 udp 4002 mountd
100005 3 tcp 4002 mountd
So oder ähnlich sollte die Ausgabe, mit den der jeweilig gewählten Konfiguration entsprechenden Ports, aussehen. Weitere, ausführlichere englischsprachige Quellen, aus denen auch dieser Beitrag gespeist wurde, finden sich hier:
Configuring NFS under Linux for Firewall control
Setting up a Linux NFS server

Philipp
22 Feb 2007
# cat /etc/sysconfig/nfs
STATD_PORT=4000
LOCKD_TCPPORT=4001
LOCKD_UDPPORT=4001
MOUNTD_PORT=4002
RQUOTAD_PORT=4003
STATD_OUTGOING_PORT=4004
Philipp