Benutzer-Werkzeuge

Webseiten-Werkzeuge


nfs

NFS

Allgemein

Mit Kerberos ist NFSv4 sicherer als NFSv3 und auch als SMB/CIFS. Ohne Kerberos (AUTH_SYS ⇒ sec=sys) ist NFSv4 genauso unsicher wie NFSv3, denn die Authentifizierung basiert dann weiterhin auf der IP-Adresse des Clients und der UID/GID des verwendeten Users.

Einziger Vorteil sind die neu hinzugekommenen ACL's in NFSv4, aber die benutzt ja nicht jeder.

Server (nfsmaster)

# nfsstat
Server rpc stats:
calls      badcalls   badauth    badclnt    xdrcall
31         0          0          0          0       

Server nfs v3:
null         getattr      setattr      lookup       access       readlink     
6        21% 6        21% 0         0% 3        10% 3        10% 0         0% 
read         write        create       mkdir        symlink      mknod        
0         0% 0         0% 0         0% 0         0% 0         0% 0         0% 
remove       rmdir        rename       link         readdir      readdirplus  
0         0% 0         0% 0         0% 0         0% 0         0% 3        10% 
fsstat       fsinfo       pathconf     commit       
0         0% 7        25% 0         0% 0         0% 

Client rpc stats:
calls      retrans    authrefrsh
0          0          0       

der RPC-Portmapper muss laufen:

# rpcinfo -p
   program vers proto   port
    100000    2   tcp    111  portmapper
    100000    2   udp    111  portmapper
    100024    1   udp  38359  status
    100024    1   tcp  54249  status
    100021    1   udp  58418  nlockmgr
    100021    3   udp  58418  nlockmgr
    100021    4   udp  58418  nlockmgr
    100021    1   tcp  34686  nlockmgr
    100021    3   tcp  34686  nlockmgr
    100021    4   tcp  34686  nlockmgr
    100003    2   udp   2049  nfs
    100003    3   udp   2049  nfs
    100003    4   udp   2049  nfs
    100003    2   tcp   2049  nfs
    100003    3   tcp   2049  nfs
    100003    4   tcp   2049  nfs
    100005    1   udp  46838  mountd
    100005    1   tcp  41717  mountd
    100005    2   udp  46838  mountd
    100005    2   tcp  41717  mountd
    100005    3   udp  46838  mountd
    100005    3   tcp  41717  mountd

so sieht man was exportiert wird:

# exportfs
/home/welt       <world>
/home/erde       mensch
/home/mond       192.168.0.0/24

reexportieren:

# exportfs -r

alle Exports aus "/etc/exports" beenden:

# exportfs -ua

exportieren auf der Kommandozeile:

# exportfs -o async mensch:/tmp

Export wieder aufheben:

# exportfs -u mensch:/tmp

/etc/exports

# /etc/exports: the access control list for filesystems which may be exported
#               to NFS clients.  See exports(5).
#
# Example for NFSv2 and NFSv3:
# /srv/homes       hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check)
#
# Example for NFSv4:
# /srv/nfs4        gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check)
# /srv/nfs4/homes  gss/krb5i(rw,sync,no_subtree_check)
#
/home/welt       *(rw,async,wdelay,insecure,no_root_squash,no_subtree_check)
/home/erde       mensch(rw,async,wdelay,insecure,no_root_squash,no_subtree_check)
/home/mond       192.168.0.0/24(rw,async,wdelay,insecure,no_root_squash,no_subtree_check)
Parameter in Klammern Bedeutung
ro nur Lesen
rw Lesen und Schreiben
async Asynchroner Datentransfer
secure nur Ports bis 1024 verwenden
insecure Ports oberhalb 1024 auch verwenden
no_root_squash Bindet man per NFS Verzeichnisse ein, die auf dem Server dem User root gehören, werden diese auf den User nobody gemapped und man kann diese nicht modifizieren. Um dieses Sicherheitsfeature zu umgehen, dient der Parameter no_root_squash (weitere Info mit man 5 exports)
nohide Wenn unterhalb eines exportierten Verzeichnisses (z.B. /home/user auf /dev/hda1) ein weiteres Dateisystem eingebunden wurde (z.B. /dev/hdb1 in /home/user/Musik), so wird dieses Verzeichnis durch einen eigenen exports-eintrag exportiert. Im Normalfall (option 'hide') sieht der Client dieses Unterverzeichnis nicht, wenn er nur das Oberverzeichnis einbindet, weswegen er beide einbinden muss. Durch die Option 'nohide' werden die eingebundenen Unterverzeichnisse dem Client nicht mehr als eigene Partitonen präsentiert, sondern als normale, zum Oberverzeichnis gehörende Verzeichnisse. Daher muss man zwar am Server noch alles explizit exportieren, am Client aber nur noch das Oberverzeichnis einbinden
subtree_check Wenn nur einzelne Verzeichnisse eines Dateisystems freigegeben wurden, wird hiermit überprüft ob eine vom Client angeforderte Datei in diesen Verzeichnissen des Dateisystems ist. Wurde das komplette Dateisystem freigegeben, werden die Übertragungsgeschwindigkeiten beim deaktivieren mittels 'no_subtree_check' erhöht. Darüberhinaus stellt diese Option sicher, dass beim Einbinden eines NFS Verzeichnisses mittels 'root_squash' alle Dateien, die dem user 'root' gehören, nicht abrufbar sind (selbst wenn die Datei-Rechte dies vorsehen). Diese Option kann jedoch Probleme verursachen, insbesondere wenn Dateien umbenannt werden, die auf dem Client gerade geöffnet sind. Deshalb ist seit nfs-utils 1.0.x 'no_subtree_check' voreingestellt.

