
Setting up an NFS server on Linux is an essential step for creating efficient and reliable file-sharing solutions in any networked environment. Whether for personal projects or enterprise use, an NFS server on Linux provides the flexibility and performance needed for seamless data access. In this guide, we will cover everything from the initial setup to best practices, helping you achieve secure and optimized configurations for your system.
Introduction
Network File System (NFS) is a robust protocol that allows seamless file sharing across multiple Linux systems, making it an essential tool for enterprises and home networks alike. By setting up an NFS server on Linux, users can centralize storage, simplify file management, and provide seamless access to shared data across multiple clients. Unlike other network-based file-sharing solutions, NFS offers high performance with minimal overhead, integrating deeply with Linux’s native file permissions and authentication mechanisms.
In this guide, we will walk you through the entire process of setting up an NFS server on Linux, from installing the necessary packages to configuring exports and managing client access. We’ll cover key considerations such as optimizing performance, ensuring security, and troubleshooting common issues. Whether you’re a system administrator looking to deploy NFS in a production environment or a home user setting up a simple file-sharing solution, this guide provides the necessary insights.
Prerequisites
You can install and configure an NFS server on any Linux machine for file sharing. However, setting it up solely to share files between two computers is impractical. NFS is primarily intended to be installed on a server and used as centralized storage for all computers on the network. For this article, I will illustrate the process using a machine equipped with five 3TB disks and running a Debian operating system. Please feel free to check out my articles on how to install and initially configure the Debian operating system on any computer:

Debian 11 Server – Minimal Installation Guide
Follow this guide for a Debian 11 Server minimal installation, providing a solid foundation for any server setup or project you want to build.

Debian 11 Server – Initial Customization Guide
Discover introductory steps to streamline performance, security, and administration in our Debian Server Initial Customization guide.
You can also check my articles on how to configure the RAID array(s) and file systems for your multiple disks:

RAID-10 Configuration on Linux – Everything You Need to Know
RAID-10 configuration on Linux made simple! Discover how to set up, monitor, and recover your RAID-10 array for unmatched performance and data protection.

