Ubuntu Server 18.04 – Setting up NFS shares

How to Configure Network Static IP Address on Ubuntu 19.10

A Network File System (NFS) is a great method of sharing files from a Linux or UNIX server to a Linux or UNIX server. As I mentioned earlier in the chapter, Windows systems can access NFS shares as well, but there may be an additional licensing penalty if you need to upgrade to a different release. NFS is preferred in a Linux or UNIX environment though, since it fully supports Linux- and UNIX-style permissions. As you can see from our earlier dive into Samba, we essentially forced all shares to be treated as being accessed by a particular user, which was messy, but was the easiest example of setting up a Samba server. Samba can certainly support per-user access restrictions and benefit greatly from a centralized directory server, though that would basically be a tutorial of its own! NFS is a bit more involved to set up, but in the long run, I think it’s easier and integrates better.

Earlier, we set up a parent directory on our filesystem to house our Samba shares, and we should do the same thing with NFS. While it wasn’t mandatory to have a special parent directory with Samba (I had you do that in order to be neat, but you weren’t required to), NFS really does want its own directory to house all of its shares. It’s not required with NFS either, but there’s an added benefit in doing so, which I’ll go over before the end of this section. In my case, I’ll use /exports as an example, so you should make sure that directory exists:

sudo mkdir /exports 

Next, let’s install the required NFS packages on our server. The following command will install NFS and its dependencies:

sudo apt install nfs-kernel-server 

Once you install the nfs-kernel-server package, the nfs-kernel-server daemon will start up automatically. It will also create a default /etc/exports file (which is the main file that NFS reads its share information from), but it doesn’t contain any useful settings, just some commented lines. Let’s back up the /etc/exports file, since we’ll be creating our own:

sudo mv /etc/exports /etc/exports.orig 

To set up NFS, let’s first create some directories that we will share to other users. Each share in NFS is known as an Export. I’ll use the following directories as examples, but you can export any directory you like:

/exports/backup 
/exports/documents 
/exports/public 

In the /etc/exports file (which we’re creating fresh), I’ll insert the following four lines:

/exports *(ro,fsid=0,no_subtree_check) 
/exports/backup 192.168.1.0/255.255.255.0(rw,no_subtree_check) 
/exports/documents 192.168.1.0/255.255.255.0(ro,no_subtree_check) 
/exports/public 192.168.1.0/255.255.255.0(rw,no_subtree_check) 

The first line is Export Root, which I’ll go over a bit later. The next three lines are individual shares or exports. The backup, documents, and public directories are being shared from the /exports parent directory. Each of these lines is not only specifying which directory is being shared with each export, but also which network is able to access them. In this case, after the directory is called out in a line, we’re also setting which network is able to access them (192.168.1.0/255.255.255.0 in our case). This means that if you’re connecting from a different network, your access will be denied. Each connecting machine must be a member of the 192.168.1.0/24 network in order to proceed (so make sure you change this to match your IP scheme). Finally, we include some options for each export, for example, rw,no_subtree_check.

As far as what these options do, the first (rw) is rather self-explanatory. We can set here whether or not other nodes will be able to make changes to data within the export. In the examples I gave, the documents export is read-only (ro), while the others allow read and write.

The next option in each example is no_subtree_check. This option is known to increase reliability and is mainly implied by default. However, not including it may make NFS complain when it restarts, but nothing that will actually stop it from working. Particularly, this option disables what is known as subtree checking, which has had some stability issues in the past. Normally, when a directory is exported, NFS might scan parent directories as well, which is sometimes problematic, and can cause issues when it comes to open file handles.

There are several other options that can be included in an export, and you can read more about them by checking the man page for export:

man export

One option you’ll see quite often in the wild is no_root_squash. Normally, the root user on one system is mapped to nobody on the other for security reasons. In most cases, one system having root access to another is a bad idea. The no_root_squash option disables this, and it allows the root user on one end to be treated as the root user on the other. I can’t think of a reason, personally, where this would be useful (or even recommended), but I have seen this option quite often in the wild, so I figured I would bring it up. Again, check the man pages for export for more information on additional options you can pass to your exports.

