Introduction
NFS:
- Native Unix sharing protocol (since 1984)
- Better performance than SMB on Linux LAN
- Transparent mount: NFS share appears as local FS
- Versions: NFSv3 (UDP/TCP), NFSv4 (TCP only, more secure and performant)
- Auth: Unix uid/gid (NFSv3), optional Kerberos (NFSv4)
Use cases: Linux NAS, shared homes, VM storage (Proxmox, KVM), shared scientific data.
⚠️ NFS without Kerberos = source IP security only. Never on internet.
Prerequisites
- Linux server Debian / Ubuntu (NFS server)
- Linux clients that mount
- Dedicated LAN or VPN
- Root access
Step 1: Server installation
sudo apt update
sudo apt install -y nfs-kernel-server
sudo systemctl status nfs-server
Step 2: Create share directory
sudo mkdir -p /srv/nfs/share
sudo chown nobody:nogroup /srv/nfs/share
sudo chmod 755 /srv/nfs/share
For writable share:
sudo chmod 775 /srv/nfs/share
Step 3: Export the share
/etc/exports:
/srv/nfs/share 192.168.50.0/24(rw,sync,no_subtree_check,no_root_squash)
/srv/nfs/data 192.168.50.10(rw,sync,no_subtree_check) 192.168.50.11(rw,sync,no_subtree_check)
/srv/nfs/readonly 192.168.50.0/24(ro,sync,no_subtree_check,root_squash)
Important options:
rw/ro: read-write / read-onlysync: synchronous writes (on disk before ack). Safer.asyncfaster but risky on crash.no_subtree_check: recommended, avoids costly checksroot_squash(default): client root becomesnobodyon server (security)no_root_squash: client root = server root (dangerous, only for legit cases)all_squash: all users becomenobody
Step 4: Apply and start
sudo exportfs -ra
sudo systemctl restart nfs-server
sudo systemctl enable nfs-server
sudo exportfs -v
Step 5: Open firewall
NFSv4 uses only port 2049:
sudo ufw allow from 192.168.50.0/24 to any port 2049
NFSv3 needs multiple dynamic ports (rpcbind 111, mountd, nlockmgr). NFSv4 is preferable.
To pin NFSv3 ports:
sudo nano /etc/default/nfs-kernel-server
RPCMOUNTDOPTS="--port 32767"
STATDOPTS="--port 32765"
Step 6: Client install
sudo apt update
sudo apt install -y nfs-common
Step 7: Manual mount
sudo mkdir -p /mnt/nfs-share
sudo mount -t nfs4 192.168.50.10:/srv/nfs/share /mnt/nfs-share
df -h /mnt/nfs-share
You can read/write in /mnt/nfs-share.
Step 8: Auto mount via fstab
/etc/fstab:
192.168.50.10:/srv/nfs/share /mnt/nfs-share nfs4 defaults,_netdev,soft,intr,timeo=600 0 0
Client options:
soft: server down doesn't block (fails after timeout)hard: blocks indefinitely (default, sometimes needed for VMs)_netdev: wait for network at boottimeo=600: RPC timeout in tenths of secondnofail: don't block boot if mount fails
sudo mount -a
Step 9: Automount (autofs)
To mount on-demand only:
sudo apt install -y autofs
sudo nano /etc/auto.master
Add:
/mnt/nfs /etc/auto.nfs --timeout=60
sudo nano /etc/auto.nfs
share -fstype=nfs4,soft,intr 192.168.50.10:/srv/nfs/share
data -fstype=nfs4,soft,intr 192.168.50.10:/srv/nfs/data
sudo systemctl restart autofs
ls /mnt/nfs/share # auto mount
After 60s idle, autofs unmounts.
Step 10: Performance tuning
Buffer sizes
On client:
sudo mount -t nfs4 server:/path /mnt/point -o rsize=1048576,wsize=1048576,nconnect=8
rsize/wsize: read/write block sizes (1 MB recommended)nconnect=8: 8 parallel TCP connections (NFSv4.1+, big perf boost)
Async write (risky but fast)
sudo mount -t nfs4 server:/path /mnt/point -o async
⚠️ Crash can lose writes. Only for tolerant use cases.
Perf test
dd if=/dev/zero of=/mnt/nfs-share/test.bin bs=1M count=1024 oflag=direct
dd if=/mnt/nfs-share/test.bin of=/dev/null bs=1M
Gigabit LAN: expect 110 MB/s+. 10 GbE: 800 MB/s+.
Step 11: NFSv4 with Kerberos (secure)
For strong auth, configure Kerberos and export with sec=krb5p:
/srv/nfs/secure *(rw,sync,sec=krb5p)
Complex (needs KDC), useful in enterprise. For small LANs, stay with sec=sys + IP whitelist.
Step 12: Monitoring
Server side:
sudo nfsstat -s
sudo nfsstat -m
sudo showmount -e
sudo showmount -a 192.168.50.10
Client side:
nfsstat -c
mount | grep nfs
Logs:
sudo journalctl -u nfs-server -f
sudo dmesg | grep nfs
Troubleshooting
"mount.nfs: Connection refused"
Service not started or port blocked:
sudo systemctl status nfs-server
sudo ss -tunlp | grep 2049
sudo ufw status
"Permission denied" on write
uid mapping issue. Client and server must have same uid for user. Else use all_squash with anonuid:
/srv/nfs/share *(rw,sync,no_subtree_check,all_squash,anonuid=1000,anongid=1000)
"Stale file handle"
File deleted or server restarted. Remount:
sudo umount -f /mnt/nfs-share
sudo mount /mnt/nfs-share
Slow performance
mount | grep nfs # see active options
Increase rsize / wsize and try nconnect.
Server won't start
sudo exportfs -ra
sudo journalctl -u nfs-server
Check /etc/exports (syntax-sensitive, spaces matter).
Useful commands
# Server
sudo systemctl status nfs-server
sudo systemctl restart nfs-server
sudo exportfs -v
sudo exportfs -ra
sudo nfsstat -s
sudo showmount -e
sudo showmount -a
# Client
sudo mount -t nfs4 server:/path /mnt/point
sudo umount /mnt/point
sudo umount -f /mnt/point
mount | grep nfs
nfsstat -c
sudo rpcinfo -p server
# Diagnostic
sudo journalctl -u nfs-server -f
sudo dmesg | grep nfs
ss -tunlp | grep 2049
Conclusion
NFS is the standard for Linux/Unix file sharing:
- Better performance than SMB on Linux LAN
- Transparent mount
- Stable, mature, in kernel
Limits:
- IP / uid security (unless Kerberos)
- Not suitable for public LAN or internet without VPN
- Performance dependent on network (latency matters)
Going further:
- For multi-client write-intensive, consider GlusterFS or CephFS
- For HA NFS, look at DRBD + Pacemaker or commercial NAS
- For cross-platform, Samba remains more universal
Resources
- NFSv4 spec: https://datatracker.ietf.org/doc/html/rfc7530
- Linux NFS Wiki: https://linux-nfs.org
- Ubuntu NFS server guide: https://ubuntu.com/server/docs/network-file-system-nfs
- Debian wiki: https://wiki.debian.org/NFSServerSetup

















