Monday 17 February 2014

ELA_36_Network File System(NFS)

Network File System(NFS)


NFS Network File System is a server-client protocol used for sharing files on Unix, Linux systems. It allows sharing files from a central server allowing several users to access and modify the same files from different clients making all the changes on the files visible on all clients. The NFS server/client can be running on different S.O. without any problem.

NFS Server

In order to configure a node as NFS server the packages 'nfs-utils' and 'rpcbind' must be installed and running :

# yum install rpcbind nfs-utils

# /etc/init.d/nfs start
# /etc/init.d/nfslock start
# /etc/init.d/rpcbind start
# chkconfig nfs on
# chkconfig nfslock on
# chkconfig rpcbind on


NFS uses portmap (rpcbind) services to export files/directories to other nodes so rpcbind service must be running. The nfs service starts the following processes :

* rpc.mountd
Handles mount requests.

* nfsd
Starts an nfsd kernel process for each shared directory.

* rpc.rquotad
Reports disk quota statistics to clients.

* rpc.svcgssd
Gives a security api to provide security for protocols using rpc (in particular, nfs).

If any of these processes is not running, NFS won't work properly. In order to check if any of these processes are running the command 'rpcinfo -p' can be used :

# rpcinfo -p

/etc/exports

This is the most important file on NFS server configuration. It lists the directories to be exported from the NFS server to clients, the hosts to which it will be exported, and the options that apply to this export. The line format is the following :

(directory) (host1)(options1) (hostN)(options2)

Where directory is a local directory on the NFS server to be exported to host1 with options options1 and to host2 withoptions2. Lets se some examples :

# cat /etc/exports

/pub (ro,insecure,sync) node01.info.net(rw,insecure,sync)
/home *.info.net(rw,insecure,sync)
/tftpboot diskless.info.net(rw,insecure,no_root_squash,sync)
/tmp 192.168.1.0/24(ro,sync,no_wdelay)


The first line exports the /pub directory in read-only mode to everybody less to node01.info.net that is exported in read-write mode. The second line the /home directory is exported in read-write mode to all computers on info.net domain. On the third line the directory /tftpboot is exported in read-write mode to all users (included root) to the computer diskless.info.net. Finally on last line the directory /tmp is exported in read-only mode to all nodes on LAN 192.168.1.0/24.

The sync flag requires all changes to be written to disk before a command such as a file copy is complete. The insecure flag allows access on ports above 1024.

Once configured /etc/exports file the command 'exportfs -a' must be executed to notify nfs daemon for the new exports :

# exportfs -a

NFS Security

Firewall

NFS uses portmap in order to execute some of its network services and by default portmap uses random UDP/TCP ports. This can be a problem when NFS must be configured in order to offer service through a firewall because this ports are randomly assigned. Solution: fix the ports used by NFS-portmap services and then open this ports on the firewall. This action can be done configuring/fixing the NFS-portmap ports on /etc/sysconfig/nfs file.

# cat /etc/sysconfig/nfs

...
RQUOTAD_PORT=60001
...
LOCKD_TCPPORT=60002
...
LOCKD_UDPPORT=60002
...
MOUNTD_PORT=60003
...
STATD_PORT=60005
...
STATD_OUTGOING_PORT=60004
...


In order to apply this changes correctly the best way is reboot the node and verify that the NFS-portmap port used are fixed.

# netstat -putan | grep rpc

tcp 0 0 0.0.0.0:60001 0.0.0.0:* LISTEN 1785/rpc.rquotad
tcp 0 0 0.0.0.0:60003 0.0.0.0:* LISTEN 1801/rpc.mountd
tcp 0 0 0.0.0.0:60005 0.0.0.0:* LISTEN 1258/rpc.statd
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 1233/rpcbind
tcp 0 0 :::60005 :::* LISTEN 1258/rpc.statd
tcp 0 0 :::111 :::* LISTEN 1233/rpcbind
udp 0 0 0.0.0.0:984 0.0.0.0:* 1233/rpcbind
udp 0 0 0.0.0.0:60001 0.0.0.0:* 1785/rpc.rquotad
udp 0 0 0.0.0.0:60003 0.0.0.0:* 1801/rpc.mountd
udp 0 0 0.0.0.0:60005 0.0.0.0:* 1258/rpc.statd
udp 0 0 0.0.0.0:111 0.0.0.0:* 1233/rpcbind
udp 0 0 0.0.0.0:1010 0.0.0.0:* 1258/rpc.statd
udp 0 0 :::984 :::* 1233/rpcbind
udp 0 0 :::60005 :::* 1258/rpc.statd
udp 0 0 :::111 :::* 1233/rpcbind


Now the ports has been fixed and is time to open the ports on the firewall.

