By default, OpenBSD includes all the programs necessary to act as an NFS server, but you must turn it on. The NFS server requires three daemons:
portmap(8)
. Maps requests for remote procedure call (RPC) services to TCP/IP port numbers.
mountd(8)
. Listens for incoming NFS mount requests.
nfsd(8)
. Processes requests for filesystem actions.
The portmap(8)
daemon has its own rc.conf flag, as it can be used by many other RPC services. The mountd(8)
and nfsd(8)
daemons are controlled by a single rc.conf flag.
Add the following entries to rc.conf.local to start all three processes at boot time:
portmap=YES nfs_server=YES
You can start these three daemons from scripts in /etc/rc.d. If you try to start these daemons now, however, they won’t run. You must configure at least one export before the NFS server daemons will start.
To export filesystems, define which clients may mount which filesystems and/or directories in /etc/exports. This file takes a separate line for each disk device on the server and each client or group of clients that can access that disk device. Each line has up to three parts:
Directories or partitions to be exported
Options on that export
Clients permitted to connect
Of the three components of an /etc/exports entry, only the directory is mandatory. The directory path cannot contain symlinks, double dots, or single dots.
If I wanted to export my home directory as read-write to every host on the Internet, I could use an exports line containing only the path to my /home folder:
/home/mwlucas
This perfectly valid (but perfectly foolish) entry contains no options and no host restrictions.
To export multiple directories that reside on the same partition, separate them with a single space.
/home/mwlucas /home/lasnyder
You can list any number of directories on one line, as long as they exist on the same partition.
NFS clients can mount only exactly the directory specified in /etc/exports. If you export /home/mwlucas, clients can attach only /home/mwlucas to a mount point. They cannot mount, say, /home/mwlucas/bin instead. If you would like to export an entire partition, you can do that, too. If you want to let clients mount any directories beneath that mount point, specify the mount point and the -alldirs
option. You cannot use -alldirs
with a subdirectory; it must be the actual mount point. This next entry lets anyone mount any directory in /home:
/home -alldirs
To export multiple partitions, or directories from multiple partitions, specify them on separate lines.
/home -alldirs /var/log
Any time you change /etc/exports, you must signal mountd
to reread its configuration. You can do this by passing the reload
argument to the mountd
startup script:
# /etc/rc.d/mountd reload
While these simple mounts give you an idea of how NFS works, they’re very insecure. To make an intelligent export, you need a few options and an access list. Let’s take a look at some of NFS’s more commonly used options.
You might want to share files without worrying about whether your underlings will delete, modify, or otherwise undo your hard work. You can share files as read-only by using the -ro
option. Here, I offer my home directory to all the computers in the world, but as a read-only share:
/home/mwlucas -ro
This is slightly more intelligent than offering my NFS exports to the entire world read-write, but only slightly.
You already know that file ownership and permissions are tied to UID numbers. Unlike many other file-sharing protocols, NFS also uses UIDs to identify file ownership. For example, on my test server, my account mwlucas
uses the UID 1000; on my client, my mwlucas
account also uses the UID 1000. This simplifies my life, as I don’t need to worry too much about file ownership; files owned by mwlucas
on the server are owned by mwlucas
on the client.
On a small network with only a few users and machines,[22] you can probably keep UID numbers synchronized without a problem by assigning the same UID to the same user on all of your systems. But on a large network, with more than one user and where users have root on their own machines, file ownership can quickly become a serious problem. The best way around this is to maintain a central repository of authorized users via LDAP or Kerberos.
Regardless of how you manage your users, NFS handles the root account differently. An NFS server cannot trust root on client machines to execute commands or write files as root on the server; if that were the case, a breach on one NFS client would mean a breach on the NFS server. By default, requests from root on the client are mapped to UID and GID 32767 (also known as nobody
).
If you want to map root to a specific user rather than the generic UID nobody
, use the -maproot
option and specify either a username or UID. Here, we map incoming requests from root on the client to the user nfsroot
on the server:
/home/mwlucas -maproot=nfsroot
You can give the mapped root user a list of groups that the remote root account can access by specifying them after the username, separated by colons. Here, we give the client’s root user access to the server as the user nfsroot
and the groups customers
and webmasters
:
/home/mwlucas -maproot=nfsroot:customers:webmasters
If you want to explicitly remove the mapped root user from all groups, put a colon after the username or UID, as in this example:
/home/mwlucas -maproot=nfsroot:
Suppose you want all the NFS clients, regardless of username on the client system, to use a single user ID on the NFS server. The -mapall
option allows you to do this. This option uses the same format as the -maproot
option. Here, we map all NFS users to the username nfsuser
on the server:
/home/mwlucas -mapall=nfsuser
Correct control of user access will help protect your NFS server.
By default, every host can access your NFS server. For many reasons, that’s not a great idea. You can restrict the clients permitted to access your NFS server by listing their IP addresses at the end of the export entry.
/home/mwlucas 192.0.2.1
You can also specify clients by their hostname, but if the server has a DNS failure, it won’t allow any clients access.
/home/mwlucas treble.blackhelicopters.org
To permit access to an entire network, use the -network
and -mask
options. The next example permits access to the addresses 192.0.2.0 through 192.0.2.15, using a subnet mask. (If you’re not familiar with subnet masks, read Chapter 11.)
/home/mwlucas -network=192.0.2.0 -mask=255.255.255.240
When setting up your NFS server, I recommend you grant access to only the hosts who need it.
You can have only one line for each combination of partition and permitted clients. If /home is a single partition, you can’t have an exports file that looks like this:
/home/mwlucas -maproot=nfsroot: 192.0.2.1 /home/pkdick 192.0.2.1
If two directories are located on the same partition, NFS will not allow you to export them to the same host using different permissions. You can, however, export directories on one partition to different hosts with different permissions, as shown here:
/home/mwlucas -maproot=nfsroot: 192.0.2.1 /home/pkdick 192.0.2.2
You can export directories on a partition to different hosts with different permissions.
/home/mwlucas -maproot=nfsroot: 192.0.2.1 /home/mwlucas -maproot=root 192.0.2.2
Only by combining IP restrictions and controlling user permissions can you can effectively control NFS server access.