If it seems like I'm on an acronym kick, it's not my fault. In the previous bits of my home NAS series, I've shown you all sorts of them: S.M.A.R.T., RAID, LVM, SMB...wait, what happened to SMB? Astute readers will no doubt notice that I initially intended to connect my NAS to my network using the ubiquitous Windows networking protocol, SMB, which in its UNIX implementation is referred to as Samba. So why is this post's acronym NFS?

Ultimately, it was the realization that none of the computers I use on a daily basis are running Windows anymore. If I'm using UNIX-like systems all the time, why not use a UNIX-native networked file system tool? Enter NFS, which, appropriately enough, stands for Networked Filesystem. Cue the band. (For those of you who are hoping for Windows connectivity, don't worry; I'll cover Samba in a future post. Nice thing is, you can run both if you want to.)

Now, before we get started, there are a few kind of strange things about NFS you'll want to know. First, you don't log in to an NFS share. NFS is designed on the assumption that, within a given network, one user always has the same numeric user ID. The net result of this is that if you can log on to an authorized client computer as, say, user 1000, you are effectively logged into the NFS server as user 1000 as well (but only within the shared directories). Fortunately for security's sake, it is possible to very strictly control which network hosts are authorized to access the share, which effectively means that the only way someone can get to the share is by gaining access to one of the client computers (or compromising the server itself).

One other thing worth noting up front: ultimately, my goal was to make this NFS share securely accessible over the internet. However, given the login-less nature of the system, exposing an NFS share to the open internet is really kind of stupid without additional security measures. I considered setting up a full-blown VPN for this, but just then one of my co-workers introduced me to SSH tunneling (or port forwarding). Tunneling NFS through an SSH connection allows just the extra security I need for internet access to the share, and is a good idea even if you're only accessing it locally; you just can't be too careful.

(Much of the following tutorial was adapted from this HowToForge page. All credit where credit is due, after all.)

OK, time to get the hands dirty. First things first, we need to install the NFS server components. Debian gives you two choices here (nfs-kernel-user and nfs-kernel-server); I opted for the kernel version, which is easily installed via a simple apt-get install nfs-kernel-server command. (Note: if you uninstalled the RPC services early on in this guide, this should reinstall them. That's a good thing; they're necessary for NFS.)

Next, since we're going to be tunneling this through SSH, we need to set the various NFS-related services up such that they use static (i.e., predictable) port numbers. To do this, first edit /etc/default/nfs-common; if there's a line beginning with STATDOPTS, change it to the following (if it's not already there, just add it to the end of the file):

STATDOPTS='--port 2231'

Next, edit /etc/modules.conf such that it includes the following line:

options lockd nlm_udpport=2232 nlm_tcpport=2232

And finally, edit /etc/default/nfs-kernel-server such that the line beginning with RPCMOUNTDOPTS reads:

RPCMOUNTDOPTS='-p 2233'

The next step is to create the user that will dig the tunnel each time you connect. In my setup, this is also the user who owns the files shared over the network, so it's important that you choose the user's UID carefully. For example, all of the client computers in my setup are Macs, and the default UID in OS X is 501, so the user I added here is also user 501. I named it macshare so that I know exactly what it's for. To add the user...

adduser macshare --uid 501
adduser macshare users

You'll also want to set up public key authentication for the new user to avoid having to enter in a password. I'd put the steps in here, but you can find them in detail in lots of places all over the internet, and I really don't want to rewrite any more of that earlier HowToForge article's content. So, I'll leave that step up to you for now.

Moving forward, we've still got to set up the NFS shares, or "exports". This is actually pretty easy; it's all handled through NFS's central nervous system, the /etc/exports file. It should just be comments at this point, describing the various kinds of things you can do. My own goal was to set up each of the logical volumes we created earlier as its own NFS share, so my /etc/exports ended up looking something like this:

/export/standard 127.0.0.1(rw,sync,no_subtree_check,insecure)
/export/critical 127.0.0.1(rw,sync,no_subtree_check,insecure)
/export/pictures 127.0.0.1(rw,sync,no_subtree_check,insecure)
/export/music 127.0.0.1(rw,sync,no_subtree_check,insecure)

Each line is a different share, and the various configuration fields are separated by spaces. The first field is the full path to the directory you're sharing; that's easy enough. The second field begins with the hostname or IP address of a machine that's allowed to access that directory; in this case, we used 127.0.0.1, which is the server's own localhost address. In effect, this means that the server is only exporting these directories to itself, thus ensuring that other computers can only access them via port forwarding. Anyway, immediately following the IP address is a parenthesized list of options specifying how this share can be mounted; I won't go into the details, but suffice it to say, these were the options that worked for me.

The configuration doesn't stop there! For security purposes, you'll need to take a look at your /etc/hosts.allow file to make sure that the localhost IP address above is allowed to access a few particular services. If you put the following lines at the top of your /etc/hosts.allow file (under the comments, of course), you should be good to go:

portmap: 127.0.0.1
lockd: 127.0.0.1
mountd: 127.0.0.1
rquotad: 127.0.0.1
statd: 127.0.0.1

It's also important that your client machines be able to access the sshd daemon; otherwise, your SSH tunnel won't be allowed. So, if you haven't already, make sure to add an appropriate record for sshd in /etc/hosts.allow. If your NFS configuration doesn't end up working, this is a really important place to look for errors.

Now, on to the SSH tunnel. There are actually two distinct services we'll need to tunnel, listening on two distinct ports...so we'll need two tunnels. The first service is nfs itself; to find out which port it's using, type in rpcinfo -p (on the server) and look for the nfs line(s). Mine was listening on port 2049. The second service we'll need to tunnel is mountd, which earlier we set up to listen on port 2233. Knowing these details, the ssh command to set up both tunnels looks a little like this:

ssh macshare@hostnameorip -L 48151:127.0.0.1:2049 -L 62342:127.0.0.1:2233 -f sleep 600m

As you can see, there are two -L options, one per tunnel. The first forwards port 48151 on my client computer to port 2049 on the server (which is identified by its own localhost IP, just like in the /etc/exports file on the server); that's the tunnel for NFS. The second forwards port 62342 on my client computer to port 2233 on the server; that's the tunnel for mountd. For the life of me, I don't know why the other NFS-related services aren't involved, but I'm kind of glad they weren't; I ran out of LOST numbers. (By the way, if you're concerned about using Hurley's magic lottery numbers to forward your data around your home network, be advised that the client-side port numbers are entirely arbitrary; just make them very large.)

Once you've got the tunnel running (ideally you'd set it up to run automatically), all that's left is to mount the NFS share(s) to appropriate locations in your filesystem. This process varies by operating system (even across UNIXes), so for now I'll leave that up to you. If my hands stop hurting from writing this terrifically long post, I may add the details later; for now, happy fiddling!

Categories: