NFS - Network File System

ArticleCategory:

System Administration

AuthorImage:

TranslationInfo:

Original in fr Fr�d�ric Raynal

fr to en Philippe Trbich & Emmanuel Bonnel

en to nl Hendrik-Jan Heins

AboutTheAuthor:

Fr�d�ric Raynal schrijft een thesis op het gebied van computerwetenschappen over 'brandmerken' in afbeeldingen aan het INRIA. Hij leest op dit moment een heel goede detective roman, gesitueerd in het begin van deze eeuw, toen Th. Roosevelt nog hoofcommissaris was bij de politie. De toon is duister. Het gaat over de ondervraging door een groep personen om een seriemoordenaar te vinden die kinderen belaagt. Deze groep wordt gesteund door enkele nieuwe technieken (psychologie, vingerafdrukken, enz...) bij het vinden van de oplossing. Deze roman van Caleb Carr, l'Ange des t�n�bres, schetst een verrassend beeld over het begin van de vorige eeuw.

Abstract:

Een Network File System (NFS) laat je toe om bestanden op verschillende computers in een netwerk te beheren op een manier die lijkt op het beheer van een lokale schijf. Dus het is niet meer van belang dat je weet waar de bestanden zich fysiek bevinden om ze te openen.

ArticleIllustration:

ArticleBody:

Inleiding

NFS staat het eenvoudig delen van gegevens tussen verschillende computers toe. Een gebruiker die bijvoorbeeld is ingelogd op een netwerk hoeft niet in te loggen op een specifieke computer: met behulp van NFS kan hij zijn home directory (die ergens anders staat) openen vanaf de machine waar hij achter zit.

Maar NFS is niet direct een efficiënt protocol en daardoor zeer traag over een modemverbinding. Het is ontworpen voor lokale netwerken en het is zeer flexibel. Het biedt gebruikers en beheerders veel mogelijkheden.

Je moet deze dienst voorzichtig, met een duidelijk beleid, beheren. Iedereen toegang geven om te schrijven naar je netwerk is geen doordacht beleid ;-) Enkele belangrijke voorzorgsmaatregelen kunnen de risico's aanzienlijk verkleinen.

Dit artikel begint met een zeer korte introductie over bestandssystemen. Daarna zullen we het NFS protocol bekijken. Vervolgens zullen we dieper ingaan op minder theoretische onderdelen en een NFS server en cliënt installatie uitvoeren. We zullen ook kijken naar de minimale veiligheidsmaatregelen die je zou moeten nemen. En tenslotte zullen we met een voorbeeld illustreren hoe je NFS, NIS en autofs kunt combineren.
 

Algemene en onvolledige presentatie over bestandssytemen

Voordat we gaan praten over NFS, moet je eerst de term bestandssysteem begrijpen. Een bestandssyteem is een manier van gegevens opslaan, beheren en organiseren op een medium. Er bestaan vele bestandssytemen, sommigen worden vaker gebruikt dan anderen (New Technology Filesystem (NTFS), High Performance Filesystem (HPFS) DOS FAT 12/16/32, VFAT, Machintosh Hierarchical Filesystem (HFS), ISO 9660 (voor CD-rom), extended file systems (Ext, Ext2, Ext3) en nog vele anderen).

We zouden ieder fysiek medium voor gegevens (een harde schijf bijvoorbeeld) kunnen zien als een opeenvolging van kleinere eenheden die informatie bevatten: we praten hier over blokken. Ieder bestandssyteem beheert deze blokken op een andere manier. In figuur 1 proberen we bijvoorbeeld een bestand in te voegen dat twee blokken beslaat. In de bovenste illustratie wordt het bestand geplaatst achter het laatste bezette blok, waardoor er lege ruimte overblijft aan het begin. In het onderste deel van de illustratie (in een ander bestandssyteem), wordt het bestand op de eerste vrije plaats gezet. Dit soort beleid bepaalt hoe ernstig een schijf gefragmenteerd raakt. Sommige bestandssytemen gaan fragmentatie automatisch tegen, terwijl anderen handmatig gedefragmenteerd moeten worden.
 
 