Client (mensch)

# tracepath nfsmaster
# nfsstat
Client rpc stats:
calls      retrans    authrefrsh
0          0          0       

der RPC-Portmapper muss laufen:

# rpcinfo -p nfsmaster
   program vers proto   port
    100000    2   tcp    111  portmapper
    100000    2   udp    111  portmapper
    100024    1   udp  38359  status
    100024    1   tcp  54249  status
    100021    1   udp  58418  nlockmgr
    100021    3   udp  58418  nlockmgr
    100021    4   udp  58418  nlockmgr
    100021    1   tcp  34686  nlockmgr
    100021    3   tcp  34686  nlockmgr
    100021    4   tcp  34686  nlockmgr
    100003    2   udp   2049  nfs
    100003    3   udp   2049  nfs
    100003    4   udp   2049  nfs
    100003    2   tcp   2049  nfs
    100003    3   tcp   2049  nfs
    100003    4   tcp   2049  nfs
    100005    1   udp  46838  mountd
    100005    1   tcp  41717  mountd
    100005    2   udp  46838  mountd
    100005    2   tcp  41717  mountd
    100005    3   udp  46838  mountd
    100005    3   tcp  41717  mountd

so sieht man was exportiert wird:

# showmount -e nfsmaster
Export list for nfsmaster:
/home/welt *
/home/erde mensch
/home/mond 192.168.0.0/24

mounten:

# mount -t nfs -v nfsmaster:/home/erde /mnt

/etc/fstab

nfsmaster:/home/erde /home/erde nfs rw 0 0
Parameter Bedeutung
ro nur Lesen
rw Lesen und Schreiben
hard Bei Unterbrechungen ohne Timeout warten bis der Server wieder normal erreichbar ist
soft Bei Unterbrechungen sofort einen Timeout machen (verhindert ein Einfrieren des Dateimanagers)
timeo=<SEKUNDEN> In Verbindung mit soft kann festgelegt werden, wann der Timeout erfolgen soll
bg Bei einem Timeout, wird der mount im Hintergrund weiter versucht. Ist z.B. bei einem Laptop, dass im Heimnetz automatisch einen NFS-Server mounten soll, nützlich.
intr Erlaubt einem wartenden Programm bei Bedarf dennoch zu unterbrechen/killen
nolock Deaktiviert das Sperren von Dateien. Wird gelegentlich für die Verbindung zu alten NFS-Servern benötigt
rsize=8192,wsize=8192 Vorsicht: Mit diesen Optionen kann man die Blockgröße der übertragenen Daten festlegen. In den allermeisten Fällen ist es nicht empfehlenswert diese Optionen zu setzen. Server und Client handeln diese Werte selbst aus und erreichen so ein Maximum an Performance. Falsche Werte können die Geschwindigkeit von NFS um bis zu 50% reduzieren.

FreeBSD

Server

Im Kernel muss die Option options NFSD aktiviert worden sein, die Option options NFSSERVER darf nicht aktiviert sein!

Um die ACL's nutzen zu können, müssen die Kernel-Optionen options NFSCL und options NFSD aktiviert werden.

