grapes on hand
Sun Feb 12

How to Set Up an NFS Server on Ubuntu

File sharing is a crucial aspect of modern computing, allowing users to access and collaborate on shared data and resources across a network. While discussing file sharing, two protocols probably come to mind: SMB (Server Message Block) and NFS (Network File System). In this article we are going to focus only on NFS which is a widely used protocol for file sharing in a networked environment.

What is NFS?

NFS was developed by Sun Microsystems in 1984 and is now an open IETF standard. NFS (Network File System) is one of the protocols used for both directory and file sharing over the network. The NFS will allow remote hosts to mount file systems so that remote hosts can assume that the shared directory is running locally.

About NFS

Until this article was written, there had been three versions of NFS released, with the latest (NFSv4) allowing NFS to work over the internet and firewalls. The two previous versions (NFSv2 and NFSv3) allowed users to use both TCP and UDP, but the latest version (NFSv4) only allows and requires communication with TCP only. The reason is, if the server unexpectedly dies, the client will not make continuous requests to the server which will have a negative impact on network performance.

NFS Configuration

NFS works with a server-client architecture which requires special configuration on both sides.

Identifying client and server IP addresses

To check the IP address of client and server, you need to enter the command below.

ip addr show

You can find the IP address of both client and server depending on the interface you are using to connect to the network. For example, in this case we use Wi-Fi for the client, so the IP address can be found at wlan0. In this case we have 192.168.1.5/24. This server is part of my local home network and is connected to it directly through an ethernet cable, so you can find it inside eth0 with IP address of 192.168.1.2/24.

NFS Server Configuration

  • Installation

You will need an NFS service running on the server to be able to start file sharing. Use the following command to install NFS Server.

sudo apt install nfs-kernel-server

To run the services mentioned earlier, use the following command.

sudo systemctl start nfs-kernel-server
  • Creating shared directories

You can specify the directory that you will later use to share with the client. For example, we will create a shared directory with the name shared located at /shared. To create this directory or a file within it, you need root access. The following command is used to create a new directory

cd ~
sudo mkdir /shared
  • Creating test file

We can also create files to test if file sharing has been successfully created. Here we will create two files with different file ownership to see how the root and user accounts work based on the option we are going to set later.

  • Root owned files

Use the following command to make a root owned file.

	sudo nano /shared/test-root.txt

After that, we can write something. For example, we can type hello from tes- root!. Then you can exit and save with Ctrl+x and y.

  • User owned files

Here we assume the user is named ubuntu. Use the following command to create a file owned by ubuntu.

	sudo nano /shared/test-noroot.txt

Then do the same as above and type hello from test-noroot!.
Change the file ownership to ubuntu with the following command.

	sudo chown ubuntu:ubuntu /shared/test-noroot.txt
  • Editing config files

The NFSconfiguration file on the server is located in /etc/exports. This configuration is used to determine which client will be allowed to access the directory or file exported by the server. After the access is granted, the client will have the authority to perform operations on files or directories based on the permissions defined by the server.

To access it, we can use the following command.

sudo nano /etc/exports

Then we can modify the bottom part to be like this.

/shared 192.168.1.5/24(rw,root_squash,no_subtree_check)

Warning

When writing the configuration file, make sure it is written correctly as a single space different conveys a very different meaning. Compare the two lines below.

/shared 192.168.1.5/24(rw)
/shared 192.168.1.5/24 (rw)

Say that this address 192.168.1.5/24 belongs to Bob’s PC. The first line will give read and write permission to Bob when /shared is mounted. The second line will only let Bob to mount the directory as read-only as it is the default value if no options are defined, while the rest of the world have read and write access.

Let’s break things down into three different sections to see what this configuration means.

  • /shared

First, we can define the directory that we will share as above which is obvious.

  • 192.168.1.5/24

Next, we will define a client that can access the data that we share. Here, we grant a very specific permission to a single host with the Ip address of 192.168.1.5 with CIDR /24. This is interchangeably with the 255.255.255.0, so you can also type it as 192.168.1.5/255.255.255.0.

