NFS, or Network File System, is a distributed file system protocol that allows you to mount remote directories on your server. This lets you manage storage space in a different location and write to that space from multiple clients. NFS provides a relatively standard and performative way to access remote systems over a network and works well in situations where the shared resources must be accessed regularly.
In this guide, you’ll learn how to install the software needed for NFS functionality on Ubuntu 18.04, configure NFS mounts on a server and client, and mount and unmount the remote shares.
We’ll use two servers in this tutorial, with one sharing part of its filesystem with the other. To complete this tutorial, you will need:
Two Ubuntu 18.04 servers. Each of these should have a non-root user with
sudo privileges configured, a firewall set up with UFW, and private networking if it’s available to you.
Throughout this tutorial, we refer to the server that shares its directories as the host and the server that mounts these directories as the client. We’ll use the following IP addresses as stand-ins for the host and client values:
When these IP addresses appear in commands and configuration files, replace them with your own respective host and client IP addresses.
First begin by installing the necessary components on each server.
On the host server, install the
nfs-kernel-server package, which will allow you to share your directories. Since this is the first operation that you’re performing with
apt in this session, refresh your local package index before the installation:
- sudo apt update
Next, install the package:
- sudo apt install nfs-kernel-server
Once these packages are installed, switch to the client server.
On the client server, install a package called
nfs-common, which provides NFS functionality without including server components. Again, refresh the local package index prior to installation to ensure that you have up-to-date information:
- sudo apt update
Then, install the package:
- sudo apt install nfs-common
Now that both servers have the necessary packages, you can start configuring them.
We’re going to share two separate directories with different configuration settings in order to illustrate two key ways that NFS mounts can be configured with respect to superuser access.
Superusers can do anything anywhere on their system. However, NFS-mounted directories are not part of the system on which they are mounted, so by default, the NFS server refuses to perform operations that require superuser privileges. This default restriction means that superusers on the client cannot write files as root, reassign ownership, or perform any other superuser tasks on the NFS mount.
Sometimes, however, there are trusted users on the client system who need to perform these actions on the mounted file system but who have no need for superuser access on the host. You can configure the NFS server to allow this, although it introduces an element of risk, as such a user could gain root access to the entire host system.
In the first example, you’ll create a general-purpose NFS mount that uses default NFS behavior to make it difficult for a user with root privileges on the client machine to interact with the host using those client superuser privileges. You might use something like this to store files that were uploaded using a content management system or to create space for users to share project files.
First, make a shared directory:
- sudo mkdir /var/nfs/general -p
Since you’re creating it with
sudo, the directory is owned by the host’s root user:
- ls -la /var/nfs/general
Outputtotal 8 drwxr-xr-x 2 root root 4096 Feb 7 23:21 . drwxr-xr-x 3 root root 4096 Feb 7 23:21 ..
NFS will translate any root operations on the client to the
nobody:nogroup credentials as a security measure. Therefore, you need to change the directory ownership to match those credentials:
- sudo chown nobody:nogroup /var/nfs/general
You’re now ready to export this directory.
In our second example, the goal is to make user home directories stored on the host available on client servers, while allowing trusted administrators of those client servers the access they need to conveniently manage users.
To do this, you’ll export the
/home directory. Since it already exists, you don’t need to create it. You won’t change the permissions, either. If you did, it could lead to a range of issues for anyone with a home directory on the host machine.
Next, we’ll dive into the NFS configuration file to set up the sharing of these resources.
On the host machine, open the
/etc/exports file in your preferred text editor with root privileges. Here we’ll use
- sudo nano /etc/exports
The file has comments showing the general structure of each configuration line. The syntax is as follows:
You’ll need to create a line for each of the directories that you plan to share. Since our example client has an IP of
203.0.113.24, our lines will look like the following. Be sure to change the IP address to that of your client:
/var/nfs/general 203.0.113.24(rw,sync,no_subtree_check) /home 203.0.113.24(rw,sync,no_root_squash,no_subtree_check)
Here, we’re using the same configuration options for both directories with the exception of
no_root_squash. Let’s review what each of these options mean:
rw: This option gives the client computer both read and write access to the volume.
sync: This option forces NFS to write changes to disk before replying. This results in a more stable and consistent environment since the reply reflects the actual state of the remote volume. However, it also reduces the speed of file operations.
no_subtree_check: This option prevents subtree checking, which is a process where the host must check whether the file is actually still available in the exported tree for every request. This can cause many problems when a file is renamed while the client has it opened. In almost all cases, it is better to disable subtree checking.
no_root_squash: By default, NFS translates requests from a root user remotely into a non-privileged user on the server. This was intended as security feature to prevent a root account on the client from using the file system of the host as root.
no_root_squashdisables this behavior for certain shares.
When you’re finished making your changes, save and close the file. If you’re using
nano, you can do this by pressing
CTRL + X then
ENTER. Then, to make the shares available to the clients that you configured, restart the NFS server with the following command:
- sudo systemctl restart nfs-kernel-server
Before you can actually use the new shares, however, you’ll need to be sure that traffic to the shares is permitted by firewall rules.
First, check the firewall status to confirm if it’s enabled and, if so, review what’s currently permitted:
- sudo ufw status
OutputStatus: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6)
On our system, only SSH traffic is being allowed through, so we’ll need to add a rule for NFS traffic.
With many applications, you can use
sudo ufw app list and enable them by name, but
nfs is not one of those. However, because
ufw also checks
/etc/services for the port and protocol of a service, you can still add NFS by name. Best practice recommends that you enable the most restrictive rule that will still allow the traffic you want to permit, so rather than enabling traffic from anywhere, you’ll be specific.
Use the following command to open port
2049 on the host, being sure to substitute your client IP address:
- sudo ufw allow from 203.0.113.24 to any port nfs
You can verify the change by running the following:
- sudo ufw status
You should receive a list of traffic allowed from port
2049 in the output:
OutputStatus: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere 2049 ALLOW 203.0.113.24 OpenSSH (v6) ALLOW Anywhere (v6)
This confirms that UFW will only allow NFS traffic on port
2049 from your client machine.
Now that the host server is configured and serving its shares, you’ll prepare your client.
To make the remote shares available on the client, you need to mount the directories on the host that you want to share to empty directories on the client.
Note: If there are files and directories in your mount point, they will become hidden as soon as you mount the NFS share. To avoid the loss of important files, be sure that if you mount in a directory that already exists that the directory is empty.
Create two directories for your mounts. Run the following command to make the first one::
- sudo mkdir -p /nfs/general
Then run this command to create the second::
- sudo mkdir -p /nfs/home
Now that you have a location to put the remote shares and you’ve opened the firewall, you can mount the shares by using the IP address of your host server, which in this guide is
- sudo mount 203.0.113.0:/var/nfs/general /nfs/general
- sudo mount 203.0.113.0:/home /nfs/home
These commands will mount the shares from the host computer onto the client machine. You can double-check that they mounted successfully in several ways. You can check this with a
findmnt command, but
df -h provides a more readable output that illustrates how disk usage is displayed differently for the NFS shares:
- df -h
OutputFilesystem Size Used Avail Use% Mounted on udev 480M 0 480M 0% /dev tmpfs 99M 5.6M 94M 6% /run /dev/vda1 25G 1.3G 23G 6% / tmpfs 493M 0 493M 0% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 493M 0 493M 0% /sys/fs/cgroup /dev/vda15 105M 4.4M 100M 5% /boot/efi tmpfs 99M 0 99M 0% /run/user/1000 203.0.113.0:/var/nfs/general 25G 1.3G 23G 6% /nfs/general 203.0.113.0:/home 25G 1.3G 23G 6% /nfs/home
Both of the shares you mounted appear at the bottom. Because they were mounted from the same file system, they show the same disk usage. To check how much space is actually being used under each mount point, use the disk usage command
du and the path of the mount. The
-s flag provides a summary of usage rather than displaying the usage for every file. The
-h prints human-readable output:
- du -sh /nfs/home
This shows you that the contents of the entire home directory are using only 44K of the available space.
Next, test access to the shares by writing something to each of them.
First, write a test file to the
- sudo touch /nfs/general/general.test
Then, check its ownership:
- ls -l /nfs/general/general.test
Output-rw-r--r-- 1 nobody nogroup 0 Feb 7 23:53 /nfs/general/general.test
Because you mounted this volume without changing NFS’s default behavior and created the file as the client machine’s root user via the
sudo command, ownership of the file defaults to
nobody:nogroup. client superusers won’t be able to perform typical administrative actions, like changing the owner of a file or creating a new directory for a group of users, on this NFS-mounted share.
To compare the permissions of the General Purpose share with the Home Directory share, create a file in
/nfs/home the same way:
- sudo touch /nfs/home/home.test
Then review the ownership of the file:
- ls -l /nfs/home/home.test
Output-rw-r--r-- 1 root root 0 Feb 7 23:56 /nfs/home/home.test
home.test as root using the
sudo command, exactly the same way you created the
general.test file. However, in this case it is owned by root because you overrode the default behavior when you specified the
no_root_squash option on this mount. This allows your root users on the client machine to act as root and makes the administration of user accounts much more convenient. At the same time, it means you don’t have to give these users root access on the host.
You can mount the remote NFS shares automatically at boot by adding them to
/etc/fstab file on the client.
Open the following file with root privileges in your preferred text editor:
- sudo nano /etc/fstab
At the end of the file, add a line for each of your shares, like the following:
. . . 203.0.113.0:/var/nfs/general /nfs/general nfs auto,nofail,noatime,nolock,intr,tcp,actimeo=1800 0 0 203.0.113.0:/home /nfs/home nfs auto,nofail,noatime,nolock,intr,tcp,actimeo=1800 0 0
Note: You can find more information about the options specified here in the NFS
man page. You can access this by running the following command:
- man nfs
The client server will automatically mount the remote partitions at boot, although it may take a few moments to establish the connection and for the shares to be available.
If you no longer want the remote directory to be mounted on your system, you can unmount it by moving out of the share’s directory structure and unmounting.
First change into the home directory:
- cd ~
/nfs/home. Take note that the command is named
unmount as you might expect:
- sudo umount /nfs/home
- sudo umount /nfs/general
This will remove the remote shares, leaving only your local storage accessible:
- df -h
OutputFilesystem Size Used Avail Use% Mounted on udev 480M 0 480M 0% /dev tmpfs 99M 5.5M 94M 6% /run /dev/vda1 25G 1.3G 23G 6% / tmpfs 493M 0 493M 0% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 493M 0 493M 0% /sys/fs/cgroup /dev/vda15 105M 4.4M 100M 5% /boot/efi tmpfs 99M 0 99M 0% /run/user/1000
If you also want to prevent them from being remounted on the next reboot, edit
/etc/fstab and either delete the line or comment it out by placing a
# character at the beginning of the line. You can also prevent auto-mounting by removing the
auto option, which will allow you to mount it manually.
In this tutorial, you created an NFS host and illustrated some key NFS behaviors by creating two different NFS mounts, which you shared with your NFS client. If you’re seeking to implement NFS in production, it’s important to note that the protocol itself is not encrypted. In cases where you’re sharing files over a private network, this may not be a problem. In other cases, a VPN or some other type of encrypted tunnel will be necessary to protect your data. Note that this often results in a significant reduction in performance. If performance is an issue, consider using SSHFS.
Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in our Questions & Answers section, find tutorials and tools that will help you grow as a developer and scale your project or business, and subscribe to topics of interest.Sign up
Click below to sign up and get $100 of credit to try our products over 60 days!