NFS Storage Configuration: Complete Server and Client Setup Guide
Network File System (NFS) is one of the most widely used protocols for sharing files across Linux and Unix systems in networked environments. Whether you're building a centralized storage solution, sharing application data across multiple servers, or creating a home lab environment, understanding NFS configuration is essential for modern infrastructure management.
This comprehensive guide covers complete NFS setup—from basic server configuration to advanced security hardening—enabling you to implement robust, performant network storage solutions.
Introduction to NFS
NFS (Network File System) allows remote systems to mount filesystems over a network as if they were local disks. Developed by Sun Microsystems in 1984, NFS has evolved through multiple versions, with NFSv4 being the current standard offering improved performance, security, and features.
Why Use NFS?
NFS provides several advantages for networked storage:
- Centralized storage: Single source of truth for shared data
- Transparent access: Mounted filesystems appear local to applications
- Cross-platform support: Works across Linux, Unix, and other systems
- Cost-effective: No specialized hardware required
- Scalable: Supports multiple concurrent clients
- Simple management: Centralized backup and maintenance
Common NFS Use Cases
- Home directories: Centralized user home directories across multiple systems
- Application data sharing: Shared configuration and data files
- Web content: Shared web root across multiple web servers
- Media streaming: Centralized media library for streaming services
- Development environments: Shared code repositories and build artifacts
- Container storage: Persistent volumes for Kubernetes and Docker
- Backup storage: Centralized backup destination
NFS Versions Overview
- NFSv3: Widely supported, stateless protocol, no built-in security
- NFSv4: Modern standard, stateful, improved security, better performance
- NFSv4.1: Adds parallel NFS (pNFS) for better scalability
- NFSv4.2: Latest version with server-side copy and sparse file support
This guide focuses on NFSv4 as the recommended version for new deployments.
Prerequisites
Before configuring NFS, ensure you have:
- Root or sudo access on both server and client systems
- Network connectivity between server and clients
- Firewall rules configured to allow NFS traffic
- Basic understanding of Linux filesystem concepts
- Synchronized time across server and clients (critical for NFSv4)
- Understanding of your network security requirements
System Requirements
NFS Server:
- Linux distribution with NFS server packages
- Sufficient storage space for shared directories
- Static IP address or reliable DNS name
- Adequate network bandwidth
NFS Client:
- Linux distribution with NFS client packages
- Mount point directories
- Network access to NFS server
Critical Security Warning
WARNING: Improper NFS configuration can expose sensitive data to unauthorized access. Always:
- Implement firewall rules to restrict NFS access
- Use NFSv4 with Kerberos authentication when possible
- Export only necessary directories
- Apply appropriate read/write restrictions
- Monitor NFS access logs
- Keep NFS software updated
- Never expose NFS directly to the internet without VPN
Part 1: NFS Server Configuration
Step 1: Install NFS Server Packages
On Debian/Ubuntu
sudo apt update
sudo apt install nfs-kernel-server
On CentOS/RHEL/Rocky Linux
sudo yum install nfs-utils
# or
sudo dnf install nfs-utils
Step 2: Verify NFS Installation
# Check NFS version
sudo nfsstat -v
# Verify NFS service
sudo systemctl status nfs-server
Step 3: Create Shared Directories
Create directories to be shared via NFS:
# Create main shared directory
sudo mkdir -p /srv/nfs/shared
# Create specific purpose directories
sudo mkdir -p /srv/nfs/homes
sudo mkdir -p /srv/nfs/data
sudo mkdir -p /srv/nfs/backups
Step 4: Set Directory Permissions
Configure appropriate permissions:
# Full access for shared directory
sudo chown -R nobody:nogroup /srv/nfs/shared
sudo chmod 777 /srv/nfs/shared
# Or more restrictive
sudo chown -R root:root /srv/nfs/data
sudo chmod 755 /srv/nfs/data
Note: nobody:nogroup (Debian/Ubuntu) or nfsnobody:nfsnobody (RHEL/CentOS) represents unprivileged users.
Step 5: Configure NFS Exports
The /etc/exports file defines which directories are shared and with what permissions.
Basic Export Configuration
Edit exports file:
sudo nano /etc/exports
Add export entries:
# Basic syntax: directory client(options)
# Share to specific IP
/srv/nfs/shared 192.168.1.100(rw,sync,no_subtree_check)
# Share to entire subnet
/srv/nfs/data 192.168.1.0/24(rw,sync,no_subtree_check)
# Share to multiple clients
/srv/nfs/backups 192.168.1.10(rw,sync) 192.168.1.11(rw,sync)
# Read-only share
/srv/nfs/readonly 192.168.1.0/24(ro,sync,no_subtree_check)
# Multiple exports
/srv/nfs/homes 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)
Understanding Export Options
Access Options:
- rw: Read-write access
- ro: Read-only access
Synchronization Options:
- sync: Write operations complete before responding (safer, slower)
- async: Respond before writes complete (faster, less safe)
ID Mapping Options:
- root_squash: Map root user to anonymous user (default, secure)
- no_root_squash: Allow root on client to have root access on server (dangerous)
- all_squash: Map all users to anonymous user
- anonuid=X, anongid=Y: Specify UID/GID for anonymous user
Other Important Options:
- no_subtree_check: Disable subtree checking (improves reliability)
- fsid=0: Mark as root filesystem for NFSv4
- crossmnt: Allow crossing mount points
- secure: Require connections from ports < 1024 (default)
- insecure: Allow connections from any port
Advanced Export Examples
sudo nano /etc/exports
# NFSv4 root export
/srv/nfs 192.168.1.0/24(rw,sync,fsid=0,crossmnt,no_subtree_check)
# User home directories
/srv/nfs/homes 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)
# Application data
/srv/nfs/app_data 192.168.1.50(rw,sync,no_subtree_check) 192.168.1.51(rw,sync,no_subtree_check)
# Web content (read-only for most, read-write for specific server)
/srv/nfs/www 192.168.1.0/24(ro,sync,no_subtree_check) 192.168.1.20(rw,sync,no_subtree_check)
# Backup storage (read-write for backup server only)
/srv/nfs/backups 192.168.1.30(rw,sync,no_subtree_check,no_root_squash)
# Media library (read-only for media servers)
/srv/nfs/media 192.168.1.0/24(ro,sync,no_subtree_check,all_squash,anonuid=1000,anongid=1000)
Step 6: Apply Export Configuration
After editing /etc/exports, apply the configuration:
sudo exportfs -a
Verify exports:
sudo exportfs -v
Output:
/srv/nfs/shared 192.168.1.0/24(rw,sync,wdelay,hide,no_subtree_check,sec=sys,...)
/srv/nfs/data 192.168.1.0/24(rw,sync,wdelay,hide,no_subtree_check,sec=sys,...)
Step 7: Start and Enable NFS Service
On Debian/Ubuntu
sudo systemctl enable nfs-kernel-server
sudo systemctl start nfs-kernel-server
sudo systemctl status nfs-kernel-server
On CentOS/RHEL/Rocky Linux
sudo systemctl enable nfs-server
sudo systemctl start nfs-server
sudo systemctl status nfs-server
Step 8: Configure Firewall
Allow NFS traffic through the firewall.
Using UFW (Debian/Ubuntu)
# Allow NFS from specific subnet
sudo ufw allow from 192.168.1.0/24 to any port nfs
# Or allow specific services
sudo ufw allow from 192.168.1.0/24 to any port 2049
sudo ufw allow from 192.168.1.0/24 to any port 111
# Reload firewall
sudo ufw reload
Using firewalld (CentOS/RHEL)
# Add NFS service
sudo firewall-cmd --permanent --add-service=nfs
sudo firewall-cmd --permanent --add-service=rpc-bind
sudo firewall-cmd --permanent --add-service=mountd
# Reload firewall
sudo firewall-cmd --reload
# Verify
sudo firewall-cmd --list-all
Using iptables
# Allow NFS
sudo iptables -A INPUT -p tcp --dport 2049 -s 192.168.1.0/24 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 111 -s 192.168.1.0/24 -j ACCEPT
sudo iptables -A INPUT -p udp --dport 111 -s 192.168.1.0/24 -j ACCEPT
# Save rules
sudo iptables-save | sudo tee /etc/iptables/rules.v4
Step 9: Verify NFS Server Configuration
Check NFS server status:
# Show exports
showmount -e localhost
# Check RPC services
rpcinfo -p localhost
# View NFS statistics
nfsstat -s
Expected output for showmount:
Export list for localhost:
/srv/nfs/shared 192.168.1.0/24
/srv/nfs/data 192.168.1.0/24
Part 2: NFS Client Configuration
Step 1: Install NFS Client Packages
On Debian/Ubuntu
sudo apt update
sudo apt install nfs-common
On CentOS/RHEL/Rocky Linux
sudo yum install nfs-utils
# or
sudo dnf install nfs-utils
Step 2: Create Mount Points
# Create mount point directories
sudo mkdir -p /mnt/nfs/shared
sudo mkdir -p /mnt/nfs/data
sudo mkdir -p /mnt/nfs/backups
Step 3: Test NFS Server Accessibility
Verify the NFS server is reachable:
# Check available exports (replace with your NFS server IP)
showmount -e 192.168.1.10
Output:
Export list for 192.168.1.10:
/srv/nfs/shared 192.168.1.0/24
/srv/nfs/data 192.168.1.0/24
Step 4: Mount NFS Share Temporarily
Test mounting before making it permanent:
# Mount NFS share
sudo mount -t nfs 192.168.1.10:/srv/nfs/shared /mnt/nfs/shared
# Verify mount
df -h /mnt/nfs/shared
mount | grep nfs
Output:
192.168.1.10:/srv/nfs/shared on /mnt/nfs/shared type nfs4 (rw,relatime,vers=4.2,...)
Step 5: Test NFS Share
# Create test file
echo "NFS test successful" | sudo tee /mnt/nfs/shared/test.txt
# Read test file
cat /mnt/nfs/shared/test.txt
# Verify from server
# (On NFS server)
cat /srv/nfs/shared/test.txt
Step 6: Unmount NFS Share (if testing)
sudo umount /mnt/nfs/shared
Step 7: Configure Automatic Mounting
Make NFS mounts permanent by adding to /etc/fstab.
Backup fstab
sudo cp /etc/fstab /etc/fstab.backup.$(date +%Y%m%d)
Add NFS Mounts to fstab
sudo nano /etc/fstab
Add entries:
# Basic NFSv4 mount
192.168.1.10:/srv/nfs/shared /mnt/nfs/shared nfs4 defaults 0 0
# With specific options
192.168.1.10:/srv/nfs/data /mnt/nfs/data nfs4 rw,hard,intr,rsize=8192,wsize=8192,timeo=14 0 0
# With nofail (continues boot if NFS unavailable)
192.168.1.10:/srv/nfs/backups /mnt/nfs/backups nfs4 defaults,nofail 0 0
# Read-only mount
192.168.1.10:/srv/nfs/readonly /mnt/nfs/readonly nfs4 ro,defaults 0 0
Understanding NFS Mount Options
Common Options:
- defaults: Use default options
- rw/ro: Read-write or read-only
- hard: Keep trying if server unavailable (recommended)
- soft: Return error after timeout (can cause data corruption)
- intr: Allow interruption of NFS operations
- nofail: Continue boot if mount fails
- _netdev: Wait for network before mounting
Performance Options:
- rsize=8192: Read buffer size in bytes
- wsize=8192: Write buffer size in bytes
- timeo=14: Timeout in tenths of seconds
- retrans=2: Number of retransmission attempts
- actimeo=3: Attribute cache timeout
Version Options:
- nfsvers=4: Force NFSv4 (or nfsvers=3 for NFSv3)
- vers=4.2: Specify exact NFSv4.2
Step 8: Test fstab Configuration
CRITICAL: Test before rebooting:
# Unmount if currently mounted
sudo umount /mnt/nfs/shared
# Mount all from fstab
sudo mount -a
# Verify
df -h | grep nfs
Step 9: Verify After Reboot
# Reboot to test automatic mounting
sudo reboot
# After reboot, verify mounts
df -h | grep nfs
mount | grep nfs
Performance Optimization
Optimizing NFS Performance
Server-Side Optimization
Edit /etc/default/nfs-kernel-server (Debian/Ubuntu) or /etc/nfs.conf (RHEL/CentOS):
# Increase number of NFS server threads
RPCNFSDCOUNT=16
# Or in /etc/nfs.conf
[nfsd]
threads=16
Restart NFS:
sudo systemctl restart nfs-kernel-server
Client-Side Optimization
Optimal mount options in /etc/fstab:
192.168.1.10:/srv/nfs/data /mnt/nfs/data nfs4 rw,hard,intr,rsize=131072,wsize=131072,timeo=600,retrans=2,_netdev 0 0
Options explained:
- rsize=131072: 128KB read size (adjust based on network)
- wsize=131072: 128KB write size
- timeo=600: 60-second timeout
- retrans=2: Two retransmission attempts
Network Optimization
Enable jumbo frames (if supported):
# On both server and clients
sudo ip link set eth0 mtu 9000
# Make permanent (edit network config)
# For netplan:
sudo nano /etc/netplan/01-netcfg.yaml
# Add under interface:
# mtu: 9000
Performance Testing
Test NFS Write Performance
# Create 1GB test file
dd if=/dev/zero of=/mnt/nfs/shared/testfile bs=1M count=1024 oflag=direct
Test NFS Read Performance
# Read test file
dd if=/mnt/nfs/shared/testfile of=/dev/null bs=1M
Comprehensive Benchmark
# Install fio
sudo apt install fio
# Run benchmark
fio --name=nfs-test --directory=/mnt/nfs/shared --size=1G \
--bs=4k --rw=randrw --rwmixread=70 --numjobs=4 --time_based \
--runtime=60 --group_reporting
Security Hardening
Using NFSv4 with Kerberos
For production environments, use Kerberos authentication.
On NFS Server
# Install Kerberos packages
sudo apt install krb5-user nfs-kernel-server
# Configure Kerberos
sudo nano /etc/krb5.conf
# Add NFS service principal
# (Requires Kerberos KDC setup - beyond scope)
Restricting Access by IP
Limit NFS access to specific IPs in /etc/exports:
# Single IP
/srv/nfs/secure 192.168.1.100(rw,sync,no_subtree_check)
# IP range
/srv/nfs/secure 192.168.1.100-192.168.1.110(rw,sync,no_subtree_check)
# Multiple specific IPs
/srv/nfs/secure 192.168.1.100(rw) 192.168.1.101(rw) 192.168.1.102(rw)
Using Firewall Rules
Implement strict firewall rules:
# Allow only from specific subnet
sudo iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 2049 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 2049 -j DROP
Monitoring NFS Access
Enable logging:
# View NFS statistics
nfsstat
# Monitor NFS connections
sudo netstat -an | grep 2049
# Check NFS logs
sudo journalctl -u nfs-server -f
Troubleshooting Common Issues
Issue: Cannot Mount NFS Share
Cause: Firewall blocking, incorrect exports, or network issues.
Solution:
# Check if server is reachable
ping 192.168.1.10
# Check if NFS port is open
telnet 192.168.1.10 2049
# Check exports from client
showmount -e 192.168.1.10
# Check NFS service on server
sudo systemctl status nfs-server
# Check firewall (on server)
sudo iptables -L -n | grep 2049
Issue: "Permission Denied" Errors
Cause: User ID mismatch or incorrect permissions.
Solution:
# Check directory permissions on server
ls -la /srv/nfs/shared
# Ensure UIDs match between server and client
# On server
id username
# On client
id username
# Fix permissions on server
sudo chown -R nobody:nogroup /srv/nfs/shared
sudo chmod 777 /srv/nfs/shared
# Or use all_squash in exports
# In /etc/exports:
/srv/nfs/shared 192.168.1.0/24(rw,sync,all_squash,anonuid=1000,anongid=1000)
Issue: Stale NFS File Handles
Cause: Server restarted or export configuration changed.
Solution:
# On client, unmount
sudo umount -f /mnt/nfs/shared
# Remount
sudo mount -a
# If still stale, reboot client
sudo reboot
Issue: Slow NFS Performance
Cause: Small buffer sizes, network latency, or server load.
Solution:
# Optimize mount options in /etc/fstab
192.168.1.10:/srv/nfs/data /mnt/nfs/data nfs4 rw,hard,intr,rsize=131072,wsize=131072,async 0 0
# Increase server threads (on server)
# Edit /etc/default/nfs-kernel-server
RPCNFSDCOUNT=32
# Restart NFS server
sudo systemctl restart nfs-kernel-server
Issue: "Mount.nfs: access denied by server"
Cause: Client IP not in exports or incorrect export options.
Solution:
# On server, check exports
sudo exportfs -v
# Verify client IP is allowed
# Edit /etc/exports if needed
sudo nano /etc/exports
# Reload exports
sudo exportfs -ra
# Check from client
showmount -e 192.168.1.10
Issue: NFS Not Mounting at Boot
Cause: Network not ready or incorrect fstab options.
Solution:
# Add _netdev option in /etc/fstab
192.168.1.10:/srv/nfs/shared /mnt/nfs/shared nfs4 defaults,_netdev,nofail 0 0
# Ensure network is ready before mounting
sudo systemctl enable NetworkManager-wait-online.service
Best Practices
1. Use NFSv4
NFSv4 offers better security and performance:
# Force NFSv4 in /etc/fstab
192.168.1.10:/srv/nfs/shared /mnt/nfs/shared nfs4 defaults 0 0
2. Use Root Squashing
Prevent root on client from having root access on server:
# In /etc/exports (root_squash is default)
/srv/nfs/shared 192.168.1.0/24(rw,sync,root_squash)
3. Use Sync Instead of Async
Safer but slightly slower:
# In /etc/exports
/srv/nfs/data 192.168.1.0/24(rw,sync,no_subtree_check)
4. Implement Firewall Rules
Restrict NFS access:
# Allow only from trusted subnet
sudo ufw allow from 192.168.1.0/24 to any port nfs
5. Monitor NFS Performance
Regular monitoring:
# Create monitoring script
cat << 'EOF' | sudo tee /usr/local/bin/nfs_monitor.sh
#!/bin/bash
nfsstat -s | grep -E 'commit|write|read'
EOF
sudo chmod +x /usr/local/bin/nfs_monitor.sh
6. Regular Backups
NFS server data should be backed up:
# Backup NFS shared directories
sudo rsync -avz /srv/nfs/ /backup/nfs_$(date +%Y%m%d)/
7. Use nofail for Non-Critical Mounts
Prevent boot failures:
# In /etc/fstab
192.168.1.10:/srv/nfs/optional /mnt/optional nfs4 defaults,nofail 0 0
8. Document NFS Configuration
Maintain documentation:
# Save NFS configuration
sudo cp /etc/exports /root/exports_backup_$(date +%Y%m%d)
sudo exportfs -v > /root/nfs_exports_$(date +%Y%m%d).txt
9. Keep Systems Updated
Regular updates:
# Update NFS packages
sudo apt update && sudo apt upgrade nfs-kernel-server nfs-common
10. Test Disaster Recovery
Regular testing:
# Test server failure scenario
# Test client remounting
# Verify data integrity
Advanced NFS Configurations
Exporting to Multiple Subnets
# In /etc/exports
/srv/nfs/multi 192.168.1.0/24(rw,sync) 10.0.0.0/24(rw,sync)
Using NFSv4 Pseudo-Filesystem
# In /etc/exports
/srv/nfs 192.168.1.0/24(rw,sync,fsid=0,crossmnt,no_subtree_check)
/srv/nfs/dir1 192.168.1.0/24(rw,sync,no_subtree_check)
/srv/nfs/dir2 192.168.1.0/24(rw,sync,no_subtree_check)
# Mount on client (note simplified path)
sudo mount -t nfs4 192.168.1.10:/dir1 /mnt/dir1
NFS with AutoFS
Automatically mount/unmount NFS shares on access:
# Install autofs
sudo apt install autofs
# Configure
sudo nano /etc/auto.master
# Add:
/mnt/auto /etc/auto.nfs --timeout=60
# Create auto.nfs
sudo nano /etc/auto.nfs
# Add:
shared -rw,hard,intr 192.168.1.10:/srv/nfs/shared
# Restart autofs
sudo systemctl restart autofs
# Test (automatically mounts on access)
ls /mnt/auto/shared
Conclusion
NFS provides powerful, flexible network storage capabilities for Linux environments. By properly configuring NFS servers and clients with appropriate security measures and performance optimizations, you can create reliable centralized storage solutions that scale with your infrastructure needs.
Key takeaways:
- Use NFSv4 for modern deployments
- Implement proper security with firewall rules and root_squash
- Optimize performance with appropriate buffer sizes
- Use _netdev and nofail in fstab for reliability
- Monitor NFS performance and access regularly
- Document configurations thoroughly
- Test failure scenarios before production deployment
- Keep systems updated for security and bug fixes
- Backup NFS data regularly
- Consider Kerberos for production security
Remember that NFS is best suited for trusted networks. For internet-facing storage or untrusted networks, consider VPN tunneling or alternative solutions like SFTP or cloud object storage.
By following the procedures and best practices in this guide, you can confidently deploy and manage NFS infrastructure that provides reliable, performant network storage for your Linux environment.