# cat /etc/syscopnfig/iptables
...
-A INPUT -m state --state NEW -m tcp -p tcp --dport 2049 -j ACCEPT
-A INPUT -m state --state NEW -m udp -p udp --dport 2049 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 111 -j ACCEPT
-A INPUT -m state --state NEW -m udp -p udp --dport 111 -j ACCEPT
-A INPUT -m state --state NEW -m udp -p udp --dport 60001 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 60001 -j ACCEPT
-A INPUT -m state --state NEW -m udp -p udp --dport 60003 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 60003 -j ACCEPT
-A INPUT -m state --state NEW -m udp -p udp --dport 60004 -j ACCEPT
-A INPUT -m state --state NEW -m udp -p udp --dport 60005 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 60005 -j ACCEPT


Port 2049 TCP/UDP is from the NFS service itself, the port 111 TCP/UDP is portmap (rpcbind) and the rest are the NFS-portmap ports fixed on /etc/sysconfig/nfs file.

# /etc/init.d/iptables restart

SElinux

If your server is protected by SElinux some SElinux-NFS booleans can be configured in order to allow NFS process to be executed without any SElinux interference. By default all this values are enabled.

# setsebool -P allow_gssd_read_tmp 1
Supports the reading of temporary directories by the General Security Services daemon, gssd, which helps protect NFS using Kerberos

# setsebool -P allow_nfsd_anon_write 1
Supports NFS servers when they modify files on public file transfer services.

# setsebool -P nfs_export_all_ro 1
Supports read-only access to shared NFS directories.

# setsebool -P nfs_export_all_rw 1
Supports read-write access to shared NFS directories.

# setsebool -P use_nfs_home_dirs 1
Allow the export of home directories.

If a new directory (/newdir) has been created on the NFS server, in order to export it in read-write mode it must be labelled with the 'public_content_rw_t' SElinux label if we want write on it assuming that the mentioned SElinux-NFS booleans has been configured.

chcon -R -t public_content_rw_t /newdir

Security Considerations

NFS includes a number of security problems and should never be used in hostile environments such as the Internet. The main security problems can be listed as :

* Portmap (rpcbind) services used on NFS Server/Client transactions are not secure.

* Authentication relies on the host to report user and group IDs. This can expose your files if root users on other computers access your NFS shares as root. Data that is accessible via NFS to any user can potentially be accessed by any other user. By default, NFS is set up to root_squash, which prevents root users on an NFS client from gaining root access on the NFS server.

* Be careful with any symbolic links on an exported directory. The client interprets a symbolically linked file with respect to its own local filesystem.

NFS Client

When you start NFS-Client command such as 'mount' the following processes are executed :

rpc.statd
Control the status of NFS servers from the client.

rpc.lockd
Manages file locking on client side. It allows simultaneous access to the same file from different NFS-Clients.

In order to list the NFS shares accessible from a client the command 'showmount' can be used :

# showmount -e rhel6

Export list for rhel6:
/tmp 192.168.1.0/24


As we can see the /tmp NFS share is exported from rhel6 NFS server to all nodes on LAN192.168.1.0/24. In order to mount that NFS share on a local directory the command 'mount can be used' :

# mount -t nfs -o defaults,soft,timeo=100 rhel6:/tmp /mnt

With this command the NFS share /tmp exported from rhel6 server has been mounted locally on /mnt directory in 'soft,timeo=100' mode that makes that the NFS client does not crash in case of connectivity problems with the NFS server. Just use the 'mount' command to verify it :

# mount
...
rhel6:/tmp on /mnt type nfs (rw,soft,timeo=100,vers=4,addr=192.168.1.10,clientaddr=192.168.1.101)
As can be seen /tmp NFS share from rhel6 (192.168.1.10) has been mounted on /mnt of the NFS client (192.168.1.101) in read-write mode.

Lets try to write on it.

# touch /mnt/file

# ls -lrt /mnt/file

-rw-r--r--. 1 nfsnobody nfsnobody 0 Feb 17 2011 /mnt/file


Note that the file created belongs to 'nfsnobody' user and not to 'root'.

The file '/etc/fstab' can be used in order to mount NFS shares on boot time. For the case exposed before just add the corresponding line on /etc/fstab.

# echo "rhel6:/tmp /mnt nfs defaults,soft,timeo=100 0 0" >> /etc/fstab

NFS over UDP

NFS server runs over TCP by default but shares can be mounted on NFS clients using udp protocol :

# mount -o udp rhel6.info.net:/tmp /mnt

This action increases the performance on read-write operations on the NFS share but it decreases the fault tolerance because of TCP is connection oriented and UDP is not. You can read/write faster on the NFS share but the probability of get/create corrupted data higher than using TCP protocol.

NFS Limitations

Some limitations derived from NFS architecture has to be considered :

* The stateless nature of the NFS protocol makes that the NFS client wait if the NFS server ever has to be rebooted. The client waits, and waits, and waits ... Using the 'soft' option when mounting NFS filesystems, when an NFS server fails, a soft-mounted NFS filesystem will fail rather than hang.

* NFS relies heavily on DNS direct and reverse name resolution. If NFS can't find a host name, rpc.mountd will deny access to that client. For security reasons, it also adds a "request from unknown host" entry in /var/log/messages.

No comments :

Post a Comment