Fig. 1 : 2 verschillende manieren om blokken te plaatsen





Het beroemdste bestandssysteem voor Linux heet ext2fs (extended 2 file system). Daarion wordt elk bestand vertegenwoordigd door een inode1. Directories bevatten de bestandslijst en de toegang tot apparaten wordt verzorgd door het lezen en schrijven van/naar bepaalde bestanden.

Het is de taak van de NFS server om de inodes die de cliënten willen openen aan te leveren. Echter, een cliënt zou niet veel kunnen met slechts de inode van een bestand! Een NFS server heeft daarom ook een extra netwerklaag die andere machines toelaat om de inodes te manipuleren.

Het NFS protocol

Wat we over het algemeen NFS noemen bestaat eigenlijk uit vier verschillende protocollen. Ieder protocol wordt aangestuurd met behulp van Remote Procedure Calls(RPC) en portmap (ook wel rpc.portmap genoemd). Een portmapper converteert RPC programmanummers naar poortnummers. Wanneer een RPC server opstart, geeft hij door aan portmap welke poort en welk RPC-nummer hij gaat gebruiken. Wanneer een cliënt een RPC aanvraag doet op een gegeven programmanummer, neemt hij eerst contact op met de portmap server om te vragen welk poortnummer hij moet gebruiken om toegang te krijgen tot het gewenste programma. Daarna adresseert hij de RPC pakketten rechtstreeks voor de aangegeven poort.

De 4 diensten achter NFS zijn:
 
Protocol
Omschrijving
Daemon
nfs Dit protocol vormt het hart van NFS en dient voor het maken, zoeken, lezen en schrijven van bestanden. Dit protocol regelt ook de authenticatie en de statistische bestandsgegevens.
nfsd
mountd Deze beheert het mounten van geëxporteerde bestandssystemen om ze te kunnen openen met nfs. De server ontvangt aanvragen zoals mount en umount en moet dus informatie bijhouden over de geëxporteerde bestandssystemen.
mountd
nsm
(Network Status Monitor) 
Dit wordt gebruikt om netwerk nodes in de gaten te houden. Statd moet altijd weten in welke staat de machine (cliënt of server) zich bevindt; het geeft bijvoorbeeld aan of een machine aan het heropstarten is.
statd
nlm
(Network Lock Manager) 
Om gegevensmodificatie door verschillende cliënten tegelijk te voorkomen, beheert dit protocol een "lock" systeem. Het weet welke bestanden worden gebruikt. Met behulp van het Nsm protocol kan het weten wanneer een cliënt opnieuw opstart. Nsm opent eerst het "lock" van alle cliënten voordat ze een nieuwe toegewezen krijgen.
lockd

De daemon knfsd, beschikbaar in de nieuwste kernel versies, ondersteunt de nfs en nlm protocollen direct. Mountd en nsm aan de andere kant worden nog niet ondersteund. Wanneer de NFS server is geïnstalleerd en opgestart, kunnen we controleren of alles werkt met het commando:
 


>> 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

Op dit moment zijn er twee versies van NFS beschikbaar (versie 2 en 3 - deze zullen respectievelijk NFSv2 en NFSv3 worden genoemd om onderscheid te maken). Linux NFS servers ondersteunen alleen versie 2 (vandaar de optie in de mountd regel in het bovenstaande voorbeeld).

Het NFS gaat over een gegevensstructuur genaamd een file handle (letterlijk: bestandshandvat). Het is een vrij esoterische serie bits die ieder object in een bestandssysteem op een unieke manier identificeert. Het bevat bijvoorbeeld de inode van een bestand, maar ook een representatie van het apparaat waarop het bestand staat. NFS kan je dus bekijken als een soort bestandssysteem dat op een bestandssysteem ligt.

Installatie

De server