If you are on a home network, you may also want to allow all hosts within your home network to access the data. In this case, the above IP can be replaced with 192.168.1.0/24. Furthermore, you can allow access from anywhere in the world. If you wish, you can replace this part with a * symbol, yet it is highly discouraged to do so for security reasons.

In another case, you can also determine who can access it by specifying the netgroups where the client is a member with @<group-name> or simply replacing the address with the DNS. For example, binaryte.com, sales.binaryte.com or *.binaryte.com

  • (rw,root_squash,no_subtree_check)

This section describes the options available to the agencies and individuals listed in the previous section. There are many options to choose from and some of which are as follows.

ro - Exported file system will be made read-only. In this state, the clients or remote hosts have no read or write access. To grant the read and write access for clients, use rw instead..

wdelay - This option lets the server wait before saving any changes if it thinks another request is about to come in. So that the server doesn’t need to save changes frequently, reducing the number of times it needs to access the disk for separate saves. You can disable this feature with the no_wdelay option which is only available with the sync option. If async is set, it has no effect.

sync, async - It controls how the changes should be handled. async gives more performance benefits at the risk of data loss or corruption. With sync, you ensure any changes are saved to the disk in a timely manner, reducing the risk of data loss.

subtree_check - Subtree check is used to make sure the intended client can only access the particular location desired by the server by checking the directory and its subdirectories. In some cases, you may prefer no_subtree_check as it can improve reliability and performance even though it has mild security implications. It can be useful, for instance, in directories where files are renamed frequently, such as /usr and /var.

Next, we will get into the user ID mapping. To understand how the ID mapping works, see the table below.

OptionClient UIDServer UID
root_squash065534
10001000
no_root_squash00
10001000
all_squash065534
100065534
no_all_squash065534
10001000

Source: https://serverfault.com/questions/1089557/what-does-the-no-all-squash- option-do-in-nfs-exports
Credits: Siu Ching Pong -Asuka Kenji-

This table explains how the server maps client accounts.

From the table above, we can see how both root account (UID = 0) and user account (UID = 1000) behave based on the User ID Mapping option set by the server. From the table, UID = 65534 belongs to nobody which in this context can also be considered as “nfsnobody”.

As you can see, it is very unsafe to set the option to no_root_squash. The reason is, by doing so, you let the client root account have the same role as the server root account. As a result, if any remote hosts were compromised and the malicious actor was able to upload applications with virus, it would be extremely dangerous since other users might be able to accidentally execute them.

From the security standpoint, it is better to make the server set any client account as “nfsnobody” by setting it up to all_squash. However, it may not be suitable for your use case. So, in such circumstances, you may consider using root_squash or no_all_squash (default).

NFS Client Configuration

  • Installation

On the client side, installation can be done by installing nfs-common with the following command.

sudo apt install nfs-common
  • Check connection to server

To test connectivity with the server, you can use the following command.

showmount --exports 192.168.1.2

If you find an export list like the following, it means the connection has been successfully established.

Export list for 192.168.1.2:
/shared 192.168.1.5/24
  • Creating mount directory

NFS sharing directories need to be mounted before they can be used. Therefore, we must define the directory that we are going to use. Use the following command.

sudo mkdir /mnt/nfs/shared

At this point, we don’t have anything yet inside this folder, so we can start mounting it.

  • Mounting the shared folder

To mount to the directory we have made, simply use the command below.

sudo mount 192.168.1.2:/shared /mnt/nfs/shared

It is supposed to be mounted by now. To check if it is working, check our recently created directory again.

cd /mnt/nfs/shared

Now you can see that both test-root.txt and test-noroot.txt from the server are already there. You can check its content by using these commands.

cat test-root.txt
cat test-noroot.txt

Try to switch between the root and user account and modify both files with nano to see how each account works from the client side. From the server side, you may need to change the files or the folder ownership first in order to use or modify (see the above example about user owned files).

After all, the behavior will depend on the User ID Mapping we have talked about earlier, so you can choose by yourself which one suits your needs the most.

Conclusion

Setting up an NFS can be really confusing at some point. However, if you are doing file sharing in a Linux to Linux environment, NFS will likely suit you better. You may also get slightly better performance over SMB (or SAMBA in Linux). On the other hand, if you don’t want the nitty-gritty of setting up the NFS, SMB could be a better option for you.