ZFS RAID-Z on Linux – Guide to Data Protection and Performance
Learn to set up and configure ZFS RAID-Z on Linux with this step-by-step guide for reliable storage setup on your system.
Once you have your machine ready, I will show you how to install and configure the NFS server on Linux in the following sections of this guide.
NFS Server on Linux – NFS Server Setup
In this section, I will explain how to configure the server side of this setup. I have a machine running Debian with a ZFS RAID-Z1 configured on my disk array, which consists of five 3TB WD Red HDDs. Additionally, I have a 10 Gigabit network setup throughout my premises. I needed to decide whether to use NFSv3 or NFSv4, so let’s take a brief look at the differences between the two.
| Feature | NFSv3 | NFSv4 |
|---|---|---|
| Protocol Type | Uses both TCP & UDP | Uses only TCP (more reliable) |
| Port Usage | Requires portmapper (rpcbind) and dynamic ports | Uses only port 2049 (simpler firewall rules) |
| Security | No built-in authentication | Supports Kerberos (krb5), encryption, and ACLs |
| Locking Mechanism | Uses separate nlockmgr daemon (not atomic) | Built-in stateful file locking (atomic) |
| Performance | Faster in simple LAN environments | Better over WAN/VPN, handles latency better |
| Reliability | Stateless (no server-side session tracking) | Stateful (better consistency, but requires tracking) |
| Permissions | Uses traditional UNIX permissions | Supports extended ACLs |
| File Access Control | Requires UID/GID matching on client & server | Uses UID mapping for better cross-platform support |
| Symbolic Links & Hard Links | Fully supported | Fully supported |
| Firewall Configuration | Complex (multiple dynamic ports required) | Simple (only TCP 2049 needed) |
| Exporting Directories | Allows per-directory exports | Requires one root directory (fsid=0) |
| Performance Over High-Latency Networks | Struggles over WAN due to UDP usage | Better for WAN, VPN, and cloud setups |
The table above may appear complex at first, but there’s no need to worry; configuring and maintaining NFS is relatively straightforward. Since I have only several clients on the network, and I only intend to use the NFS server machine as a file storage, NFSv3 will perfectly meet my requirements. I don’t require the advanced features and options offered by NFSv4. However, for reference, let’s compare some essential advantages and disadvantages of NFSv3 and NFSv4:
-
NFSv3 – Pros & Cons
-
NFSv4 – Pros & Cons
✅ PROS:
✔️ Faster in low-latency LAN environments
✔️ Simpler setup (no state tracking)
✔️ Easier to debug (less strict authentication)
✔️ Supports both TCP & UDP (suitable for older networks)
❌ CONS:
✖️ No built-in authentication or encryption (less secure)
✖️ Requires rpcbind (extra security risks)
✖️ Complex firewall rules (dynamic ports like mountd, nlockmgr, etc.)
✖️ Stateless locking (less reliable for concurrent access)
✅ PROS:
✔️ More Secure (Kerberos authentication, encryption, ACLs)
✔️ Simpler Firewall Rules (only uses TCP 2049)
✔️ No rpcbind required (easier setup & less security risk)
✔️ Better Performance over WAN & VPN
✔️ Stateful File Locking (more reliable for concurrent access)
✔️ Supports IPv6 Fully
❌ CONS:
✖️ Requires more setup for security features (Kerberos, ACLs)
✖️ Slightly higher overhead in LAN environments
✖️ Exports must be under a single root (fsid=0)
In my opinion, if you don’t have a massive network (lots of devices) and you don’t intend to use NFS to host stuff like databases and cloud applications, NFSv3 will suit you just fine.
Required Packages – NFS Server Installation
The only package to install an NFS server on Linux, and here I am talking about Debian and Debian-based distributions specifically, is nfs-kernel-server. To do so, execute the following in the console:
apt install -y nfs-kernel-serverIt will automatically install nfs-common and rpcbind as additional packages. To enable and activate those services by executing the following in the console:
systemctl enable --now nfs-server rpcbind
systemctl start nfs-server rpcbindNow both nfs-server and rpcbind services should be active:
systemctl status nfs-server.service rpcbind.service
...
● nfs-server.service - NFS server and services
Loaded: loaded (/lib/systemd/system/nfs-server.service; enabled; preset: enabled)
Active: active (exited) since Wed 2025-02-12 10:39:25 CET; 1min 18s ago
Main PID: 4252 (code=exited, status=0/SUCCESS)
CPU: 4ms
Feb 12 10:39:24 debian-bookworm-test systemd[1]: Starting nfs-server.service - NFS server and services...
Feb 12 10:39:24 debian-bookworm-test exportfs[4251]: exportfs: can't open /etc/exports for reading
Feb 12 10:39:25 debian-bookworm-test systemd[1]: Finished nfs-server.service - NFS server and services.
● rpcbind.service - RPC bind portmap service
Loaded: loaded (/lib/systemd/system/rpcbind.service; enabled; preset: enabled)
Active: active (running) since Wed 2025-02-12 10:39:22 CET; 1min 21s ago
TriggeredBy: ● rpcbind.socket
Docs: man:rpcbind(8)
Main PID: 3800 (rpcbind)
Tasks: 1 (limit: 4638)
Memory: 600.0K
CPU: 6ms
CGroup: /system.slice/rpcbind.service
└─3800 /sbin/rpcbind -f -w
Feb 12 10:39:22 debian-bookworm-test systemd[1]: Starting rpcbind.service - RPC bind portmap service...
Feb 12 10:39:22 debian-bookworm-test systemd[1]: Started rpcbind.service - RPC bind portmap service.With services active and running, let’s check out the configuration files next.
Initial Configuration
We need to examine the configuration options in the /etc/default directory, specifically in two files: nfs-common and nfs-kernel-server. I believed these were the correct files to modify. However, when I attempted to change the options in these files and restarted the necessary services to apply the changes, nothing happened. As has often been the case with Linux, I found myself embarking on a little “witch hunt” to figure out the issue.
I started by reviewing similar guides on installing an NFS server on Linux. I found that information regarding changing the configuration options I mentioned earlier was limited and almost nonexistent, which was quite disappointing. So, I continued my search through various mailing lists, which ultimately led me to the source of the issue. I examined commits related to the nfs-utils source package and discovered one that clarified why the changes in the previously mentioned files were ineffective. You can examine it here.
To summarize, I ignored files in the /etc/default directory and performed all the required changes in the main configuration file /etc/nfs.conf. More specifically, I opened a local “snippet” file at /etc/nfs.cond.d/local.conf, and I pasted in the following content:
[lockd]
port=32768
udp-port=32768
[mountd]
udp=no
port=32767
[nfsd]
udp=n
tcp=y
vers2=n
vers3=y
vers4=n
vers4.0=n
vers4.1=n
vers4.2=n
[statd]
port=32765
outgoing-port=32766To apply the changes, several services must be restarted (or just simply reboot the machine):
systemctl restart rpcbind.service rpc-statd.service nfs-mountd.service nfs-server.serviceWhen “allocating” ports to services, Linux operating systems check the /etc/services file to see if a specific port has been assigned to a service. If you open that file, you will see that RPC/portmapper and NFS have their respective ports assigned (111 and 2049). You can add “local ports” assignments specific to your system at the bottom of the file. To satisfy our scenario, you can add the following ports:
# Local services
#
# RPC/NFS ports
# Listing here does not mean they will bind to these ports.
#
rpc.statd-bc 32765/tcp # RPC statd broadcast
rpc.statd-bc 32765/udp # RPC statd broadcast
rpc.statd 32766/tcp # RPC statd listen
rpc.statd 32766/udp # RPC statd listen
rpc.mountd 32767/tcp # RPC mountd
rpc.mountd 32767/udp # RPC mountd
rpc.lockd 32768/tcp # RPC lockd/nlockmgr
rpc.lockd 32768/udp # RPC lockd/nlockmgrSecurity and Firewall
If you are running NFS on your home server and storing non-essential data, security may not be an issue. But still, I am going to show you how to secure and harden your NFS server. As a prerequisite, I will use 192.168.100.0/24 as a local network subnet (please change that to your local network subnet). If you have no other services besides NFS on your machine, the following set of firewall rules should do the trick:
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp -s 192.168.100.0/24 --dport 111 -m state --state NEW -j ACCEPT
iptables -A INPUT -p tcp -s 192.168.100.0/24 --dport 2049 -m state --state NEW -j ACCEPT
iptables -A INPUT -p tcp -s 192.168.100.0/24 --dport 32765 -m state --state NEW -j ACCEPT
iptables -A INPUT -p tcp -s 192.168.100.0/24 --dport 32767 -m state --state NEW -j ACCEPT
iptables -A INPUT -p tcp -s 192.168.100.0/24 --dport 32768 -m state --state NEW -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -s 192.168.100.0/24 -j ACCEPTThe rules above will allow access to your NFS server from all computers on the 192.168.100.0/24 network. As an option (such as in case you have more subnets), you can also block everything else from accessing the NFS:
iptables -A INPUT -p tcp --dport 111 -j DROP
iptables -A INPUT -p tcp --dport 2049 -j DROP
iptables -A INPUT -p tcp --dport 32765 -j DROP
iptables -A INPUT -p tcp --dport 32767 -j DROP
iptables -A INPUT -p tcp --dport 32768 -j DROPIf you have followed my guides from the prerequisites above, you should already have some general, sane rules in your firewall. If so, you must only set the “allow” rules in a dedicated chain. To do so, first, create a new chain:
iptables -N NFS-SERVICESNow, you must define a “jump” from the INPUT chain to the NFS-SERVICES chain:
iptables -I INPUT -m tcp -p tcp -s 192.168.100.0/24 -m comment --comment "NFS Specific Rules" -j NFS-SERVICESSince the local subnet (192.168.100.0/24) is already defined in the jump rule, you don’t have to define it again in NFS-specific rules:
iptables -A NFS-SERVICES -p tcp -m tcp --dport 111 -m state --state NEW -m comment --comment "RPC Bind" -j ACCEPT
iptables -A NFS-SERVICES -p tcp -m tcp --dport 2049 -m state --state NEW -m comment --comment "NFS Daemon" -j ACCEPT
iptables -A NFS-SERVICES -p tcp -m tcp --dport 32765 -m state --state NEW -m comment --comment "RPC Statd" -j ACCEPT
iptables -A NFS-SERVICES -p tcp -m tcp --dport 32767 -m state --state NEW -m comment --comment "RPC Mountd" -j ACCEPT
iptables -A NFS-SERVICES -p tcp -m tcp --dport 32768 -m state --state NEW -m comment --comment "RPC Lockd" -j ACCEPTThere is also no need to define “DROP” rules as the chain that drops “everything else” is also in place. You can examine it by executing the following in the console:
iptables -L REJECT-ALL -v -n
...
Chain REJECT-ALL (1 references)
pkts bytes target prot opt in out source destination
0 0 REJECT 6 -- * * 0.0.0.0/0 0.0.0.0/0 reject-with tcp-reset
0 0 REJECT 17 -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
0 0 DROP 1 -- * * 0.0.0.0/0 0.0.0.0/0In both cases, you must save the firewall rules by executing the following in the console:
iptables-save > /etc/iptables/rules.v4The set of rules above should “satisfy all” for small networks. A more fine-grained approach may be required for larger networks.
NFS Server on Linux – NFS Exports
With NFSv3, you can export any directory on your server, although I do not recommend doing this indiscriminately. In my example, I will export only one directory: my entire ZFS storage array. First, I created the directory /mnt/zfs-data/storage, which I intend to export. After that, I defined the export by opening the /etc/exports file and adding the following line at the bottom:
/mnt/zfs-data/storage 172.17.0.0/24(rw,sync,no_subtree_check)Let’s examine the options a bit:
- rw: Allows clients to read & write.
- sync: Ensures data is written to disk immediately (safer).
- no_subtree_check: Improves performance and reliability.
For a more fine-grained approach, you could do something like in the following example:
/mnt/zfs-data/storage/backup/computer01 172.17.0.10/32(rw,sync,no_subtree_check)
/mnt/zfs-data/storage/backup/computer02 172.17.0.11/32(rw,sync,no_subtree_check)
/mnt/zfs-data/storage/movies 172.17.0.0/24(rw,sync,no_subtree_check)
/mnt/zfs-data/storage/tv 172.17.0.0/24(rw,sync,no_subtree_check)
/mnt/zfs-data/storage/music 172.17.0.0/24(rw,sync,no_subtree_check)
/mnt/zfs-data/storage/docs 172.17.0.0/24(rw,sync,no_subtree_check)In the example above, a dedicated backup export is created for each individual computer on the network, while the other exports can be accessed by any device on the network. Regardless of the approach you choose, be sure to apply the changes by executing the following commands in the console:
exportfs -a
systemctl restart nfs-serverNon-Linux Clients Options
In my scenario, I want to connect my Windows 11 computer to my NFS server and access media files from my Android TV using VLC Player. This requires additional configuration on the NFS server to ensure compatibility.
Firstly, please don’t take this for granted, but I’m pretty sure that Windows still only supports NFSv3. Additionally, Windows and Android handle permissions differently, so a minor adjustment to the NFS configuration is needed.
/mnt/zfs-data/storage 172.17.0.0/24(rw,sync,no_subtree_check,all_squash)As you may have noticed, I have added the all_squash option. This option will treat all non-Linux clients as anonymous users, resolving any compatibility issues between the NFS server on Linux and non-Linux clients. To apply the change, please execute the following in the console:
exportfs -raWith all this in place, you can start connecting your clients. Let’s observe how.
Connecting Clients
To mount an NFS share on a Linux client (e.g., your desktop computer, or another server), you must install the nfs-common package. To do so, please execute the following in the console:
sudo apt install -y nfs-commonOnce installed, you must modify /etc/fstab and define a persistent NFS mount. To do so, open the file and add the following at the bottom:
# NFS Share /mnt/zfs-data/storage
172.17.0.2:/mnt/zfs-data/storage /mnt/storage nfs rw,noatime,hard,intr,retrans=2,timeo=600,vers=3,actimeo=2 1 0Save and close the file. To “activate” the share, you can either restart your computer, or execute the following command:
sudo mount /mnt/storageFrom here, you can symlink NFS share to wherever you need, for instance, in your user home directory:
cd
ln -sf /mnt/storage StorageOptional – Windows 11
You must enable NFS Client for Windows to connect NFS share on Windows. To do so, open a PowerShell (Admin) and execute the following:
dism /online /enable-feature /featurename:ServicesForNFS-ClientOnlyAt this point, you will need to restart your computer. Once it is back, start PowerShell again and execute the following:
mount -o anon,mtype=hard,tcp 172.17.0.2:/mnt/zfs-data/storage Z:To make it persistent, please execute the following in the PowerShell also:
net use Z: \\172.17.0.2\mnt\zfs-data\storage /persistent:yesOptional – VLC Player on Android TV
Connecting to your NFS share from VLC Player on Android TV is pretty simple. Start the VLC Player application and go to “Browsing” → Select “NFS.” Once there, enter the following details:
- Server Address: nfs://172.17.0.2/mnt/zfs-data/storage
- No authentication required (due to
all_squashin server settings)
Since most Android apps (like VLC) rely on NFSv3 over UDP by default, and I enforced TCP above in this guide, an additional step of allowing the UDP protocol may be required in the main NFS server configuration file. It is up to you to allow this, and if you do, please remember to allow UDP connections in the firewall as well.
Conclusion
Setting up an NFS server on Linux provides a powerful and efficient way to share files across multiple systems, including Linux, Windows, and even Android-based devices. While NFSv4 offers security and performance improvements, NFSv3 remains widely used for its simplicity and compatibility. Key considerations include UID/GID mapping, firewall rules, and ensuring proper permission settings to maintain both accessibility and security.
For a smooth cross-platform experience, carefully configuring export options such as all_squash, and optionally anonuid, and anongid helps maintain consistency, especially when connecting from non-Linux clients. Additionally, limiting unnecessary services, enforcing iptables rules, and securing access through authentication mechanisms like Kerberos can significantly enhance the security of your NFS setup.
By following best practices for configuration, security, and user management, you can ensure a stable, secure, and high-performance NFS environment tailored to your needs. Whether for personal media storage or enterprise file sharing, a well-configured NFS server on Linux remains a reliable and scalable solution.
Nice to know I wasn’t the only one who read the Debian documentation, then realized it wasn’t working.
Thank you for your comment; I appreciate it. And I am glad there are still people out there who read manuals.