Het eerste dat we moeten doen is, zoals we al gezien hebben, het starten van portmap, aangezien dit protocol nodig is voor NFS.
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
Het rpcinfo commando toont de RPC diensten die aanstaan op de machine zoals ook wordt gespecificeerd in het argument (de -p optie). We kunnen zien dat portmap nog niet draait; we starten deze (de meeste Linux distributies bevatten scripts om dit bij het opstarten automatisch te laten verlopen) en we controleren of het werkt. Een andere veel voorkomende reden voor een negatieve respons op rpcinfo is het feit dat de portmapper niet mag antwoorden vanwege veiligheidsbeperkingen in de /etc/hosts.{allow, deny} bestanden. In dat geval moet je een "portmap: hosts" ingang toevoegen aan het hosts.allow bestand.

Voordat je NFS zelf start moet het eerst geconfigureerd worden. Er is maar één configuratiebestand en dat draagt de naam /etc/exports. Iedere regel geeft een exportlokatie gevolgd door een lijst van cliënten die er toegang tot hebben. Het is mogelijk om opties toe te voegen achter iedere cliënt naam. De man exports pagina geeft de syntax voor cliëntnamen en opties.

Geaccepteerde vormen voor cliëntnamen zijn:

We zullen de beschikbare mount opties hier niet tot in detail geven, maar hier zijn de belangrijkste: Nu moeten we de daemonsrpc.mountd en rpc.nfs starten om een werkende NFS server te krijgen. We controleren weer met het commando rpcinfo of alles werkt. We kunnen zelfs de server starten voor de protocollen nsm en nlm (respectievelijk rpc.statd en rpc.lockd). Ze zijn niet noodzakelijk voor het draaien van een NFS server... Maar we raden ze ten zeerste aan voor het geval een machine vastloopt, vanzelf opnieuw opstart, enz...

Wanneer we het configuratiebestand /etc/exports veranderen, moeten we de betreffende daemons laten weten dat er veranderingen zijn aangebracht. Het commando exportfs verzendt deze informatie naar onze servers. De optie -r synchroniseert het bestand /etc/mtab2 met het /etc/exports bestand. De optie -v laat de geëxporteerde bestandssytemen met hun opties zien.

Na het opstarten bevatten de volgende bestanden belangrijke informatie:

Wanneer een cliënt toegang vraagt tot een bestandssysteem, stuurt hij eerst een aanvraag naar mountd. Daarna zoekt hij in etab op of het aangevraagde beschikbaar is. Hij controleert of de kernel weet of de cliënt een aanvraag mag doen (check hosts.{allow, deny}, firewall rules, ...). De kernel maakt gebruik van exportfs bij deze controle, en zorgt ervoor dat het /var/lib/nfs/etab bestand wordt bijgewerkt. Als het geëxporteerde systeem in dit bestand staat aangegeven als een bestandssysteem dat gedeeld mag worden naar de groep waartoe de cliënt behoort, dan vertelt mountd dit aan de kernel die op zijn beurt het bestand xtab up to date brengt en deze nieuwe host toevoegt.

De cliënt

Normaal gesproken hoef je hier niets aan te doen... De toegang tot een met NFS geëxporteerd bestandssysteem wordt direct door de kernel beheerd. Ondersteuning voor NFS moet wel tijdens de compilatie van de kernel worden ingebracht. Het bestand /proc/filesystems geeft alle bestandssystemen die de kernel direct ondersteunt. Nu hoef je de kernel alleen nog maar te vertellen dat je een met NFS geëxporteerd systeem wilt openen.

Het mount commando geeft toegang tot meerdere typen bestandssystemen. Dit commando vertelt de kernel dat er een nieuw bestandssysteem beschikbaar is, welk type het is, z'n device (apparaat) en een mount punt. De optie -t  kan worden gebruikt om handmatig aan te geven om wels soort bestandssysteem het gaat. Voor NFS geven we hier: -t nfs.

mount heeft eigen opties voor NFS. Bijvoorbeeld de opties rsize en wsize die kunnen worden gebruikt om de blokgrootte voor lezen en schrijven te veranderen. Je kan specifieke NFS opties combineren met algemenere opties zoals bijvoorbeeld intr, noexec of nosuid. De mount man pagina bevat een lijst met al deze opties.

Laten we aannemen dat de machine charly een NFS server draait en dat deze de directory /usr/local exporteert. Als je deze wilt openen vanaf de machine jill, dan hoef je alleen de geëxporteerde directory van charly te mounten op jill:

root@jill >> mount -t nfs -o nosuid,hard,intr charly:/usr/local /usr/local
Het commando geeft aan dat we een NFS bestandssyteem mounten (-t nfs), met de nosuid, hard en intr opties. De laatste 2 argumenten zijn het interessantst. De eerste specificeert het device dat gemount wordt. De syntax is bij NFS anders dan bij andere mount commando's waarbij je het apparaat en de directory aan kan geven. Hier specificeren we server: geëxporteerde_directory in plaats van een apparaat. Het tweede argument geeft de locatie van het bestandssysteem aan de kant van de cliënt. Hier delen we gewoon charly's /usr/local met jill en zo kunnen we meteen voorkomen dat programma's meer dan eens geinstalleerd worden. Om deze opstelling permanent te maken, kunnen we hem opgeven in jill's /etc/fstab bestand. fstab bevat alle apparaten die bij het opstarten gemount moeten worden. De syntax voor /etc/fstab is:
 
#    device           mount point   file system   options     dump  fsckorder
charly:/usr/local    /usr/local       nfs       nosuid,hard,intr    0      0

Maar wees voorzichtig met een permanente koppeling. Je kan de koppeling alleen gebruiken wanneer server (charly) continu aanstaat of wanneer je charly altijd eerder aanzet dan jill.

Pas Op

Een groot probleem van NFS is het feit dat er standaard een vertrouwensrelatie bestaat tussen de server en de cliënt. In dit geval wordt, als de root account van de server gekraakt is, automatisch ook de root-account van de cliënt gekraakt. De NFS-HOWTO beschrijft enkele belangrijke maatregelen die je moet nemen om de beveiliging enigzins te verbeteren.

Een cliënt mag een server niet onvoorwaardelijk vertrouwen, dus we moeten extra beperkende opties aangeven als we gebruik maken van het mount commando. We hebben de eerste al genoemd: nosuid. Dit zorgt ervoor dat de SUID en SGID bits niet ingesteld kunnen worden. Dus, iemand met een root login op de server moet eerst inloggen als een gebruiker op de cliënt en kan pas daarna root worden. Een andere, nog meer beperkende optie, is noexec. Dit verbiedt het opstarten van programma's op het geëxporteerde bestandssysteem. Deze optie is alleen bruikbaar voor systemen die alleen maar data bevatten.

Aan de server kant kunnen we ook aangeven dat we de root account van de cliënten niet vertrouwen. We moeten dit aangeven in /etc/exports met de optie root_squash. Vanaf dat moment krijgt een gebruiker die de cliënt opent met UID 0 (root) op het door de server geëxporteerde bestandssysteem een nobody UID om bestanden mee op te vragen. Deze optie staat onder Linux standaard aan, maar kan uitgezet worden met de optie no_root_squash. Een aantal UID's kan worden aangegeven bij de optie waarop ze van toepassing zijn. Onthoud ook dat de opties anonuid en anongid het mogelijk maken om de UID/GID van de gebruiker te veranderen van nobody in iets anders.

Sommige mogelijkheden zijn wat algemener en hebben effect op de portmapper. We verbieden bijvoorbeeld de toegang tot alle machines met de volgende regel in het /etc/hosts.deny bestand:
 

# hosts.deny : verbiedt absoluut iedereen om
#              gebruik te maken van portmap
portmap: ALL


En daarna heffen we in het bestand /etc/hosts.allow dit stricte verbod op, maar dan enkel voor de machines waarbij dit gewenst is.

Een goed ingestelde firewall geeft ook een nog wat betere bescherming. Let op de poorten die gebruikt worden door de verschillende diensten en de gebruikte protocollen:
 

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

Gebruik van NIS, NFS en autofs

Nu gaan we kijken naar een gecompliceerder netwerk, met een opbouw zoals je het bijvoorbeeld tegen zal komen in een bedrijf. In een klein thuisnetwerk zal je waarschijnlijk wel kunnen leven zonder NIS. NIS, Network Information Service, is een methode om configuratiebestanden centraal te beheren (dus in /etc) en de instellingen hierin te gebruiken op andere machines.
De belangrijkste server in ons netwerk heet "charly", 3 andere machines in het netwerk zijn "sabrina", "jill" en "kelly". We hebben charly geconfigureerd als NIS server voor het domein bosley. De andere machines zijn NIS clients van charly (we zouden ook een backup (slaaf) NIS server moeten hebben, maar dat is dit keer niet ons doel).

