STORAGE ENGINEERING

Linux network filesystems: NFS & SMB/CIFS

Category: Network StorageTechnologies: NFSv4.2, Samba, Kerberos, WireGuard, Active Directory, pNFS

NFS and SMB are the two dominant network filesystem protocols on Linux. NFS is native to Unix and optimized for Linux-to-Linux sharing; SMB (via Samba) is the standard for interoperability with Windows and Active Directory environments.

NFS versions

VersionStatePortsKey features
NFSv3Stateless111 + randomRequires rpcbind, mountd, lockd, statd. Firewall-unfriendly.
NFSv4Stateful2049 onlyIntegrated locking, ACLs, RPCSEC_GSS/Kerberos mandatory-to-implement (AUTH_SYS still permitted), compound operations.
NFSv4.1Stateful + sessions2049 onlypNFS (parallel access), session trunking, exactly-once semantics.
NFSv4.2Stateful + sessions2049 onlyServer-side copy, sparse files, IO advise, space reservation.

NFS server setup

# Debian/Ubuntu
sudo apt install nfs-kernel-server
sudo systemctl enable --now nfs-kernel-server

# RHEL/Fedora
sudo dnf install nfs-utils
sudo systemctl enable --now nfs-server

/etc/exports

# Read-write to a subnet, sync, no subtree check
/srv/nfs/share  192.168.1.0/24(rw,sync,no_subtree_check)

# With Kerberos privacy (encryption)
/home  10.0.0.0/16(rw,sec=krb5p)

# Multiple security flavors (preferred first)
/usr  10.0.0.0/16(rw,sec=krb5p:krb5i:krb5:sys)

# Read-only public
/srv/public  *(ro,sync,no_subtree_check)

# All users squashed to anonymous
/srv/guest  192.168.1.0/24(ro,all_squash,anonuid=65534,anongid=65534)

Export options

OptionEffect
rw / roRead-write / read-only
sync / asyncReply after commit / reply before commit (faster, unsafe)
no_subtree_checkDisable subtree checking (recommended for reliability)
root_squash (default)Map remote root (UID 0) to anonymous user
no_root_squashRemote root acts as root on server (security risk)
all_squashMap all users to anonymous
sec=sysAUTH_SYS, UID/GID based (insecure, default)
sec=krb5Kerberos authentication only
sec=krb5iKerberos + integrity (signed packets)
sec=krb5pKerberos + privacy (encrypted)

Applying exports

# Export all entries
sudo exportfs -a

# Re-export after editing /etc/exports
sudo exportfs -ra

# Display current exports
sudo exportfs -v

NFS client setup

# Debian/Ubuntu
sudo apt install nfs-common

# RHEL/Fedora
sudo dnf install nfs-utils

# Manual mount (NFSv4.2)
sudo mount -t nfs -o vers=4.2,hard,rsize=1048576,wsize=1048576 \
  server:/share /mnt/nfs

# /etc/fstab
server:/share  /mnt/nfs  nfs  _netdev,vers=4.2,hard,rsize=1048576,wsize=1048576  0  0

Key mount options

OptionEffect
hard (recommended)Retry indefinitely until server responds
softReturn error after retrans attempts (data loss risk)
rsize / wsizeMax read/write transfer size (NFSv4.2 default 1 MB)
timeo=600Initial timeout in tenths of seconds (60s default)
retrans=2Retransmissions before giving up (soft only)
nconnect=NUse N TCP connections (NFSv4.1+, max 16)
_netdevWait for network before mounting

autofs (on-demand mounting)

# /etc/auto.master
/mnt  /etc/auto.nfs  --timeout=60

# /etc/auto.nfs
share  -rw,hard,rsize=1048576,wsize=1048576  server:/srv/nfs/share

sudo systemctl enable --now autofs

NFS security

sec=sys is insecure

With sec=sys (the default), the client sends UID/GID in cleartext and the server trusts them. Any root user on any client can claim to be any user. Use Kerberos (sec=krb5p) or wrap NFS in a VPN.

NFS over WireGuard (modern alternative to Kerberos)

# Server: listen only on WireGuard interface
# /etc/nfs.conf:
[nfsd]
host = 10.0.0.1

# Export to WireGuard subnet only
/srv/data  10.0.0.0/24(rw,sync,no_subtree_check,sec=sys)

