====== NFS ====== ===== Allgemein ===== * [[http://wiki.ubuntuusers.de/NFS]] * [[http://nfs.sourceforge.net/nfs-howto/ar01s07.html]] * [[http://notes.setvisual.de/NFSv4%20mit%20Ubuntu]] * [[https://help.ubuntu.com/community/NFSv4Howto]] 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 /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= | 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 ===== siehe: **man mount_nfs** * [[http://www.freebsd.org/doc/de_DE.ISO8859-1/books/handbook/network-nfs.html]] ==== 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 === - FreeBSD 8.0 enthält ZFS in der Version 13 - 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: * [[::freebsd:zfs#zfs-volumen_auf_platte_anlegen]] 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