Laten we eerst eens kijken naar de configuratie van onze server, charly. We beginnen met het definiëren van enkele NIS mappen die alle benodigde informatie bevatten.

Het bestand /etc/netgroup bevat de machine groepen die veel op elkaar lijken (een zelfde architectuur bijvoorbeeld). Een NIS map is heel bruikbaar voor NFS. We hoeven alleen maar de machines die toegang hebben tot hetzelfde geëxporteerde bestandssysteem te verzamelen. Deze groep wordt dan gebruikt in het bestand /etc/exports, in plaats van de machines één voor één met de hand aan te geven:

# /etc/netgroup
charlysangels (sabrina,,) (jill,,) (kelly)
 Voor zover het NFS betreft weten we dat de configuratie vrij goed is beveiligd. Het bestand /etc/exports op charly bevat:
# /etc/exports
/usr/local    @charlysangels(ro)
We besluiten om automount te gebruiken om toegang te verkrijgen tot de geëxporteerde directory /usr/local. In plaats van dit systeem bij het opstarten te laden, wordt dit automatische gedaan wanneer een gebruiker een bestand uit deze directory opent.  We maken het bestand /etc/auto.map om daarin aan te geven wat toegankelijk is voor zowel automount als NIS:
# /etc/auto.map
charly          charly:/usr/local
Aangezien we deze gegevens (het nieuwe auto.map en netgroup bestand) geïntegreerd willen hebben in de NIS database, moeten we de Makefile veranderen voordat we hem opnieuw gaan gebruiken. We moeten er zeker van zijn dat netgroup wordt toegevoegd aan de database. Wat auto.map betreft..., dit bestand word standaard niet gedefinieerd. We hoeven alleen maar een nieuwe regel toe te voegen aan Makefile, met de correcte gegevens (door gebruik te maken van een bestaande regel als model):
#Toe te voegen aan de 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) $@
Deze regel haalt alleen maar de commentaren weg, voegt een nieuwe regel toe aan de database en verzendt deze informatie vervolgens naar alle servers.

We hoeven nu alleen nog maar make vanaf de directory /var/yp te starten.

En nu nog onze drie cliënten sabrina, jill en kelly. Hier hoeven we niets te doen :) We moeten alleen autofs vertellen dat hij een nieuwe map moet beheren die aangeleverd wordt door YP. In het /etc/auto.master bestand van alle cliënten geeft de volgende regel aan dat er een map auto.map te verkrijgen is bij de YP service.

#/etc/auto.master
/usr/local    yp auto.map    --intr,nosuid,nodev
Daarna moeten we autofs herstarten om de de veranderingen (de nieuwe map) actief te maken.

Nu hebben we een unieke /usr/local fysieke directory op charly. Dus, wanneer er speciale programma's op charly worden geinstalleerd, kunnen alle machines daar gebruik van maken.

Dit voorbeeld zou kunnen worden uitgebreid met de installatie van een enkel /usr systeem, een /usr/doc of welke andere dan ook, maar de ervaring leert dat dat geen goed idee is. Bij installaties moeten er vaak bestanden uit de /etc directory of een andere directory worden gewijzigd. Dan zouden we alle machines moeten veranderen om een niet-geëxporteerd bestand up-to-date te brengen en dat wordt al snel vervelend.
 

Referenties

Bestandssystemen


NFS



Voetnoten

... inode1
Dit is een een omschrijving voor een bestand (een serie bits) die onder andere de toegangsrechten, eigenaar, fysieke blokadressen, de gegevens die het bevat enz... omschrijft.
... /etc/mtab2
Dit bestand bevat de lijst met alle bestandssystemen die door de kernel gemount zijn, met de "harde" methode (door mount, zoals de systemen die in het bestand fstab beschreven worden), of door minder "vaste" middelen (door autofs/automount).