NFS and Samba: Linux File Sharing Setup Guide

NFS and Samba: Linux File Sharing Setup Guide

NFS (Network File System) is the standard protocol for sharing filesystems between Linux and Unix systems. It allows remote directories to be mounted and accessed as if they were local, making it fundamental to shared storage architectures, home directory sharing, and NAS (Network Attached Storage) integration.

NFS Architecture

NFS uses a client-server model built on top of RPC (Remote Procedure Call):

  • NFS Server: Exports one or more directories to the network
  • NFS Client: Mounts the exported directories and accesses them
  • rpcbind: Port mapper daemon — translates RPC program numbers to network ports
  • mountd: Handles mount and unmount requests from clients
  • nfsd: The actual NFS server daemon that handles file operations

NFS Versions

VersionDefault inProtocolSecurityKey Features
NFSv2Old systemsUDPNoneBasic file sharing
NFSv3RHEL 5UDP/TCPNoneLarge files, async writes, better error handling
NFSv4RHEL 6/7TCP onlyKerberos (optional)Stateful, ACLs, single port (2049), delegation
NFSv4.1RHEL 7+TCPKerberospNFS (parallel NFS), sessions, better clustering

NFSv3 vs NFSv4 Key Differences

  • NFSv3: Stateless — server does not track client connections. Simpler but no session recovery. Uses multiple ports (111, 2049, plus dynamic ports for mountd, lockd, statd).
  • NFSv4: Stateful — server maintains session state. Uses only port 2049 (no rpcbind needed for v4). Supports file locking natively. Supports ACLs. Requires only TCP.

NFS Server Configuration — Step by Step

# Install NFS packages:
# yum install nfs-utils -y

# Create directory to share:
# mkdir -p /nfs/shared
# chmod 755 /nfs/shared              # basic permissions
# chown nobody:nobody /nfs/shared    # for anonymous access

# For SELinux:
# chcon -t public_content_rw_t /nfs/shared    # if clients need write access
# chcon -t public_content_t /nfs/shared       # if read-only

# The /etc/exports file:
# Format: directory  client(options)
# vim /etc/exports

# Export to a specific hostname:
/nfs/shared  client9.example.com(rw,sync,no_root_squash)

# Export to entire domain:
/nfs/shared  *.example.com(rw,sync)

# Export to IP subnet:
/nfs/shared  192.168.1.0/24(rw,sync,no_subtree_check)

# Export read-only to everyone:
/nfs/shared  *(ro,sync)

# Multiple clients with different permissions:
/nfs/data  db1.example.com(rw,sync) web.example.com(ro,sync)

Export Options Explained

OptionMeaning
rwRead-write access
roRead-only access (default if unspecified)
syncWrite to disk before replying to client. Safer, slightly slower.
asyncReply before writing to disk. Faster, risk of data loss on server crash.
root_squashMap remote root (UID 0) to anonymous user (nobody). Default. Prevents remote root from owning server files.
no_root_squashRemote root has root access on server. Use only on trusted private networks.
all_squashMap all remote UIDs to anonymous user (for public shares)
no_subtree_checkDisable subtree checking (faster, recommended for most exports)
secureRequire clients to use ports below 1024 (default, ensures privileged client)
insecureAllow client ports above 1024 (needed for some NFS clients)
# Apply exports without restarting NFS:
# exportfs -rv                       # re-read /etc/exports, verbose
# exportfs -a                        # export all
# exportfs -ua                       # unexport all (maintenance)

# View current exports:
# exportfs -v

# Start NFS (RHEL 7):
# systemctl start nfs-server rpcbind
# systemctl enable nfs-server rpcbind

# Start NFS (RHEL 6):
# service rpcbind start
# service nfs start
# chkconfig rpcbind on
# chkconfig nfs on

NFS Client Configuration

# Install:
# yum install nfs-utils -y

# Discover what a server exports:
# showmount -e nfs-server.example.com
# showmount -e 192.168.1.11

# Mount manually (temporary):
# mkdir -p /mnt/nfs_data
# mount -t nfs nfs-server:/nfs/shared /mnt/nfs_data
# mount -t nfs4 nfs-server:/nfs/shared /mnt/nfs_data   # force NFSv4
# mount -o ro,sync nfs-server:/nfs/shared /mnt/readonly

# Mount with additional options:
# mount -o rw,sync,hard,intr nfs-server:/share /mnt/nfs
# hard   = keep retrying if server unreachable (default, prevents data loss)
# soft   = return error if server unreachable (use with timeout)
# intr   = allow interrupt signals during hard mount (Ctrl+C works)
# noatime = don't update access times (performance)