# Client: mount via WireGuard IP
sudo mount -t nfs 10.0.0.1:/srv/data /mnt/data

WireGuard provides network-layer encryption and authentication without the complexity of Kerberos. Tailscale works similarly with MagicDNS.

NFS and firewalls

NFSv4 uses a single TCP port (2049), firewall configuration is trivial:

# firewalld
sudo firewall-cmd --permanent --add-service=nfs
sudo firewall-cmd --reload

# iptables
sudo iptables -A INPUT -p tcp --dport 2049 -j ACCEPT

NFSv3 requires rpcbind (port 111) plus random ports for mountd, lockd, statd. Configure static ports in /etc/nfs.conf and open them all.

NFS performance tuning

# Max transfer sizes (NFSv4.2 supports 1 MB)
rsize=1048576,wsize=1048576

# Multiple connections (NFSv4.1+)
nconnect=4

# Aggressive attribute caching (single-client workloads)
actimeo=600

# Disable close-to-open consistency (single-client)
nocto

SMB protocol versions

VersionIntroducedKey features
SMB1 (CIFS)-Deprecated. Disable it. No encryption, vulnerable to WannaCry/NotPetya.
SMB2Vista/2008Reduced chattiness, pipelining
SMB3Win 8/2012Encryption, Multichannel, Direct (RDMA), Transparent Failover
SMB 3.1.1Win 10/2016AES-128-GCM/CCM, pre-auth integrity, SMB over QUIC

Samba server setup

# Debian/Ubuntu
sudo apt install samba

# RHEL/Fedora
sudo dnf install samba

sudo systemctl enable --now smb nmb

/etc/samba/smb.conf

[global]
    workgroup = WORKGROUP
    security = user
    server min protocol = SMB2_02
    server max protocol = SMB3
    smb encrypt = desired
    server multi channel support = yes
    # socket options: leave unset on modern kernels, OS self-tunes better

[homes]
    browseable = no
    read only = no
    create mask = 0700

[data]
    path = /srv/samba/data
    browseable = yes
    read only = no
    valid users = @smbgroup
    create mask = 0660
    directory mask = 0770

Validate and add users

# Validate configuration
sudo testparm

# Add a Samba user (must exist as system user)
sudo smbpasswd -a username

# Restart
sudo systemctl restart smbd nmb

SMB client setup

# Install
sudo apt install cifs-utils    # Debian/Ubuntu
sudo dnf install cifs-utils    # RHEL/Fedora

# Manual mount
sudo mount -t cifs //server/share /mnt/smb \
  -o credentials=/etc/smbcredentials,uid=1000,gid=1000,vers=3.0

# Credentials file (/etc/smbcredentials, chmod 600)
username=user
password=secret
domain=WORKGROUP

# /etc/fstab
//server/share  /mnt/smb  cifs  \
  credentials=/etc/smbcredentials,uid=1000,gid=1000,vers=3.0,_netdev  0  0

SMB security

Encryption

# Server-side (smb.conf)
[global]
    smb encrypt = desired    # use if client supports
    # or per-share:
    smb encrypt = required   # reject non-encrypting clients

# Client-side
sudo mount -t cifs //server/share /mnt/smb \
  -o credentials=/etc/smbcredentials,seal,vers=3.0

Active Directory integration

# Install
sudo dnf install realmd sssd adcli samba-common

# Discover and join
sudo realm discover ad.example.com
sudo realm join --user=administrator ad.example.com

# Allow domain users
sudo realm permit --all ad.example.com

NFS vs SMB comparison

FeatureNFSSMB
Native LinuxYesVia Samba
Native WindowsVia Services for NFSYes
EncryptionKerberos (krb5p) or VPNBuilt-in (SMB3)
AuthenticationUID/GID or KerberosUser-based (AD or local)
Parallel accesspNFS (v4.1+)SMB Multichannel
Printer sharingNoYes
Single portYes (v4: 2049)No (445 + 139)
Best forLinux-to-LinuxMixed Windows/Linux, AD environments

Debugging

# NFS statistics
nfsstat -s          # server stats
nfsstat -c          # client stats
nfsstat -m          # mount info

# Common NFS errors:
# ESTALE (116), stale file handle: unmount and remount
# EIO (5)      , I/O error: check server disk health
# EACCES (13)  , permission denied: check UID/GID mapping / exports
# ETIMEDOUT    , increase timeo or check network