Allow NFS through iptables on a RedHat system
This post describes how you can configure your RedHat Enterprise WS 4 NFS system behind a iptables firewall to be available for clients outside the firewall on a permanent basis.
Symptom
NFS relies on portmap to assign the ports on which it will listen. One side effect of this is that the ports are randomly assigned, so each time NFS is restarted the ports will change. This can make it difficult to run an NFS server behind a firewall which only allows access to specific ports on the system.
Solution
The first step is to assign a permanent port number to each of the NFS services (rquotad, mountd, statd, and lockd). While they can use any unused ports greater than 1024, it is recommended that you first consult the file /etc/services to find a valid unused port range. The following examples use the range 10000-10005.
The majority of the ports are configured through the file /etc/sysconfig/nfs. You will need to create this file if it does not exist. It should look similar to the following example:
# NFS port numbers STATD_PORT=10002 STATD_OUTGOING_PORT=10003 MOUNTD_PORT=10004 RQUOTAD_PORT=10005
The lockd service is configured differently from the others because it is compiled as a kernel module. To set the port which lockd uses, add these options in the /etc/sysconfig/nfs file:
LOCKD_UDPPORT=30001 LOCKD_TCPPORT=30001
where “30001” can be replaced with any port that is available and can be assigned for use.
After these configuration changes, you can view the port assignments with the command rpcinfo -p
# rpcinfo -p | awk -F " " '{print $3 ", " $4 ", " $5}' | sort | uniq proto, port, tcp, 111, portmapper tcp, 2049, nfs tcp, 32771, nlockmgr tcp, 800, rquotad tcp, 814, mountd udp, 111, portmapper udp, 2049, nfs udp, 32768, nlockmgr udp, 797, rquotad udp, 811, mountd
At this point, the ports will remain the same when NFS is restarted. The following is a list of ports which need to be opened on the firewall:
proto, port, tcp, 10004, mountd tcp, 10005, rquotad tcp, 111, portmapper tcp, 2049, nfs tcp, 32771, nlockmgr udp, 10004, mountd udp, 10005, rquotad udp, 111, portmapper udp, 2049, nfs udp, 32768, nlockmgr
You can now open these ports on the firewall to allow remote clients to mount a share on the server. If you are using iptables, the following commands can be used to add inbound/outbound rules to allow access to these ports.
This is an excerp of my /etc/sysconfig/iptables file. It allows NFS connections from IP address 192.168.0.10 but doesn’t restrict traffic out.
-A RH-Firewall-1-INPUT -s 192.168.0.10 -p tcp -m tcp --dport 111 -j ACCEPT -A RH-Firewall-1-INPUT -s 192.168.0.10 -p udp -m udp --dport 111 -j ACCEPT -A RH-Firewall-1-INPUT -s 192.168.0.10 -p tcp -m tcp --dport 2049 -j ACCEPT -A RH-Firewall-1-INPUT -s 192.168.0.10 -p udp -m udp --dport 2049 -j ACCEPT -A RH-Firewall-1-INPUT -s 192.168.0.10 -p tcp -m tcp --dport 10000 -j ACCEPT -A RH-Firewall-1-INPUT -s 192.168.0.10 -p udp -m udp --dport 10001 -j ACCEPT -A RH-Firewall-1-INPUT -s 192.168.0.10 -p tcp -m tcp --dport 10002:10005 -j ACCEPT -A RH-Firewall-1-INPUT -s 192.168.0.10 -p udp -m udp --dport 10002:10005 -j ACCEPT -A RH-Firewall-1-INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A RH-Firewall-1-INPUT -i eth0 -p tcp -m tcp -j LOG --log-prefix "Reject Traffic " --log-level 6 -A RH-Firewall-1-INPUT -i eth0 -p tcp -m tcp -j REJECT --reject-with icmp-port-unreachable
This post is a modified example of the solution from RedHat Knowledgebase Article ID 5928.
Everything works, except for the tag “RH-Firewall-1-INPUT”.
I got this error:
iptables: Applying firewall rules: iptables-restore: line 13 failed
Line 13 was the first line of the NFS rules.
I just changed it to “INPUT” and it worked.
My iptables now looks like this:
http://pastebin.com/FLRT8jQK
I guess this is a change between CentOS 5 and CentOS 6?
Yes, this is a change between those two versions :)