# Permanent mount (/etc/fstab):
nfs-server:/nfs/shared  /mnt/nfs_data  nfs  defaults,_netdev  0  0
# _netdev = wait for network before mounting (critical for NFS mounts)

# NFSv4 mount (single port, no rpcbind):
nfs-server:/nfs/shared  /mnt/nfs_data  nfs4  defaults,_netdev  0  0

Autofs — On-Demand Mounting

Autofs automatically mounts NFS shares when they are accessed and unmounts them after a timeout period. Benefits:

  • Reduces system load (unmounted shares consume no resources)
  • Handles NFS server unavailability gracefully (no stale mounts)
  • Used for home directories in LDAP/NIS environments
  • Users only get the mount they actually access
# Install:
# yum install autofs -y

# Main map: /etc/auto.master
# Format: mount_point  map_file  [options]
/misc   /etc/auto.misc         --timeout=60
/home   /etc/auto.home         --timeout=300

# Map file: /etc/auto.misc
# Format: subdirectory  [-options]  location
nfs  -rw,sync  nfs-server:/nfs/shared
# Creates /misc/nfs → mounted when accessed, unmounted after 60 seconds

# Home directory map: /etc/auto.home
# Format: username  -options  server:/path/to/homedir
*  -rw,sync  nfs-server:/home/&
# & substitutes for the matched username
# So "raju" at /home/raju → mounts nfs-server:/home/raju

# Start autofs:
# systemctl start autofs
# systemctl enable autofs

# Test (accessing the directory triggers the mount):
# ls /misc/nfs                       # triggers mount
# ls /misc/                          # before access: empty
# cd /misc/nfs && ls                 # mounts here
# sleep 65 && ls /misc/              # after timeout: unmounted

# Reload autofs after config change (without restart):
# systemctl reload autofs

# Verify active mounts:
# service autofs status
# cat /proc/mounts | grep autofs

NFS Security — Kerberos Authentication

By default, NFS uses AUTH_SYS (trust client-supplied UID/GID). NFSv4 with Kerberos provides real authentication.

# NFS security levels (specified in /etc/exports):
/nfs/secure  *.example.com(rw,sync,sec=krb5)

# sec= options:
# sys     = AUTH_SYS (default, trusts client UID/GID — no real auth)
# krb5    = Kerberos v5 authentication only
# krb5i   = Kerberos + integrity (tamper detection)
# krb5p   = Kerberos + integrity + encryption (most secure)

Firewall Configuration for NFS

# NFSv4 uses only port 2049 (TCP):
# firewall-cmd --permanent --add-service=nfs    # port 2049
# firewall-cmd --reload

# NFSv3 requires additional ports:
# firewall-cmd --permanent --add-service=mountd  # rpc.mountd
# firewall-cmd --permanent --add-service=rpc-bind # portmapper
# firewall-cmd --reload

# For RHEL 6 (iptables), fix NFSv3 ports in /etc/sysconfig/nfs:
RQUOTAD_PORT=875
LOCKD_TCPPORT=32803
LOCKD_UDPPORT=32769
MOUNTD_PORT=892
STATD_PORT=662

# Then add fixed port rules to /etc/sysconfig/iptables:
-A INPUT -m state --state NEW -p tcp --dport 2049 -j ACCEPT
-A INPUT -m state --state NEW -p tcp --dport 111 -j ACCEPT
-A INPUT -m state --state NEW -p tcp --dport 875 -j ACCEPT
-A INPUT -m state --state NEW -p tcp --dport 892 -j ACCEPT

NFS Troubleshooting

# Client cannot mount:
# 1. Check server is exporting:
# showmount -e server_ip
# exportfs -v

# 2. Check RPC services:
# rpcinfo -p server_ip               # list RPC services and ports

# 3. Check firewall:
# firewall-cmd --list-all            # verify NFS service is open

# 4. Check SELinux on server:
# sealert -a /var/log/audit/audit.log
# getsebool -a | grep nfs

# 5. Check mount syntax:
# mount -v server:/share /mnt/nfs    # verbose

# Performance issues:
# NFS is slow → check network bandwidth, try async option, increase rsize/wsize:
# mount -o rsize=65536,wsize=65536,hard,intr server:/share /mnt/nfs

# Stale NFS mount (server went away):
# umount -f -l /mnt/nfs              # lazy force unmount
# fuser -ck /mnt/nfs                 # kill processes using it first

# Statistics:
# nfsstat                            # NFS call statistics
# nfsiostat 1 5                      # I/O statistics per mount