Next, we have one more file to edit before we can actually seal the deal on our NFS setup. The /etc/idmapd.conf file is necessary for mapping permissions on one node to another. In Chapter 2, Managing Users, we talked about the fact that each user has an ID (UID) assigned to them. The problem, though, is that from one system to another, a user will not typically have the same UID. For example, user jdoe may be UID 1001 on server A, but 1007 on server B. When it comes to NFS, this greatly confuses the situation, because UIDs are used in order to reference permissions. Mapping IDs with idmapd allows this to stay consistent and handles translating each user properly, though it must be configured correctly and consistently on each node. Basically, as long as you use the same domain name on each server and client and configure the /etc/idmapd.conf file properly on each, you should be fine.

To configure this, open /etc/idmapd.conf in your text editor. Look for an option that is similar to the following:

# sudo Domain = localdomain 

First, remove the # symbol from that line to uncomment it. Then, change the domain to match the one used within the rest of your network. You can leave this as it is as long as it’s the same on each node, but if you recall from Chapter 7, Setting Up Network Services, we used a sample domain of local.lan in our DHCP configuration, so it’s best to make sure you use the same domain name everywhere—even the domain provided by DHCP. Basically, just be as consistent as you can and you’ll have a much easier time overall. You’ll also want to edit the /etc/idmapd.conf file on each node that will access your file server, to ensure they are configured the same as well.

With our /etc/exports and /etc/idmapd.conf files in place, and assuming you’ve already created the exported directories on your filesystem, we should be all set to restart NFS to activate our configuration:

sudo systemctl restart nfs-kernel-server 

After restarting NFS, you should check the daemon’s output via systemctl to ensure that there are no errors:

systemctl status -l nfs-kernel-server 

As long as there are no errors, our NFS server should be working. Now, we just need to learn how to mount these shares on another system. Unlike Samba, using a Linux file manager and browsing the network will not show NFS exports; we’ll need to mount them manually. Client machines, assuming they are Debian based (Ubuntu fits this description) will need the nfs-common package installed in order to access these exports:

sudo apt install nfs-common 

With the client installed, we can now use the mount command to mount NFS exports on a client. For example, with regards to our documents export, we can use the following variation of the mount command to do the trick:

sudo mount myserver:/documents /mnt/documents 

Replace myserver with either your server’s hostname or its IP address. From this point forward, you should be able to access the contents of the documents export on your file server. Notice, however, that the exported directory on the server was /exports/documents, but we only asked for /documents instead of the full path with the example mount command. The reason this works is because we identified an export root of /exports. To save you from flipping back, here’s the first line from the /etc/exports file, where we identified our export root:

/exports *(ro,fsid=0,no_subtree_check) 

With the export root, we basically set the base directory for our NFS exports. We set it as read-only (ro), because we don’t want anyone making any changes to the /exports directory itself. Other directories within /exports have their own permissions and will thus override the ro setting on a per-export basis, so there’s no real reason to set our export root as anything other than read-only. With our export root set, we don’t have to call out the entire path of the export when we mount it; we only need the directory name. This is why we can mount an NFS export from myserver:/documents instead of having to type the entire path. While this does save us a bit of typing, it’s also useful because from the user’s perspective, they aren’t required to know anything about the underlying filesystem on the server. There’s simply no value for the user to have to memorize the fact that the server is sharing a documents directory from /exports; all they’re interested in is getting to their data. Another benefit is if we ever need to move our export root to a different directory (during a maintenance period), our users won’t have to change their configuration to reference the new place; they’ll only need to unmount and remount the exports.

So, at this point, you’ll have three directories being exported from your file server, and you can always add others as you go. However, anytime you add a new export, they won’t be automatically added and read by NFS. You can restart NFS to activate new exports, but that’s not really a good idea while users may be connected to them, since that will disrupt their access. Thankfully, the following command will cause NFS to reread the /etc/exports file without disrupting existing connections. This will allow you to activate new exports immediately without having to wait for users to finish what they’re working on:

sudo exportfs -a 

With this section out of the way, you should be able to export a directory on your Ubuntu Server, and then mount that export on another Linux machine. Feel free to practice creating and mounting exports until you get the hang of it. In addition, you should familiarize yourself with a few additional options and settings that are allowable in the /etc/exports file, after consulting with the man page on export. When you’ve had more NFS practice than you can tolerate, we’ll move on to a few ways in which you can copy files from one node to another without needing to set up an intermediary service or daemon.

Comments are closed.