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