NFS HOWTO

NFS HOWTO

V.0.2

        If there are any questions or comments, please direct them to
walt@erudition.net. The newest copy of this HowTo can always be retrieved
from www.freebsd-howto.com. All rights for the reproduction of this
document are reserved.

	Summary.

	This HowTo deals with the theory behind and configuration of
NFS (Network FileSystem) on FreeBSD.


	1.	Background - What is NFS?

        2.      Deployment
        2.1.    Configuring NFS Server
	        2.1.1.  portmap(8)
	        2.1.2.  mountd(8)
	        2.1.3.  nfsd(8), Reserved Ports, rpc.lockd(8)
	        2.1.4.  exports(5)

        2.2.    NFS Clients, nfsiod(8)
        2.3.    Mount NFS exported Filesystems or Directories

	3.	Appendix












	1.	Background		

	NFS, an acronym for 'Network FileSystem', is a method for
distributing a filesystem across multiple hosts on a local or wide area
network. Instead of other methods for exchaging files between hosts, such
as ftp and scp, NFS allows one to treat moving files between multiple
hosts as if the move was being made on a single filesystem. On Windows
systems this is accomplished through Windows 'shares' (shared
Windows partitions). Because of this, NFS allows for a very convenient
method in manipulating files between multiple, trusted, hosts.

	Because of security considerations resulting from the NFS
protocol, it is strongly recommended that NFS not be deployed across
wide area networks, especially not between untrusted hosts or across
untrusted network channels, such as the internet. For local area network
purposes, NFS supplies a convenient and relatively safe method for file
exchange between hosts using all of the convenience and power of regular
shell commands such as mv(1) and cp(1).  

	For a clearer understanding of what NFS is, let us take two
example hosts: A and B. Host A will serve out one of its filesystems to
host B so that host B will be able to view all files on the host A
filesystem as if they were located locally on host B. The host that serves
out the filesystem(s) is termed the "NFS Server", while the host accesses
the served filesystem(s) is termed the "NFS Client." It is possible for a
particular host to be both an NFS server and client; in our example, each
host will only perform one of the actions.

	Our NFS server (host A) will serve out the filesystem mounted
locally on its mount point /serve/data/. Our NFS client will mount this
served out filesystem on its local mount point /nfs/A/data/. On the NFS
client, when it runs 'ls /nfs/A/data/' the following output displays:

	data.1
	data.2
	data.3
	INDEX

	To copy the data to one of its local filesystems, the
command 'cp data.* /tmp/data' is issued in the directory /nfs/A/data/ on
the NFS client, and the data files are copied from the NFS server's
filesystem to a directory in the /tmp filesystem on the NFS client. If the
command mv(1) were attempted instead of cp(1), then the following error
would have shown:

	mv: Operation not permitted

	This is because when accessing NFS mounted filesystems, one does