# vi /etc/exports:
### nur lesend
### Das ganze Klasse-C-Netz kann auf das CDROM zugreifen.
/cdrom  -ro                  -network 192.168.0.0 -mask 255.255.255.0
### jeder kann NUR mit seiner UID auf das Verzeichnis zugreifen
### Nur die Rechner mit den genannten IPs koennen auf das
### Home-Verzeichnis zugreifen.
/home   -alldirs -maproot=0:  192.168.0.100 192.168.0.101 192.168.0.102
### jeder hat in diesem Verzeichnis die UID "0" (root)
### Nur die drei Rechner "sonne", "mond" und "stern" koennen
### auf das Verzeichnis zugreifen.
/public -alldirs -mapall=0:   sonne   mond   stern
Nach jeder Aendereung in /etc/exports muss "mountd" neu gestartet werden!

Ich glaube, es muss auch noch in der Datei /etc/hosts.allow eine Zeile eingefügt werden.

erstmal sollte die besagte Stelle so aussehen:

# Rpcbind is used for all RPC services; protect your NFS!
# (IP addresses rather than hostnames *MUST* be used here)
#rpcbind : 192.0.2.32/255.255.255.224 : allow
#rpcbind : 192.0.2.96/255.255.255.224 : allow
rpcbind : ALL : deny
...

und da setzen wir einfach unsere Zeile vor der Zeile mit "deny":

...
rpcbind : 192.168.1.1/255.255.255.0 : allow
rpcbind : ALL : deny
...

FreeBSD 4.x

# vi /etc/rc.conf:
portmap_enable="YES"                    # Run the portmapper service (YES/NO).
nfs_server_enable="YES"                 # This host is an NFS server (or NO)
nfs_server_flags="-t -n 4"              # (-u -t -n 4)
mountd_flags="-r"                       # Flags to mountd (if NFS server enabled).

Der Rechner kann neu gestartet werden, man kann NFS aber auch manuel starten:

# portmap
# nfsd -u -t -n 4
# mountd -r

FreeBSD 5.x

# vi /etc/rc.conf
rpc_lockd_enable="YES"                  # Run NFS rpc.lockd needed for client/server.
rpc_statd_enable="YES"                  # Run NFS rpc.statd needed for client/server.
rpcbind_enable="YES"                    # Run the portmapper service (YES/NO).
rpcbind_program="/usr/sbin/rpcbind"     # path to rpcbind, if you want a different one.
nfs_server_enable="YES"                 # This host is an NFS server (or NO)
nfs_server_flags="-t -n 4"              # (-u -t -n 4)
nfs_reserved_port_only="YES"            # YES: sysctl -w vfs.nfs.nfs_privport=1
mountd_flags="-r"                       # Flags to mountd (if NFS server enabled).
weak_mountd_authentication="NO"         # YES: mountd_flags="-n" (USER duerfen mounten)

Der Rechner kann neu gestartet werden, man kann NFS aber auch manuel starten:

# rpcbind
# nfsd -u -t -n 4
# mountd -r

FreeBSD 8.x

  1. FreeBSD 8.0 enthält ZFS in der Version 13
  2. FreeBSD 8.1 enthält ZFS in der Version 14

ZFS enthält in der Solaris-Version einen SMB- und einen NFS-Server.

Man kann mit FreeBSD 8.x auch die "FreeBSD 5.x"-Anleitung verwenden, aber das hier ist natürlich cool-er… ;-)

Konfigurieren

erstmal legen wir uns ein Volumen an:

Den NFS-Server kann man (laut Doku) so aktivieren:

# zfs set sharenfs=on tank/verzeichnis

…probieren wir das mal aus:

# zfs set sharenfs=on home/kontor
# cat /etc/zfs/exports
# !!! DO NOT EDIT THIS FILE MANUALLY !!!

/home/kontor
# vi /etc/exports
V4: / -sec=sys
# vi /etc/rc.conf
mountd_enable="YES"
nfs_client_enable="YES"
nfs_server_enable="YES"
nfsv4_server_enable="YES"
nfsuserd_enable="YES"
nfscbd_enable="YES"
# install -o root -g wheel -m 600 /dev/null /var/db/nfs-stablerestart

Damit man über sein ZFS-Laufwerk auch immer informiert ist:

