nfs across firewalls

Mounting nfs shares across firewalls can be a challenge. Some tips below.

I started making these notes while trying to figure out how to carve out exceptions for nfs in my host based firewalls (iptables) on RHEL 6.

NFS (Network File System) was invented by (the late, great) Sun Microsystems as a way of allowing hosts to share filesystems. For example, if you had some web content over on host A’s /u01/www/html, you could share it by exporting from host A and mounting on host B as /usr/local/www. Or something like that.

The big problem with nfs is that traditionally it did not provide many security options. It does allow you to restrict which clients could connect by specifying a hostname, domain name, IP address or subnet. But that was pretty much it (well, there is “root squash”, but we won’t go into that here).

One of the many other security challenges with nfs until the advent of v4 was its use of multiple random ports for key services, specifically mountd, statd and lockd. With NFS 4 the service only needs a single, well-known port, 2049, to operate. The only problem there is that NFS 4 lacks some NFS 3 features like 64-bit filehandle support, safe async writes and better error handling.

The nfs service itself should always listen on both tcp and udp port 2049. Where using v3 or earlier the companion portmapper service will listen on tcp and udp 111.

Among others, Red Hat saw the problem of random ports in v3 and provided a configuration option to lock down its nfs service to specific ports so that those of us who use firewalls can carve out exceptions for them. There’s a chapter in the Storage Administration Guide that goes through things in some detail.

The /ec/sysconfig/nfs file comes with some “suggested” port numbers, which I try to use unless they conflict with something else on the system.

LOCKD_TCPPORT=32803
LOCKD_UDPPORT=32769
MOUNTD_PORT=892
STATD_PORT=662

Be sure to bounce rpcbind, nfslock and nfs to apply these changes. Use “rpcinfo -p” to check that the correct ports are listed (you may not see lockd or statd listed).

Taken together, this is what a set of simple rules in /etc/sysconfig/iptables would then look like:

-A INPUT -p tcp -m tcp --dport 111 -j ACCEPT
-A INPUT -p udp -m udp --dport 111 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 2049 -j ACCEPT
-A INPUT -p udp -m udp --dport 2049 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 892 -j ACCEPT
-A INPUT -p udp -m udp --dport 892 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 662 -j ACCEPT
-A INPUT -p udp -m udp --dport 662 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 32803 -j ACCEPT
-A INPUT -p udp -m udp --dport 32769 -j ACCEPT
This entry was posted in Security, System Administration on by .

About phil

My name is Phil Lembo. In my day job I’m an enterprise IT architect for a leading distribution and services company. The rest of my time I try to maintain a semi-normal family life in the suburbs of Raleigh, NC. E-mail me at philipATlembobrothersDOTcom. The opinions expressed here are entirely my own and not those of my employers, past, present or future (except where I quote others, who will need to accept responsibility for their own rants).