not operate with the same user ID as one does on the local host. The user
ID with which NFS clients can access a served filesystem (hereafter known
as an 'exported filesystem) is determined by the NFS server, thus
restricting operations on the exported files according to the
administrator's discretion. One can, although it is rarely recommended,
allow access to NFS exported filesystems as root, or other high level user
IDs, so that, in the case of the root user ID, NFS clients can perform
operations on the NFS exported filesystem as if they were local root.

	Although, NFS is usually deployed by serving entire filesystems, a
presumption dominating the previous discussion, directory structures not
constituting an entire filesystem can be exported as well. This allows for
an even greater amount of flexibility.


	2.	Deployment

	NFS can be deployed without too much difficulty. First, determine
which hosts will be exporting filesystems/directories and with what
permissions one wishes to export them (that is, as what user ID as
discussed above). We will use the example filesystems used to illustrate
NFS functionality from above. In our following discussion we are presuming
that each of the hosts is on a local network and already configured for
communication via TCP/IP across that network.

	2.1.	Configuring NFS Server.

	2.1.1.	portmap(8)

	The first task at hand is to configure the NFS server. Because NFS
operates as an RPC service, it requires that portmap(8) be running on both
the NFS server and client. RPC (Remote Procedure Call) services allow
programs to make procedure calls across a network to other hosts. Portmap
converts RPC program numbers into DARPA protocol port numbers, hence, it
is vital for RPC service operation. By default the portmap daemon is set
to start during bootup. If this had been disabled in /etc/rc.conf with the
line 'portmap_enable="NO"' at some previous time, remove this line
accordingly from both the NFS server and client hosts, and then start the
portmap service by typing (remember, you must be root):

	(root@A)/># /usr/sbin/portmap

	Verify that the daemon is running:	

	(root@A)/># ps aux | grep portmap
	daemon 105 0.0 0.3 884 496 ??  Is Thu07PM 0:00.01 /usr/sbin/portmap
	(root@A)/>#

	2.1.2.	mountd(8)

	The mountd(8) daemon is vital for NFS operation. It services NFS
mount requests of NFS exported filesystems by NFS clients. By default it
is started during bootup if an /etc/exports file exists. On a clean
FreeBSD installation the /etc/exports file does NOT exist, therefore, you
will need to manually start the mountd(8) daemon, along with create an
/etc/exports file, whose configuration will be explained later.

	to start the mountd(8) daemon, simply type:

        (root@A)/># /sbin/mountd -rl

	Verify that the daemon is running:

	(root@erudition)/># ps aux | grep mountd
	root  110  0.0  0.2  500  304  ??  Is  Thu07PM  0:00.04 mountd -rl
	(root@A)/>#

	The -r flag will allow the mounting of directories which are
exported instead of the entire filesystem, and the -l flag will log NFS
mount requests.

	2.1.3.	nfsd(8), Reserved Ports, rpc.lockd(8)

	Next, one must enable the NFS server daemon. Usually four
instances of the server daemon are initiated. To make sure that the daemon
instances are started during host bootup, enter the following lines into 
/etc/rc.conf:

	nfs_server_enable="YES"
	nfs_reserved_port_only="YES"
	rpc_lockd_enable="YES"

	The first line is self-explanatory. By default the NFS server
daemon (nfsd) is started with four instances of itself. The second line
allows NFS to only travel across a reserved port. Reserved ports are ports
< 1024, which processes that are owned by regular system users can not
bind to. This allows an extra element of security by preventing regular
users from starting NFS clients and mounting NFS exported filesystems or
directory structures. The last line enables file/record locking across
NFS by starting the rpc.lockd(8) daemon. It is necessary for proper NFS
functioning.

	Next, lest one wish to have to reboot to enable the above options,
type the follow command at the prompt:

	(root@A)/># nfsd -n 4
	(root@A)/>#

	Verify that the NFS server daemons have been started:

	(root@A)/># ps x | grep nfsd
	  113  ??  Is     0:00.01 nfsd: master (nfsd)
	  115  ??  I      0:00.00 nfsd: server (nfsd)
	  116  ??  I      0:00.00 nfsd: server (nfsd)
	  117  ??  I      0:00.00 nfsd: server (nfsd)
	  118  ??  I      0:00.00 nfsd: server (nfsd)
	(root@A)/>#

	Then, specify that NFS only be done over reserved ports:

	(root@A)/># sysctl -w vfs.nfs.nfs_privport=1
        (root@A)/>#

	2.1.4.	exports(5)

	Finally, we must configure the /etc/exports file to set up which
filesystems and directory structures will be exported, and to which NFS
clients we will allow that exportations along with their corresponding 
permissions. Open the /etc/exports file in your favourite text editor.

	The format of the entries is simple:

	<filesystem | directory> <permissions> <host1, host2, host3...>

	Or alternatively, if one wishes to allow permission for an entire
network easily:

	<filesystem | directory> <permissions> -network=<net> -mask=<mask>

	The first column contains the filesystem or directory structure
being exported. The second column contains the UIDs as which NFS clients
will be able to read exported files, whether the exported mounts will be
read/write or read-only, and some additional miscellaneous options which
we will not concern ourselves with in this HowTo. The final column(s)
contains a list of one or more hosts which will be allowed to NFS mount
the exported filesystems or directories or the network and its mask that
will be allowed to NFS mount the exported filesystems or directories.

	For instance, if we use our original example, one of our
/etc/exports entries may look like this:

	/serv/data	-maproot=nobody -ro	B 

	The filesystem that the NFS server will export is mounted on
/serv/data, it will export it as read only (-ro) and such that when root
processes on NFS client A accesses it, it will access it as user 'nobody'
(UID 65534), and only host named 'B' will be able to NFS mount this
filesystem.

	The most common permission options available are:

	-maproot=<user | UID>. This maps remote accesses to the NFS
exported filesystem or directory with the specified user or UID, thus
preventing root processes on NFS clients from being able to perform with
root privileges on the NFS server.

	-mapall=<user | UID>. This maps all remote accesses to the NFS
exported filesystem or directory with the specified user or UID, thus
preventing any processes on NFS clients from being able to perform with
the privileges of any users with the same UID on the NFS server; it allows
for a very restricted control of what UIDs will be accessing the exported
mounts.

	-ro. This only allows read-only access to the NFS exported
filesystem or directory.

	Hosts which will be allowed to NFS mount the exported filesystem
or directory can be specified by name or IP. Specification by IP is safer
in case DNS information is spoofed thus inadvertently allowing exports to
unintended hosts.

	Once the /etc/exports file is completed, a Hangup signal must be
sent to the mountd(8) daemon so it will reread /etc/exports:


	(root@A)/># killall -HUP mountd
	(root@A)/>#

	Your NFS server configuration is complete.

	2.2.	NFS Clients, nfsiod(8)	

	Next, each NFS client must be configured. Portmap(8) is required
on the NFS clients as well; the previous explanations about portmap(8) in
the NFS server section apply wholly to NFS clients as well. Mountd(8) is
not required on NFS client hosts unless they are also acting as NFS
servers. NFS client daemons, however, are required. To ensure that the NFS
client daemons start during bootup, enter the following lines into
/etc/rc.conf:

	nfs_client_enable="YES"
	nfs_reserved_port_only="YES"

	Finally, lest you wish to reboot to have these options enabled,
type the following on your NFS client host to start the NFS client daemon
instances:

	(root@B)/># nfsiod -n 4
        (root@B)/>#

	Verify that the NFS client daemons have been started:

	(root@B)/># ps x | grep nfsiod
	  125  ??  I      0:00.00 nfsiod -n 4
	  126  ??  I      0:00.00 nfsiod -n 4
	  127  ??  I      0:00.00 nfsiod -n 4
	  128  ??  I      0:00.00 nfsiod -n 4
	(root@B)/>#

	And, finally, enable NFS over private ports with:

        (root@B)/># sysctl -w vfs.nfs.nfs_privport=1
        (root@B)/>#

	Your NFS client configuration is complete.

	2.3.	Mount NFS exported Filesystems or Directories

	Once the NFS server and client have been configured, we must mount
the NFS exported filesystems or directories on the NFS client. Create the
mount points at which you would like to mount the NFS exports, just as you
would for regular, local, HD filesystems. In our original example we used
the directory /nfs/A/data/ on which we mounted the NFS export. Continuing
with this example, let us supposed we have the filesystem /serve/data/ on
host A that we wish to mount on /nfs/A/data/. To accomplish this, we will
use the mount(8) command at the NFS client command prompt (as root):

	(root@B)/># mount -t nfs A:/serve/data /nfs/A/data
	(root@B)/>#

	To Verify that the mount took hold, we can simply use df(1). To
simplify the mounting process, we can use /etc/fstab entries to both
simplify the mounting syntax and allow NFS mounts to take hold during
boot-time. An /etc/fstab entry for the above command would look like thus:

	A:/serve/data	/nfs/A/data	nfs	rw	0	0

	It is strongly recommended that the 'soft' option be used also:

        A:/serve/data   /nfs/A/data     nfs     rw,soft      0       0

	The 'soft' option allows bad NFS RPC requests to timeout,
otherwise, the process that made the RPC request will hang and will NOT be
able to be killed. Bad NFS RPC requests usually occur when the NFS server
has shut down or is experiencing network conneectivity problems. In such
cases, the RPC call from the NFS client will not succeed. Because NFS RPC
requests can potentially, permanently hang the process that called made
them, this is an ugly shortcoming of the NFS implementation. The 'soft'
option allows for NFS RPC requests to timeout and thus avoid this
shortcoming if the NFS server is unable to respond.

	Once the /etc/fstab entry is completed, the NFS mount will be
done during boot up, and/or can be easily done at the command prompt with:

	(root@B)/># mount /nfs/A/data
        (root@B)/>#

	If one does not wish to have the NFS export(s) mounted during
bootup, but still have the /etc/fstab entry for the convenient manual
mounting, then simply add the 'noauto' option in the /etc/fstab entry.

	
	3.	Appendix
	
	Manual Page Resources:

	8 portmap
	8 mountd
	8 nfsd
	8 rpc.lockd
	5 exports
	8 nfsiod
	5 fstab	
	8 sysctl

Leave a Reply

Your email address will not be published. Required fields are marked *