# echo 'daily_status_zfs_enable="YES"' >> /etc/periodic.conf
Start
# /etc/rc.d/nfsd restart
# /etc/rc.d/nfsserver restart
# /etc/rc.d/nfsuserd restart
# /etc/rc.d/nfsclient restart
# /etc/rc.d/nfscbd restart
# /etc/rc.d/mountd restart
Test
# mount_newnfs -o nfsv4,acls bsd:/home/kontor /mnt/
# cd /home/kontor
# getfacl gna

Client

Konfiguration

# vi /etc/rc.conf:
nfs_client_enable="YES"       # This host is an NFS client (or NO).

Der Rechner kann neu gestartet werden, man kann die Client-Software aber auch manuel starten:

# nfsiod -n 4
"nfsiod" ist nicht zwingend erforderlich, verbessert aber die Leistung.
# mount  192.168.0.xxx:/datadir   /datadir

bei Problemen

UDP
# mount   -t nfs   -r=1024  192.168.0.xxx:/datadir   /datadir
# vi /etc/fstab
192.168.9.1:/cdrom    /scdrom   nfs   ro,noauto          0   0
192.168.9.1:/home     /home     nfs   rw                 0   0
192.168.9.1:/public   /home     nfs   rw                 0   0
TCP
# mount   -t nfs   -o tcp  192.168.0.xxx:/datadir   /datadir
# vi /etc/fstab
192.168.9.1:/cdrom    /scdrom   nfs   ro,tcp,noauto      0   0
192.168.9.1:/home     /home     nfs   rw,tcp             0   0
192.168.9.1:/public   /home     nfs   rw,tcp             0   0

oder (bei Problemen / Wenn der Server kein FreeBSD-Rechner ist.):

192.168.9.1:/cdrom    /scdrom   nfs   ro,r=1024,noauto   0   0
192.168.9.1:/home     /home     nfs   rw,r=1024          0   0
192.168.9.1:/public   /home     nfs   rw,r=1024          0   0

oder (bei Problemen / Wenn der Client kein FreeBSD-Rechner ist.):

192.168.9.1:/cdrom    /scdrom   nfs   ro,w=1024,noauto   0   0
192.168.9.1:/home     /home     nfs   rw,w=1024          0   0
192.168.9.1:/public   /home     nfs   rw,w=1024          0   0

Linux

NFS4 ohne Kerberos mounten; dabei werden die Originalrechte (uid,gid auf dem NFS4-Server) exportiert und gelten auch auf den anderen Maschinen!

Server

Vorbereitungen

# useradd kontor
# mkdir -p /home/kontor
# chmod 0775 /home/kontor
# chown kontor:nutzer /home/kontor

Konfiguration

# aptitude install nfs-kernel-server nfs-common portmap
# echo "portmap: ALL" >> /etc/hosts.deny
# echo "portmap: 192.168.0.0/16" >> /etc/hosts.allow
# echo "NEED_IDMAPD=yes" >> /etc/default/nfs-common
# 
# mkdir -p /export/kontor
# echo "/home/kontor    /export/kontor   none    bind  0  0" >> /etc/fstab
# mount /export/kontor
# #mount --bind /home/kontor/ /export/kontor/
# 
# sed -i -e 's/NEED_SVCGSSD=.*/NEED_SVCGSSD=no/' /etc/default/nfs-kernel-server
# sed -i -e 's/NEED_STATD=.*/NEED_STATD=no/' -e 's/NEED_IDMAPD=.*/NEED_IDMAPD=yes/' -e 's/NEED_GSSD=.*/NEED_GSSD=no/' /etc/default/nfs-common
# vi /etc/exports
...
/export        192.168.88.0/24(rw,fsid=0,insecure,no_subtree_check,async,sec=sys)
/export/kontor 192.168.88.0/24(rw,nohide,insecure,no_subtree_check,async,sec=sys)
/export/files  192.168.88.80(rw,insecure,no_root_squash,no_subtree_check,async,anonuid=1000,anongid=1000)
# /etc/init.d/nfs-kernel-server restart
# exportfs -r
# exportfs -v

Kontrolle

# exportfs -v
# showmount -e
# rpcinfo -p
# netstat -tunap

Client

Vorbereitungen

# useradd kontor
# mkdir -p /home/kontor
# chmod 0700 /home/kontor
# chown kontor:nutzer /home/kontor

Konfiguration

# aptitude install nfs-client nfs-common portmap
> vi /etc/fstab
...
192.168.88.218:/               /mnt           nfs4    _netdev,intr,proto=tcp,auto  0  0
192.168.88.170:/export/files   /emnt/files    nfs     _netdev,auto,sec=sys         0  0
# mount /mnt

