Friday, October 10, 2014

NFS - Network File System


What is NFS?

Network File System or NFS is a client/server system. It allows users to access files across network and the shared files/directories from remote are treated as if they reside on local system.

Works on both TCP and UDP protocol.

The stateless UDP connection under normal conditions has less Protocol overhead than TCP which can translate into better performance on very clean, non-congested networks.

Note (From CentOS official docs):

NFSv4 has no interaction with portmapper, rpc.mountd, rpc.lockd, and rpc.statd, since protocol support has been incorporated into the v4 protocol. NFSv4 listens on the well known TCP port (2049) which eliminates the need for the portmapper interaction. The mounting and locking protocols have been incorpated into the V4 protocol which eliminates the need for interaction with rpc.mountd and rpc.lockd.

Salient features:

* A NFS file system mounted is very similar to a local file system on the machine
* NFS does not disclose the location of a file on the network
* An NFS server can be made of a completely different architecture and operating system
        than the client
* It also never discloses the underlying file system on the remote machine

Versions:
Currently there are three versions available viz. NFSv2, NFSv3 & NFSv4

Setup on CentOS-6.5 systems:
Following are the IP details of the server and the Client for this example setup;

i. Server: 172.16.20.8
ii. Client: 172.16.20.9

A. NFS Server (IP 172.16.20.8):

1. Install the packages;
yum install nfs*

2. Start the NFS service;
# service nfs start
Starting NFS services:      [  OK  ]
Starting NFS mountd:        [  OK  ]
Starting NFS daemon:        [  OK  ]
Starting RPC idmapd:        [  OK  ]

[NOTE:  Although, it is mentioned that rpcbind (earlier Portmapper) services are incorporated into NFS-V4 and there is no need to start the rpcbind service explicitly, I encountered NFS services failed to start without explicitly starting the "rpcbind" service; thus if you encounter the same, start the rpcbind service as; 

# service rpcbind start

Starting rpcbind:                                          [  OK  ]
]


3. Ports it listen to;

111/tcp  open  rpcbind
2049/tcp open  nfs

4. Open the relevant ports in the firewall so that they are accessible;

# iptables -I INPUT 4 -p tcp --dport 111 -j ACCEPT
# iptables -I INPUT 4 -p tcp --dport 2049 -j ACCEPT

Note: Number '4' is the position in the INPUT chain where these records are inserted, could be different in your case. Find that out using "iptables -L INPUT --line-numbers"

5. Create a NFS share;
mkdir /nfsshare

6. Share the directory with NFS client (172.16.20.9):

vi /etc/exports
/nfsshare 172.16.20.9(rw,sync,no_root_squash)


B. On the Client (172.16.20.9):

1. Install the packages
        #yum install nfs*

2. Start NFS service;
        # service nfs start

3. You may check all the rpcservices information on the server using;
         # rpcinfo -p 172.16.20.8

2. Create the mount point to mount the NFS share;
# mkdir /opt/nfs_share

3. Mount the NFS share directory from the NFS server to the client;
# mount -t nfs 172.16.20.8:/nfsshare/ /opt/nfs_share/

4. Check with mount command;
# mount
/dev/vda1 on / type ext4 (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
tmpfs on /dev/shm type tmpfs (rw,rootcontext="system_u:object_r:tmpfs_t:s0")
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw)
nfsd on /proc/fs/nfsd type nfsd (rw)
172.16.20.8:/nfsshare/ on /opt/nfs_share type nfs (rw,vers=4,addr=172.16.20.8,clientaddr=172.16.20.9)

5. On the client, one may also check with 'nfsstat -m' command (displays details about nfs mounts)

# nfsstat -m
/opt/nfs_share from 172.16.20.8:/nfsshare/
Flags:
rw,relatime,vers=4,rsize=262144,wsize=262144,namlen=255,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=172.16.20.9,minorversion=0,local_lock=none,addr=172.16.20.8

Now, create files or directories under /opt/nfs/ (on the client) or /nfsshare on the server to see if they are visible/accessible to each other.

C. NFS Options:

1. The following would provide statistics about NFS server and client respectively;
nfsstat -s
nfsstat -c

2. Important configuration files (all man page info);

/etc/sysconfig/nfs
/etc/nfsmount.conf ---->  Configuration  file  for  NFS  mounts  that  allows options to be set
                                             globally, per server or per mount point.
/etc/exports     ---->  Contains  a table of local physical file systems on an NFS server that
                                             are accessible to NFS clients.

3. Any changes to the /etc/exports would only require to have NFS services reloaded to
        make the changes effective. This does not require clients to unmount NFS share or the
        any service restarts on clients and server.

eg.

Thus, an entry like the following in /etc/exports;
/nfsshare 172.16.20.9(rw,sync,no_root_squash)

when changed to ('rw' to 'ro');
/nfsshare 172.16.20.9(ro,sync,no_root_squash)

It only needs 'service nfs restart' on the NFS Server to make the changes effective.


D. NFS share options:

1. ro:    With the help of this option we can provide read only access to the shared files i.e client
                will only be able to read.

2. rw:   This option allows the client server to both read and write access within the shared
                directory.

3. sync:   Sync confirms requests to the shared directory only once the changes have been
                  committed.

4. no_subtree_check:   This option prevents the subtree checking. When a shared directory
                                       is the subdirectory of a larger file system, nfs performs scans of every
                                       directory above it, in order to verify its permissions and details.

                   Disabling the subtree check may increase the reliability of NFS, but reduce security.

5.     no_root_squash:    This phrase allows root to connect to the designated directory.
                                     Thus, remote  "root" user on the client would be treated a                                  
                                     local "root" user on the server.
                                      The opposite is "root_squash".

Issues:
1. # showmount -e
clnt_create: RPC: Unknown host

Solution: Check using;

                # showmount -e localhost
         Export list for localhost:
        /nfsshare 172.16.20.9

         Now, provide a hostname entry with IP in the /etc/hosts as;
         172.16.20.8 ins-1

         Where, ins-1 is the hostname as revealed by;
           # hostname
           ins-1