Writeable Linux NFS 4 shares and Mac OS X Finder

In my setup I run Arch Linux and NFSv4 server on this system. I’d like to connect to any of the shares thatare available on this laptop server and write to them from the Finder in Mac OS X.

NFS Configuration

First things first, the Arch Wiki:


Then you get NFS and its dependencies installed.

Now, NFS configuration.

I export just one folder, /srv/nfs4/seagate1TB. NFS4 has the concept of the root for the exports and that’s what /srv/nfs4/ is exactly. Access is granted exclusively to specific /29 network.


/srv/nfs4/ xxx.xxx.xxx.0/29(rw,fsid=0,no_subtree_check)
/srv/nfs4/seagate1TB xxx.xxx.xxx.0/29(rw,insecure,no_subtree_check,nohide,all_squash,anonuid=1000,anongid=1000)

I encourage to read ‘man exports’, specifically General Options, User ID Mapping and EXAMPLE sections.

After reading ‘man exports’ it was clear that the key to configuring writeable NFS share were all_squash, anonuid and anonguid options.

In plain English, when Finder copies to NFS share/export files and folders they have to be created on the NFS server. The server then has to decide who these files are going to belong to. Since the server has no way to tell what user (user ids, the UID and GID) are currently used on the client OS X machine, and also because it is, in fact, not always desired that files are created on a server with the same UID/GID of the user that runs NFS client software, there are basically two options.

First, is to use all_squash which is going to ‘anonymize’ UID/GID and instruct NFS server to create files in such a way that they belong to nobody user. Alternatively, you can set all_squash, as well as anonuid=1000 and anongid=1000 to match first non-system user on a modern Linux system.

So, I know that I store files on the disk that is exported as a specific user, so I configured my NFS export/share to create files on behalf of a client (Finder in Mac OS X) as that specific user (that’s what anonuid and anongid are for).

One more thing. Just for the sake of completeness, this is how I mount the disk and make it available for NFS export:


UUID=9d244934-d9fa-4a8e-8dd7-5c595f5518cf /mnt/seagate1TB auto defaults 0 0

# NFSv4
/mnt/seagate1TB /srv/nfs4/seagate1TB none bind 0 0

I first mount this disk device with unique identifier (UUID) in /mnt/seagate1TB, then bind it to /srv/nfs4/seagate1TB. I like to keep things multihomed sort of. Meaning, they can do many functions simultaneously, so this disk isn’t used for NFS alone and it makes sense to mount it in /mnt/seagate1TB first.

If you couldn’t care less about such things, just mount it directly to /srv/nfs4/seagate1TB to have it as a reminder that it is explicitly used for NFS.

You can also use symlinks, that are really handy. Consider the following example:

% ls -l /srv/nfs4/

disk -> /run/media/joe/disk
disk-1 -> /run/media/joe/disk-1
disk-2 -> /run/media/joe/disk-2
seagate1TB -> /run/media/joe/9d244934-d9fa-4a8e-8dd7-5c595f5518cf/

In fact, I’ve switched to using symlink because it lets me maintain NFS export handles in a consistent fashion regardless of where the actual filesystems/disks are mounted. So, I can always access them as:


while the disk are mounted elsewhere.

Firewall and NFS4

If you have a restrictive firewall things get really interesting. rpcbind daemon uses random ports to facilitate client to server connections. Fun! Honestly, I don’t know how to deal with this. Well, except restarting firewall manually or granting access to all destination ports for the host in question (this is what I’m doing on my home LAN).


To quickly unexport all shares on the server:

exportfs -au

To quickly mount/export all shares on the server:

exportfs -rav

-v will increase verbosity so that you know what’s going on.