1. Introduction
A Network File System (NFS) shares files over a client-server architecture. A client can mount the file systems exposed by the server. When the server runs behind a firewall, it’s necessary to configure firewall rules to enable successful client-server communication. These rules contain network protocols and ports to allow.
In this tutorial, we’ll learn how to configure firewalld on an NFS server. Firstly, we’ll study ports and services associated with NFS in Linux. Then, we’ll add corresponding rules to firewalld. Lastly, we’ll verify that the NFS client can connect to the server and work properly.
All scripts in this tutorial were run in Bash as root user on CentOS 7 systems after installing nfs-utils package. These scripts are compatible with major distributions and shells.
2. NFS Ports and Services
The NFS protocol works on port 2049 by default. Additionally, clients and servers communicate through Remote Procedure Calls (RPC). Hence, many RPC services are associated with the Linux implementation nfs, namely:
- nfsd: the NFS server process; works with the nfsd kernel module for coordinating NFS server hostname, port, transport layer protocols, logging, supported NFS versions, and kernel threads
- rpcbind: runs on the well-known port 111 to provide a universal address containing the hostname and port of an RPC program, e.g., nfs, to an RPC client
- mountd: the NFS mount daemon; chooses a random port but is configured for port 20048 in some distributions
- lockd: Network Lock Manager (NLM) protocol implementation for file locking over NFS
- statd: Network Status Monitor (NSM) protocol implementation for notifying peers after the system reboots, i.e., the client informs the server after reboot and vice versa
Both lockd and statd run on NFS clients and servers to support file locking with crash and recovery functions. By default, they pick random, distinct ports for TCP and UDP connections.
Other services involved are idmapd for mapping NFSv4 names, like ‘user@domain’, with local server UIDs and GIDs and rquotad for returning the quota information of an NFS-shared filesystem’s local user.
2.1. NFSv4 vs NFSv3
The latest protocol of NFS is v4. It has minor versions: v4.2, v4.1, and v4.0. However, NFS Linux implementations generally support NFSv3 for backward compatibility.
NFSv3 requires supplementary services like rpcbind, mountd, lockd, and statd. Furthermore, the v3 protocol doesn’t mandate TCP implementation.
On the other hand, NFSv4 doesn’t depend on rpcbind, lockd, and statd as it has these functionalities built in. Only mountd is still used for exporting file shares, but not in the client-server connection. Hence, these services needn’t be exposed through a firewall. Moreover, NFSv4 has features like better security, reliability, enhanced client caching, and internationalization.
3. Configuring firewalld on the NFS Server
firewalld is a stateful, zone-based firewall that supports defining rules for specific services and applications. We can utilize its predefined list of services or configure new ones. A service has parameters, such as protocols and ports, which we can allow: e.g., the mountd service configuration allows TCP and UDP on port 20048.
Nine preconfigured firewall zones are already present: drop, block, public, dmz, internal, external, home, work, and trusted. If the NFS client and server communicate over an internal network, firewalld might allow traffic between them already. Conversely, NFS servers running on the cloud might require additional configuration.
firewalld is the default firewall management tool in RHEL 7, CentOS 7, Fedora 18, SUSE 15, and OpenSUSE 15. For other distributions, we can install it manually and turn off any other firewall to avoid conflicts.
3.1. Initial firewalld Setup
We can manage firewalld using the firewall-cmd command. Let’s create a zone for our NFS clients by passing ‘nfs-clients‘ to the –new-zone option. Moreover, we’ll also provide the –permanent option at the beginning to make these changes persistent across firewalld restarts:
# firewall-cmd --permanent --new-zone=nfs-clients
success
A success message appears to indicate a successful operation. Alternatively, we can configure an existing zone for our NFS clients.
For this tutorial, our NFS server has the public IP 34.10.65.56, while the client has 34.10.100.200. Let’s add our client IP address as a source to our zone using the –add-source and the –zone options:
# firewall-cmd --permanent --zone=nfs-clients --add-source=34.10.100.200
success
After specifying permanent changes, firewalld needs to be reloaded using the –reload option to apply the changes immediately:
# firewall-cmd --reload
success
We can now check the details of our zone with the –list-all option:
# firewall-cmd --zone=nfs-clients --list-all
nfs-clients (active)
target: default
icmp-block-inversion: no
interfaces:
sources: 34.10.100.200
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
We can see the zone details above. The target can be default, ACCEPT, REJECT, or DROP. A default target is analogous to REJECT, except it inherently allows ICMP packets. The sources include our client’s IP address.
3.2. Allowing nfs
To allow a particular service, firewall-cmd has an –add-service option. Let’s pass nfs to this option along with our zone. Then, we’ll reload firewalld. Lastly, we’ll inspect the zone details:
# firewall-cmd --permanent --zone=nfs-clients --add-service=nfs
success
# firewall-cmd --reload
success
# firewall-cmd --zone=nfs-clients --list-all
nfs-clients (active)
target: default
icmp-block-inversion: no
interfaces:
sources: 34.10.100.200
services: nfs
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
Hereafter, NFSv4 clients can work with this NFS server. We’ve exposed a directory /opt/nfsserver/shared on the server with read-write permissions for testing. Let’s mount this path at /mnt/shared by passing the nfsvers=4 option on the client:
# mount -t nfs -o nfsvers=4 34.10.65.56:/opt/nfsserver/shared /mnt/shared
Let’s check the connection by trying to modify a shared file:
# touch /mnt/shared/baeldung.txt
Although this works, NFSv3 clients can’t connect yet. Let’s try the mount command with nfsvers=3:
# umount /mnt/shared
# mount -t nfs -o nfsvers=3 34.10.65.56:/opt/nfsserver/shared /mnt/shared
This command hangs up and doesn’t run. We can also try using showmount with the –exports (-e) option on the client:
# showmount -e 34.10.65.56
clnt_create: RPC: Port mapper failure - Unable to receive: errno 113 (No route to host)
We can see this error because showmount invokes mountd on the server, but mountd isn’t allowed by firewalld yet.
3.3. Allowing Supplementary Services
For supporting NFSv3 clients, we’ll allow other services through firewalld on the server.
Let’s add or edit the following lines in /etc/nfs.conf to set fixed ports for mountd, lockd, and statd:
[mountd]
port=20048
[lockd]
port=32767
udp-port=32767
[statd]
port=32765
Now, we’ll add rpcbind, which is listed as ‘rpc-bind‘ in firewalld, and mountd services along with these ports to transit firewalld:
# firewall-cmd --permanent --zone=nfs-clients --add-service=rpc-bind --add-service=mountd
success
# firewall-cmd --permanent --zone=nfs-clients --add-port=32767/tcp --add-port=32767/udp --add-port=32765/tcp --add-port=32765/udp
success
Let’s reload firewalld and inspect our zone:
# firewall-cmd --reload
success
# firewall-cmd --zone=nfs-clients --list-all
nfs-clients (active)
target: default
icmp-block-inversion: no
interfaces:
sources: 34.10.100.200
services: mountd nfs rpc-bind
ports: 32767/tcp 32767/udp 32765/tcp 32765/udp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
Finally, we’ll restart statd and nfsd daemons on the server:
# systemctl restart rpc-statd.service
# systemctl restart nfs-server.service
Let’s verify the connection using mount and showmount on the client:
# mount -t nfs -o nfsvers=3 34.10.65.56:/opt/nfsserver/shared /mnt/shared
# touch /mnt/shared/baeldung.txt
# showmount -e 34.10.65.56
Export list for 34.10.65.56:
/opt/nfsserver/shared 34.10.100.200
Thus, NFSv3 clients can now function normally.
4. Conclusion
In this article, we learned how to configure firewalld on an NFS server.
Initially, we examined ports and services associated with nfs, specifically nfsd, rpcbind, mountd, lockd, and statd. We also saw the upgrades in NFSv4 compared to NFSv3. Then, we configured firewalld on the server by setting fixed ports for some services and adding the required rules. Lastly, we tested the connection from our client using mount and showmount commands.