Core Concepts — Read This First
Before setting anything up, understand what NFS is and why the architecture works the way it does. This makes debugging much easier later.
What is NFS?
Network File System (NFS) is a protocol that allows one Linux machine (the server) to share a directory over the network, and another machine (the client) to mount and use it as if it were a local disk. No file copying needed — the client reads and writes directly on the server's storage.
🖥️ NFS Server
Owns the storage. Runs nfs-kernel-server. Defines which directories are shared via /etc/exports.
💻 NFS Client
Any machine that mounts the server's shared directory. Runs nfs-common. Sees the remote directory as a local folder.
🔗 RPC
NFS uses Remote Procedure Call for communication. Default port is 2049. Must be open in the firewall.
📤 Exports
The server's /etc/exports file controls which directories are shared and who can access them.
Prerequisites
Have these ready before starting. The setup requires at least two Linux machines — one as the server and one as the client — that can reach each other over the network.
- Two Linux machines — Ubuntu/Debian recommended for both server and client
- Network connectivity — the client must be able to ping the server IP
- SSH access to both machines
- Sudo privileges on both machines
- Server IP address — you'll need this on the client side (note it down)
/etc/exports, the IP address you specify is the client's IP — not the server's. This is a common point of confusion. The server is telling NFS: "allow this client IP to connect."
NFS Server Setup
Run all commands in this section on the NFS Server machine only.
Install the NFS Server Package
Install nfs-kernel-server — the core package that runs the NFS server daemon on Linux.
sudo apt update
sudo apt install nfs-kernel-server -y
Create the Shared Directory
Create the directory that will be shared with clients. Then assign it to the nobody:nogroup user — a safe, unprivileged owner for shared NFS directories.
# Create the share directory
sudo mkdir -p /mnt/nfs_share
# Assign to nobody:nogroup (safe unprivileged owner)
sudo chown nobody:nogroup /mnt/nfs_share
# Set permissions (read/write for owner, read for others)
sudo chmod 755 /mnt/nfs_share
777 gives full read/write/execute access to every user. Use 755 or more restrictive permissions and control access through /etc/exports instead.
Configure the Exports File
The /etc/exports file defines which directories are shared and who can access them. Open it with your editor and add one of the configurations below.
sudo vim /etc/exports
Export Options — Choose One
Pick the export rule that matches your environment. Specific IP or subnet is always preferred over a wildcard.
# Allow all clients in the 192.168.1.0/24 subnet
/mnt/nfs_share 192.168.1.0/24(rw,sync,no_subtree_check)
# Allow only a specific client machine
/mnt/nfs_share 192.168.1.10(rw,sync,no_subtree_check)
rw — read and write access. sync — writes are committed to disk immediately before replying. no_subtree_check — improves reliability by disabling subtree permission checks (recommended for most setups).
/etc/exports, you are specifying which client machines are allowed to mount this share. The server's own IP does not appear here.
Apply Export Configuration and Restart
Run exportfs -a to tell the NFS server to re-read its exports file, then restart the service to apply all changes.
# Re-read and apply all exports
sudo exportfs -a
# Restart NFS server service
sudo systemctl restart nfs-kernel-server
Verify Active Exports
Confirm the server is exporting the correct directory with the correct options.
# List all active NFS exports with options
sudo exportfs -v
/mnt/nfs_share listed with the client IP and options like rw,sync,no_subtree_check. If nothing appears, double-check the exports file for syntax errors.
NFS Client Setup
Run all commands in this section on the NFS Client machine. Replace <SERVER_IP> with the actual IP address of your NFS server.
Install the NFS Client Package
Install nfs-common — this provides the tools needed to mount NFS shares on the client side.
sudo apt update
sudo apt install nfs-common -y
Create a Mount Point and Mount the Share
Create a local directory as the mount point, then mount the NFS share from the server. This mount is temporary — it will be lost on reboot. See Section 05 for permanent mounting.
# Create local mount point directory
sudo mkdir -p /mnt/nfs_client
# Mount the NFS share (temporary — lost on reboot)
sudo mount <SERVER_IP>:/mnt/nfs_share /mnt/nfs_client
Verify the Mount
Confirm the NFS share is mounted correctly by checking disk usage. You should see the NFS share listed with the server IP in the filesystem column.
# Check mounted filesystems (look for nfs entry)
df -h
Permanent Mount via fstab
To make the NFS share survive reboots automatically, add an entry to /etc/fstab on the client machine.
Edit the fstab File
sudo vim /etc/fstab
Add the following line at the bottom of the file:
<SERVER_IP>:/mnt/nfs_share /mnt/nfs_client nfs defaults,_netdev 0 0
<SERVER_IP>:/mnt/nfs_share /mnt/nfs_client nfs rw,sync,hard,intr,_netdev 0 0
Apply the fstab Configuration
# Mount all entries in fstab (tests your entry)
sudo mount -a
Mount Options Explained
_netdev so important?
Without it, the system tries to mount the NFS share before the network is ready during boot, causing the mount to fail silently or even hang the boot process.
Firewall Configuration
NFS communicates on port 2049. Open this port on the server's firewall, restricted to the client IP only — never open it to the entire internet.
Allow NFS Port from Client IP
# Allow only the client machine to reach NFS port
sudo ufw allow from <CLIENT_IP> to any port 2049
# Apply changes
sudo ufw reload
sudo ufw allow 2049 without a source IP exposes your NFS share to the entire internet. Always restrict by IP or subnet.
Allow by Subnet (Multi-Client Setup)
If you have multiple clients in the same subnet, allow the whole range instead of adding rules per-IP.
# Allow entire subnet (e.g., 192.168.1.0/24)
sudo ufw allow from 192.168.1.0/24 to any port 2049
Testing Your NFS Setup
Run these tests to confirm the share is working correctly end-to-end — both reading and writing across the network.
Write a Test File from the Client
On the client, create a test file inside the mounted directory. This file will be written to the server's disk.
# Create a test file via the NFS mount
touch /mnt/nfs_client/testfile
Confirm the File Appears on the Server
On the server, list the shared directory. You should see the testfile created by the client — confirming read/write access works over NFS.
# Confirm testfile exists on the server side
ls /mnt/nfs_share
Troubleshooting
If something isn't working, run through these diagnostic commands in order. Most NFS issues are caused by the service not running, a firewall block, or a misconfigured exports file.
Check NFS Server Status
systemctl status nfs-kernel-server
Check Network Connectivity
From the client, ping the server. If this fails, the problem is network-level — not NFS.
ping <SERVER_IP>
List Available Shares from Client
If the server is reachable but the mount fails, check which shares are actually being exported.
# Lists all NFS exports visible from this client
showmount -e <SERVER_IP>
showmount returns nothing or errors, your exports file may have a syntax error, or the firewall is blocking port 2049.
Check System Logs
# View recent system and NFS-related logs
journalctl -xe
Common Issues at a Glance
| Symptom | Likely Cause | Fix |
|---|---|---|
| Mount hangs or times out | Firewall blocking port 2049 | UFW rule missing |
| Permission denied on mount | Client IP not in /etc/exports | Check exports file |
| showmount returns nothing | Syntax error in exports | Re-run exportfs -a |
| NFS lost after reboot | No fstab entry | Add to /etc/fstab |
| Mount fails at boot | Missing _netdev option | Add _netdev to fstab |
Best Practices
- Restrict by IP or subnet — never use
*as the allowed host in/etc/exportsin production - Avoid chmod 777 — use
755or stricter permissions, and control access through the exports file - Use
hardmount option — prevents data loss if the server temporarily goes down - Always include
_netdevin fstab — ensures the mount waits for the network on boot - Firewall all NFS ports — restrict port 2049 to known client IPs only
- Use
syncin exports — ensures data is written to disk before the server replies to the client
Complete Working Example
A real-world reference using a concrete server IP (192.168.1.5) and a single trusted client (192.168.1.10).
🖥️ Server Details
💻 Client Details
/mnt/nfs_share 192.168.1.10(rw,sync,no_subtree_check)
192.168.1.5:/mnt/nfs_share /mnt/nfs_client nfs rw,sync,hard,intr,_netdev 0 0
sudo ufw allow from 192.168.1.10 to any port 2049
What You've Built
- NFS server exporting
/mnt/nfs_sharewith secure ownership and permissions - Client mounting the share at
/mnt/nfs_clientwith read/write access - Permanent mount via
/etc/fstab— survives reboots automatically - Firewall restricted to the client IP on port 2049
- Hard mount with
_netdevfor stability and boot safety - Production-ready NFS share with SPF-like access control via exports