Test

# root@nfsclient:~# ls -la /mnt/
insgesamt 16
drwxr-xr-x  4 4294967294 4294967294 4096  4. Nov 10:12 .
drwxr-xr-x 23 root       root       4096  2. Nov 16:48 ..
drwx------  3 4294967294 4294967294 4096  4. Nov 10:24 kontor
# root@nfsclient:~# ls -la /mnt/kontor/
ls: Öffnen von Verzeichnis /mnt/kontor/ nicht möglich: Keine Berechtigung
# root@nfsclient:~# su - kontor
# kontor@nfsclient:~$ ls -la /mnt/kontor/
# insgesamt 24
# drwx------ 3 4294967294 4294967294 4096  4. Nov 10:24 .
# drwxr-xr-x 4 4294967294 4294967294 4096  4. Nov 10:12 ..
# -rw------- 1 4294967294 4294967294   19  4. Nov 10:10 .bash_history
# drwx------ 2 4294967294 4294967294 4096  4. Nov 10:09 .ssh
# -rw-r--r-- 1 4294967294 4294967294   36  4. Nov 10:24 test.txt
# -rw------- 1 4294967294 4294967294  714  4. Nov 10:10 .viminfo

Wir sehen, ohne Kerberos, muss der User auf Server und Client die gleiche UID bzw. GID haben!

Das ist nicht sicher aber einfach!

Init-Skript zum mounten und umounten von NFS-Shares

#!/usr/bin/env bash
#
### BEGIN INIT INFO
# Provides:          mount_nfs
# Required-Start:    $network
# Required-Stop:     $network
# Default-Start:     S
# Default-Stop:      0 1 6
# Short-Description: NFS-mount+umount-Skript fuer Pacemaker
### END INIT INFO

# Author: M.Heins
VERSION="v2013102400"

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

MOUNTPOINT="${1}"       # /mnt
BEFEHL="${2}"           # start / stop / status

#------------------------------------------------------------------------------#

. /lib/lsb/init-functions

#==============================================================================#

if [ -z "${2}" ] ; then
        echo "${0} MOUNTPOINT BEFEHL"
        echo "${0} /mnt status"
        exit 2
fi

if [ -z "$(which lsof)" ] ; then
        echo "lsof muss installiert sein"
        exit 2
fi

#==============================================================================#

KONTROLLE="$(egrep -v '^[ \t]*#' /etc/fstab | fgrep noauto | fgrep nfs | fgrep "${MOUNTPOINT}")"
if [ -z "${KONTROLLE}" ] ; then
        echo "Konnte '${MOUNTPOINT}' in /etc/fstab nicht finden."
        exit 2
fi

if [ ! -d "${MOUNTPOINT}" ] ; then
        echo "Konnte '${MOUNTPOINT}' im Dateisystem nicht finden."
        exit 2
fi

#------------------------------------------------------------------------------#

PRUEFT="$(mount | fgrep "${MOUNTPOINT}")"

case ${BEFEHL} in
        status)
                if [ -n "${PRUEFT}" ] ; then
                        echo "${MOUNTPOINT} ist gemountet"
                        exit 0
                else
                        echo "${MOUNTPOINT} ist nicht gemountet"
                        exit 3
                fi
                ;;
        start)
                if [ -z "${PRUEFT}" ] ; then
                        mount ${MOUNTPOINT}
                fi
                ;;
        stop)
                while [ -n "$(lsof | fgrep " ${MOUNTPOINT}" | awk '{print $2}')" ]
                do
                        echo "Warte bis die noch offenen Datei-Haendler auf '${MOUNTPOINT}' geschlossen sind..."
                        sleep 4
                        RPIDS="$(lsof | fgrep " ${MOUNTPOINT}" | awk '{print $2}' | sort | uniq)";
                        if [ -n "${RPIDS}" ] ; then
                                kill ${RPIDS};
                                sleep 4 ;
                                kill -9 ${RPIDS};
                        fi;
                        sleep 4 ;
                done
                if [ -n "${PRUEFT}" ] ; then
                        umount -f ${MOUNTPOINT}
                fi
                ;;
        *)
                echo "Der Parameter '${BEFEHL}' wird nicht unterstuetzt."
                ;;
esac

exit 0
/home/http/wiki/data/pages/nfs.txt · Zuletzt geändert: von manfred