Debian and Ubuntu Linux NFS Server Configuration and Management

General Description of an NFS Server

Network File System (NFS) is a distributed file-system protocol that allows a Linux server to export directories to remote clients. A client mounts an exported path into its own directory tree and applications normally use the files through ordinary POSIX file operations. The server remains responsible for the underlying storage, export policy, identity interpretation, locking, state recovery, write stability, and service availability.

An NFS server is not only a process listening on TCP port 2049. It is a coordinated stack consisting of the Linux kernel NFS server, user-space helper daemons, the export table, local file-system permissions and ACLs, name and identity services, firewall policy, optional Kerberos or TLS components, and the storage beneath the export. A successful TCP connection proves only that one part of the stack is reachable.

This guide is a companion to the Debian and Ubuntu networking guide. It starts with a safe single-server NFSv4 configuration, then expands into pseudo-filesystems, NFSv3 compatibility, export administration, identity and permission design, Kerberos, RPC-with-TLS where supported, quotas, monitoring, performance, high availability, and structured troubleshooting.

Typical server tasks include:

  • Installing and managing the nfs-kernel-server and supporting packages.
  • Preparing dedicated export storage with predictable ownership, group membership, ACLs, and mount ordering.
  • Defining client allow-lists and export options in /etc/exports or /etc/exports.d/*.exports.
  • Choosing NFSv4-only operation or deliberately supporting NFSv3 and its auxiliary RPC services.
  • Applying export changes without unnecessarily interrupting active clients.
  • Restricting network exposure with UFW or native nftables rules.
  • Securing user identity with consistent UID/GID data or Kerberos security flavours.
  • Monitoring nfsd, clients, RPC operations, storage latency, network traffic, and logs.
  • Diagnosing permission errors, stale file handles, lock recovery failures, timeouts, and poor performance.

Safety, Scope, Conventions, and Example Values

Scope: The examples target current Debian and Ubuntu releases using systemd and Linux nfs-utils. Ubuntu 22.04 LTS and later use /etc/nfs.conf and /etc/nfs.conf.d/*.conf as the normal unified daemon configuration. Older releases can still contain converted settings under /etc/nfs.conf.d or historical /etc/default/nfs-* files, so always inspect the effective configuration before assuming a default.

Warning: Changing export permissions, security flavours, protocol versions, file-system mounts, or firewall rules can immediately affect running applications. Keep console access, a tested rollback, and a current backup of both configuration and data. Coordinate maintenance with client owners before restarting the service or removing an export.

Command prompts used in this guide:

$ command       # Run as an ordinary user
# command       # Run as root, or prefix the command with sudo

Documentation-only example values:

Purpose

Example

NFS server

nfs01.example.com / 192.0.2.10

Authorised IPv4 client network

192.0.2.0/24

Authorised IPv6 client network

2001:db8:100::/64

Single client

client01.example.com / 192.0.2.21

NFSv4 namespace root

/srv/nfs

Projects export

/srv/nfs/projects

Underlying storage

/data/projects

Shared writer group

nfswriters, GID 2000

Kerberos realm

EXAMPLE.COM

 

Before editing, capture the current state and create dated backups:

# stamp=$(date +%F-%H%M%S)
# mkdir -p /root/nfs-backups/$stamp
# cp -a /etc/exports /etc/exports.d /etc/nfs.conf /etc/nfs.conf.d \
  /root/nfs-backups/$stamp/ 2>/dev/null || true
# exportfs -v > /root/nfs-backups/$stamp/exportfs-v.txt
# nfsconf –dump > /root/nfs-backups/$stamp/nfsconf-dump.txt 2>&1 || true
# systemctl status nfs-server –no-pager > /root/nfs-backups/$stamp/nfs-server.txt 2>&1 || true
# ss -lntup > /root/nfs-backups/$stamp/listeners.txt

Use a staged change: edit one file, validate or display the resulting configuration, apply the export table, test from a non-privileged client account, and only then remove the rollback copy.

Contents

  1. NFS architecture, protocol versions, and service components
  2. Planning storage, identity, permissions, availability, and security
  3. Installation and service management
  4. Configuration files and runtime state
  5. Preparing export directories, bind mounts, groups, and ACLs
  6. /etc/exports syntax, client selectors, and export options
  7. Basic NFSv4 export and NFSv4 pseudo-filesystem examples
  8. Adding, changing, deleting, and reloading exports
  9. NFSv4-only and NFSv3-compatible server configuration
  10. UFW and nftables firewall configuration
  11. UID/GID mapping, root squashing, and application access
  12. Kerberos-secured NFS and RPC-with-TLS
  13. Quotas, ACLs, extended attributes, and snapshots
  14. Performance tuning, monitoring, metrics, and packet capture
  15. Backups, maintenance, high availability, and disaster recovery
  16. Troubleshooting workflows and common errors
  17. Security hardening checklist and command reference

NFS Architecture, Protocol Versions, and Service Components

The Linux NFS server is implemented primarily in the kernel. User-space programs prepare policy and state, then the kernel nfsd threads perform file operations on behalf of clients. NFSv4 integrates more functions into the main protocol, whereas NFSv3 depends on additional RPC programs for mounting, locking, status notification, and optional quota reporting.

Version

Network and state model

Administrative implications

NFSv4.2

Stateful; normally TCP 2049; integrated locking; NFSv4 namespace; supports modern features such as server-side copy when the client, server, and storage support them.

Preferred starting point for current Linux clients. Simplifies firewalls and supports krb5, krb5i, krb5p, and newer RPC-with-TLS implementations.

NFSv4.1

Stateful sessions and improved connection handling; TCP 2049.

Useful when clients do not support 4.2 or when testing identifies an interoperability issue.

NFSv4.0

Stateful; TCP 2049; older recovery and callback behaviour.

Retain only for clients that require it. Verify DNS and identity mapping carefully.

NFSv3

Core protocol is largely stateless, but mountd, rpcbind, lockd, statd, and sometimes rquotad add state and dynamic RPC services.

Requires a wider firewall policy and explicit recovery testing. Use only when a client or application requires it.

 

Important Server Components

Component

Role

Useful checks

nfsd / rpc.nfsd

Kernel NFS service and its user-space launcher. Handles NFS protocol requests and server threads.

cat /proc/fs/nfsd/versions; ps -eLf | grep nfsd; nfsstat -s

exportfs

Builds and displays the effective export table from /etc/exports and /etc/exports.d/*.exports.

exportfs -rav; exportfs -v; exportfs -s

rpc.mountd / nfs-mountd

Authorises NFSv3 MOUNT requests and supplies export information to the kernel.

systemctl status nfs-mountd; rpcinfo -p

rpcbind

Maps RPC program numbers to ports. Normally required by NFSv3-era services.

systemctl status rpcbind; rpcinfo -p localhost

rpc.statd / lockd

NFSv3 lock and reboot notification support.

systemctl status rpc-statd; journalctl -u rpc-statd

nfs-idmapd

Assists NFSv4 name-to-ID mapping when that mapping path is used.

systemctl status nfs-idmapd; grep -v “^#” /etc/idmapd.conf

rpc-svcgssd

Server-side RPCSEC_GSS helper for Kerberos-secured NFS.

systemctl status rpc-svcgssd; klist -k /etc/krb5.keytab

nfsdcld / nfsdclnts

Maintains or inspects NFSv4 client recovery state and active client information.

nfsdclnts –clientinfo; journalctl -u nfsdcld

rpc.rquotad

Provides remote quota information when configured.

systemctl status rpc-rquotad; rpcinfo -p | grep rquota

 

Choose the Protocol Deliberately

For a new deployment with current Linux clients, begin with NFSv4.2 and keep NFSv4.1 available unless a compatibility or policy requirement says otherwise. Disable NFSv3 only after inventorying every operating system, appliance, hypervisor, backup product, and embedded client. A device can silently negotiate an older version even when an administrator expects NFSv4.

Check the versions enabled by the running kernel server:

$ cat /proc/fs/nfsd/versions
-2 -3 +4 +4.0 +4.1 +4.2

A plus sign means enabled and a minus sign means disabled. The exact line depends on the kernel, nfs-utils release, and configuration. Test the version actually negotiated from the client with nfsstat -m or findmnt -o TARGET,FSTYPE,OPTIONS.

Planning the NFS Server

A stable NFS service starts with storage and identity design, not with /etc/exports. Decide what is shared, who is trusted, which protocol and security flavour are required, how data is backed up, and what applications should do during an outage.

Planning Checklist

  • Use a dedicated file system or clearly defined subtree for each data class. Avoid exporting /, /etc, /var, or a broad parent that unintentionally exposes future mount points.
  • Confirm the underlying file system supports the required ownership, POSIX ACLs, extended attributes, quotas, snapshots, and application locking semantics.
  • Choose a stable server FQDN and address. Kerberos and TLS certificates depend on correct names, and clients should not be tied to an address that will change unexpectedly.
  • Define authorised clients with single hosts, explicit CIDR networks, or managed netgroups. Avoid a writable export to * in production.
  • Document numeric UID/GID ownership. sec=sys carries numeric credentials supplied by the client; it does not authenticate a human user.
  • Use root_squash unless a narrowly defined boot, provisioning, or appliance workflow demonstrably requires no_root_squash.
  • Choose sync for normal data integrity. Treat async as a measured exception because acknowledged writes can be lost after a crash or power failure.
  • Plan firewall rules from the client subnets only. NFSv4 is simpler because it normally needs TCP 2049; NFSv3 requires auxiliary RPC services.
  • Plan backup consistency. A snapshot, application quiesce, database-native backup, or cluster-aware procedure is often required; copying live files is not automatically application-consistent.
  • For high availability, design shared storage, fencing, a stable service address/name, NFSv4 recovery state, and export ownership as one system. DNS round-robin alone is not NFS failover.

Permission Layers

Layer

Question to answer

Export allow-list

Is this client host or network permitted to mount this path with the requested security flavour?

Firewall

Can the required protocol reach the server from this source address?

NFS credential

Which numeric UID/GID or Kerberos principal is presented for this operation?

Squashing

Is root, or every user, mapped to the anonymous UID/GID?

POSIX mode and ACL

Does the resulting local identity have search, read, write, create, delete, and rename permission?

Underlying file system

Is it mounted read-write, healthy, in space and inodes, and free of quota or I/O errors?

Application policy

Does the application use the expected account, umask, locking method, and file-creation pattern?

 

Install NFS Server Packages and Manage Services

Install and Verify Packages

# apt update
# apt install -y nfs-kernel-server nfs-common
$ dpkg-query -W nfs-kernel-server nfs-common
$ command -v exportfs nfsstat rpcinfo showmount nfsconf

The nfs-kernel-server package supplies the kernel-server service and server helpers. nfs-common supplies shared utilities used by both client and server components. Install quota, acl, krb5-user, tcpdump, sysstat, or nftables only when the corresponding functions are needed.

Enable, Start, Stop, Reload, and Restart

# systemctl enable –now nfs-server.service
$ systemctl status nfs-server.service –no-pager
$ systemctl is-enabled nfs-server.service
$ systemctl is-active nfs-server.service
# systemctl reload nfs-server.service
# systemctl restart nfs-server.service
# systemctl stop nfs-server.service

Use exportfs -rav for an export-table-only change whenever possible. A full restart interrupts service processing and forces clients through recovery behaviour. Changes to protocol versions, listener ports, server thread settings, Kerberos helpers, or TLS helpers normally require a service restart.

Initial Health Checks

$ cat /proc/fs/nfsd/versions
$ exportfs -v
$ ss -lntup | grep -E “:2049\b|rpcbind|mountd”
$ rpcinfo -p localhost
$ nfsstat -s
$ journalctl -u nfs-server -b –no-pager

On an NFSv4-only server, showmount -e can be empty or unavailable because showmount queries the older MOUNT protocol. Treat exportfs -v on the server and a direct NFSv4 client mount as authoritative tests.

Configuration Files and Runtime State

Path

Purpose

/etc/exports

Primary persistent export definitions.

/etc/exports.d/*.exports

Modular export snippets. Only files ending in .exports are read by exportfs.

/etc/nfs.conf

Unified INI-style configuration for nfsd, mountd, statd, lockd, gssd, svcgssd, and related programs.

/etc/nfs.conf.d/*.conf

Local configuration snippets read with /etc/nfs.conf. Later settings can override earlier settings.

/etc/idmapd.conf

NFSv4 ID-mapping domain and related settings when name mapping is used.

/etc/krb5.conf

Kerberos realms, KDC discovery, and client library settings.

/etc/krb5.keytab

Host and nfs service keys. Protect this file as a root-only secret.

/var/lib/nfs/etab

Runtime master export table maintained by exportfs; do not edit directly.

/var/lib/nfs/rmtab

Historical mount information used by mountd; it is not a complete NFSv4 active-client inventory.

/proc/fs/nfsd

Kernel nfsd control and status pseudo-filesystem.

/proc/net/rpc/nfsd

Raw server RPC counters used by tools such as nfsstat.

systemd journal

Service and kernel events; query with journalctl rather than expecting a dedicated NFS log file.

 

Inspect the Effective Daemon Configuration

$ nfsconf –dump
$ grep -R –line-number –exclude=”*.dpkg-*” –exclude=”*~” . \
  /etc/nfs.conf /etc/nfs.conf.d 2>/dev/null
$ systemctl cat nfs-server.service
$ systemctl list-dependencies nfs-server.service

Do not assume /etc/nfs.conf is the whole configuration. Package upgrades and migration tools can create local snippets. nfsconf –dump merges the relevant files and is the fastest way to reveal an override.

Prepare Export Storage, Ownership, Groups, and ACLs

Create a Dedicated Group-Writable Export

This example creates a shared projects area where members of a consistent nfswriters group can create files. The setgid bit keeps new entries in the shared group.

# groupadd –gid 2000 nfswriters
# mkdir -p /data/projects
# chown root:nfswriters /data/projects
# chmod 2770 /data/projects
$ stat -c “%A %a %U %G %n” /data/projects
$ getent group nfswriters

Create the same numeric GID and appropriate user memberships in the authoritative identity source used by every client. A group name that looks identical but has a different numeric GID is a different identity to NFS.

Use Default ACLs for Collaborative Directories

# apt install -y acl
# setfacl -m g:nfswriters:rwx /data/projects
# setfacl -m d:g:nfswriters:rwx /data/projects
# setfacl -m d:o::— /data/projects
$ getfacl -p /data/projects

Default ACLs control permissions inherited by new children. Application umasks and explicit chmod operations can still change results, so test file creation using the real service account rather than only root.

Bind Mount Storage into an NFSv4 Namespace

A bind mount separates the client-visible NFS namespace from the physical storage layout. This is useful when data lives under /data but clients should mount paths under a clean /srv/nfs tree.

# mkdir -p /srv/nfs/projects
# mount –bind /data/projects /srv/nfs/projects
$ findmnt /srv/nfs/projects

Persistent /etc/fstab entry:

/data/projects  /srv/nfs/projects  none  bind,x-systemd.requires-mounts-for=/data/projects  0  0
# systemctl daemon-reload
# mount -a
$ findmnt -R /srv/nfs

Use the mountpoint export option for a path that must be a mounted file system. It prevents an accidental export of the empty underlying directory if storage fails to mount:

/srv/nfs/projects  192.0.2.0/24(rw,sync,no_subtree_check,root_squash,mountpoint)

Warning: Never use chmod 777 as a substitute for identity and ACL design. It makes every local and remote identity able to modify the directory and often hides the real UID/GID problem until a security incident occurs.

/etc/exports Syntax and Client Selectors

Each export line starts with a local path, followed by one or more client selectors. An option list immediately follows each selector in parentheses. There must be whitespace between the path and the selector, but no whitespace between a selector and its opening parenthesis.

/srv/nfs/projects  192.0.2.0/24(rw,sync,no_subtree_check,root_squash)

Critical whitespace example: client01.example.com(rw) and client01.example.com (rw) do not mean the same thing. The second form separates the client from the option block and can create an unintended default export. Always review exportfs -v after a change.

Client Selector Examples

Selector type

Example

Notes

Single FQDN

client01.example.com

Requires reliable forward and reverse resolution. A DNS change can alter which system matches.

Single IPv4 address

192.0.2.21

Unambiguous but tied to the address.

IPv4 CIDR network

192.0.2.0/24

Common for a managed client subnet.

Single IPv6 address

2001:db8:100::21

Do not put square brackets around IPv6 addresses inside /etc/exports.

IPv6 prefix

2001:db8:100::/64

Authorises the whole prefix.

Wildcard domain

*.example.com

Matches dots as well as labels; broader than many administrators expect.

Netgroup

@engineering

Centralised host grouping through NSS; verify getent netgroup engineering.

Everyone

*

Avoid for writable production exports. It is not user authentication.

 

Multiple Clients with Different Options

/srv/nfs/projects  192.0.2.0/24(rw,sync,root_squash) \
  198.51.100.0/24(ro,sync,root_squash) \
  client-admin.example.com(rw,sync,root_squash)

A continuation backslash must be the final character on the line. Keep entries short enough to review, and prefer one clear export definition per data set.

Important Export Options

Option

Meaning and guidance

ro / rw

Read-only or read-write. ro is the default. File-system permissions can still deny a write on an rw export.

sync / async

sync replies after changes reach stable storage and is the normal integrity choice. async can improve throughput but acknowledged data can be lost or corrupted after an unclean restart.

root_squash

Maps client UID 0 to the anonymous identity. This is the normal safe default.

no_root_squash

Preserves remote root authority. Use only for a tightly restricted, documented workflow; a compromised client root can then create or alter server-owned files.

all_squash

Maps every remote identity to the anonymous account. Useful for drop boxes or service shares with one controlled server-side identity.

anonuid / anongid

Sets the numeric anonymous UID and GID. Create and protect a dedicated local account when all_squash is used.

subtree_check

Checks whether each requested file remains under the exported subtree. Can add overhead and cause problems with frequent renames.

no_subtree_check

Disables subtree verification. Common for dedicated export roots and frequently changing data.

secure / insecure

secure normally requires non-GSS requests to originate from a reserved client port. insecure permits high source ports and should be used only for a client that requires it.

fsid=0

Marks the root of an NFSv4 pseudo-filesystem. Use only one root per server namespace.

fsid=N

Provides a stable file-system identifier where needed. Keep values unique and stable.

crossmnt

Lets a parent export cross into mounted child file systems and can implicitly export children with inherited options. Audit carefully.

nohide

Makes a mounted child visible through a parent for certain NFSv2/v3 cases. Client behaviour varies; prefer explicit exports or the NFSv4 namespace.

mountpoint / mp

Exports the path only when it is a mount point, preventing accidental exposure of an empty backing directory.

wdelay / no_wdelay

Controls a small write delay used to combine related synchronous writes. no_wdelay has no effect with async.

sec=sys

Uses client-supplied UNIX-style numeric credentials. It provides no cryptographic user authentication.

sec=krb5

Kerberos authentication without integrity protection for ordinary NFS payload data.

sec=krb5i

Kerberos authentication plus integrity protection.

sec=krb5p

Kerberos authentication, integrity, and privacy encryption. Strongest Kerberos flavour, with additional CPU cost.

xprtsec=tls / mtls

On supported current nfs-utils and kernel stacks, requires RPC-with-TLS confidentiality or mutual TLS for the export. Confirm release support before relying on it.

 

Explicitly state the important options instead of relying on defaults. The common default set includes ro, sync, root_squash, and wdelay, but readable configuration is safer than hidden assumptions.

Basic NFSv4 Server Configuration

Create and Export a Single Path

# mkdir -p /srv/nfs/projects
# chown root:nfswriters /srv/nfs/projects
# chmod 2770 /srv/nfs/projects

Add to /etc/exports or to /etc/exports.d/projects.exports:

/srv/nfs/projects  192.0.2.0/24(rw,sync,no_subtree_check,root_squash)

Validate and activate:

# exportfs -rav
$ exportfs -v
$ exportfs -s
$ systemctl status nfs-server –no-pager
$ ss -lnt sport = :2049

Permit NFSv4 Through UFW

# ufw allow from 192.0.2.0/24 to any port 2049 proto tcp comment “NFSv4 clients”
# ufw status numbered

Test from an Authorised Client

# apt install -y nfs-common
# mkdir -p /mnt/projects
# mount -t nfs4 -o vers=4.2,proto=tcp nfs01.example.com:/srv/nfs/projects /mnt/projects
$ findmnt /mnt/projects
$ nfsstat -m
$ sudo -u projectuser touch /mnt/projects/client-write-test
$ ls -ln /mnt/projects/client-write-test
$ rm /mnt/projects/client-write-test
# umount /mnt/projects

Test with the actual non-root account that will run the workload. A root-only test can be misleading because root_squash intentionally changes root into an anonymous identity.

Build an NFSv4 Pseudo-Filesystem Namespace

An NFSv4 pseudo-filesystem presents a stable client-visible tree even when the server stores data on several local file systems. The namespace root is exported with fsid=0, and child paths are exported separately. Clients then mount paths such as nfs01.example.com:/projects rather than the server-local /srv/nfs/projects path.

Prepare the Namespace

# mkdir -p /srv/nfs/projects /srv/nfs/reference
# mount –bind /data/projects /srv/nfs/projects
# mount –bind /data/reference /srv/nfs/reference
$ findmnt -R /srv/nfs

Example /etc/fstab entries:

/data/projects   /srv/nfs/projects   none  bind  0  0
/data/reference  /srv/nfs/reference  none  bind  0  0

Define the Exports

/srv/nfs  192.0.2.0/24(ro,fsid=0,crossmnt,sync,no_subtree_check,root_squash)
/srv/nfs/projects  192.0.2.0/24(rw,sync,no_subtree_check,root_squash,mountpoint)
/srv/nfs/reference 192.0.2.0/24(ro,sync,no_subtree_check,root_squash,mountpoint)
# exportfs -rav
$ exportfs -v

Client Mounts

# mount -t nfs4 nfs01.example.com:/projects /mnt/projects
# mount -t nfs4 nfs01.example.com:/reference /mnt/reference
$ findmnt -t nfs4

Use exactly one fsid=0 root for the intended NFSv4 namespace. Do not casually add crossmnt to a broad directory because newly mounted child file systems can become reachable with inherited export options.

Add, Change, Delete, and Reload Exports

Display Current Exports

$ exportfs
$ exportfs -v
$ exportfs -s
$ cat /var/lib/nfs/etab

exportfs -v is for human review. exportfs -s prints a form suitable for configuration comparison. /var/lib/nfs/etab is runtime state and must not be edited directly.

Apply Additions and Changes

# editor /etc/exports.d/projects.exports
# exportfs -rav
$ exportfs -v

The -r option synchronises runtime exports with persistent files, removing entries deleted from configuration. The -a option applies all entries and -v shows each action.

Temporarily Add an Export

# exportfs -o ro,sync,root_squash client01.example.com:/srv/nfs/reference
$ exportfs -v

A command-line-only export is useful for a controlled test but is not persistent. Record it and remove it after the test so runtime state does not diverge from configuration.

Remove One Export

# exportfs -u client01.example.com:/srv/nfs/reference
$ exportfs -v

Remove an Export Persistently

# editor /etc/exports.d/projects.exports
# exportfs -rav
$ exportfs -v

Warning: exportfs -ua unexports everything and can disrupt every client. Use it only during a planned shutdown or a deliberately isolated test.

Safe Change Sequence

  1. Confirm which clients are using the export and whether open files or locks are present.
  2. Back up the export files and capture exportfs -v.
  3. Change one entry and run exportfs -rav.
  4. Review exportfs -v for unexpected clients or options.
  5. Remount or retest from an authorised client and a deliberately unauthorised client.
  6. Monitor logs and application behaviour before deleting the rollback copy.

Configure an NFSv4-Only Server

NFSv4-only operation reduces open ports and removes dependencies on the NFSv3 MOUNT, lock, and status-notification path. Use it only after confirming that all clients support the required NFSv4 minor versions.

Create /etc/nfs.conf.d/server.conf:

[nfsd]
vers3 = n
vers4 = y
tcp = y
udp = n

To allow only NFSv4.1 and NFSv4.2, make the minor-version choices explicit:

[nfsd]
vers3 = n
vers4.0 = n
vers4.1 = y
vers4.2 = y
tcp = y
udp = n
$ nfsconf –dump
# systemctl restart nfs-server.service
$ cat /proc/fs/nfsd/versions
$ ss -lntup | grep -E “:2049\b|rpcbind|mountd”

Do not mask rpcbind or rpc-statd merely because one NFS service no longer needs them; another installed application can depend on RPC. First inventory rpcinfo -p, systemctl list-dependencies, package dependencies, and monitoring requirements. The firewall should expose only the services actually required by clients.

Bind NFS to Selected Server Addresses

On a multi-homed server, the [nfsd] host setting can restrict listeners to selected addresses or names. Confirm syntax and support with man nfs.conf and rpc.nfsd on the installed release, then test both IPv4 and IPv6.

[nfsd]
host = 192.0.2.10
host = 2001:db8:100::10
port = 2049

Binding a listener does not replace firewall policy or the export client allow-list. It only controls where the service listens.

Support NFSv3 with Fixed Ports

NFSv3 needs rpcbind and auxiliary RPC programs. Dynamic ports make firewall rules difficult, so pin the relevant daemons to documented unused ports. Check for conflicts before activation and test TCP and UDP behaviour required by the actual clients.

Example /etc/nfs.conf.d/nfsv3.conf:

[nfsd]
vers3 = y
vers4 = y
tcp = y
udp = n

[mountd]
port = 20048

[statd]
port = 32765
outgoing-port = 32766

[lockd]
port = 32767
udp-port = 32767
# ss -lntup | grep -E “:(111|20048|32765|32766|32767|2049)\b”
# systemctl restart rpcbind rpc-statd nfs-server
$ rpcinfo -p localhost
$ cat /proc/fs/nfsd/versions

The example disables NFS UDP while retaining TCP. Some legacy clients require UDP; enable it only when required and include equivalent firewall rules. Verify actual daemon ports with rpcinfo -p rather than assuming that a configuration file was honoured.

UFW Rules for the Example NFSv3 Port Set

# ufw allow from 192.0.2.0/24 to any port 111 proto tcp comment “RPC bind TCP”
# ufw allow from 192.0.2.0/24 to any port 111 proto udp comment “RPC bind UDP”
# ufw allow from 192.0.2.0/24 to any port 2049 proto tcp comment “NFS TCP”
# ufw allow from 192.0.2.0/24 to any port 20048 proto tcp comment “mountd TCP”
# ufw allow from 192.0.2.0/24 to any port 20048 proto udp comment “mountd UDP”
# ufw allow from 192.0.2.0/24 to any port 32765 proto tcp comment “statd TCP”
# ufw allow from 192.0.2.0/24 to any port 32765 proto udp comment “statd UDP”
# ufw allow from 192.0.2.0/24 to any port 32767 proto tcp comment “lockd TCP”
# ufw allow from 192.0.2.0/24 to any port 32767 proto udp comment “lockd UDP”
# ufw status numbered

The outgoing statd port controls notifications sent by the server and may need an egress or peer rule depending on network policy. Confirm packet flow with tcpdump during a planned lock-recovery test.

Native nftables Firewall Examples

Use either UFW as the policy manager or a directly managed nftables ruleset. Do not maintain two independent rule managers that overwrite or contradict each other.

NFSv4-Only Input Rule

table inet filter {
  set nfs_clients4 {
    type ipv4_addr
    flags interval
    elements = { 192.0.2.0/24 }
  }

  chain input {
    type filter hook input priority 0; policy drop;
    ct state established,related accept
    iifname “lo” accept
    ip saddr @nfs_clients4 tcp dport 2049 accept
  }
}

Merge this concept into the host’s existing ruleset rather than replacing a production firewall. Preserve management, monitoring, DNS, time, and other required traffic.

Trace a Firewall Decision

# nft list ruleset
# nft monitor trace
# tcpdump -ni any host 192.0.2.21 and port 2049

A SYN arriving at the interface but no SYN-ACK leaving suggests a local listener or firewall problem. No arriving SYN suggests routing, upstream ACL, address, DNS, or client-side problems.

Identity, UID/GID Mapping, and Squashing

Understand sec=sys

With sec=sys, the client kernel sends UNIX-style numeric credentials. The server generally trusts those numbers as supplied by an authorised client. Matching usernames are not sufficient; the numeric UID and GID must represent the same person or service on every system. A client administrator can normally create a local account with an arbitrary UID, so sec=sys should be used only on trusted, managed clients and protected networks.

$ id projectuser
$ getent passwd projectuser
$ getent group nfswriters
$ ls -ldn /srv/nfs/projects
$ getfacl -pn /srv/nfs/projects

Demonstrate Root Squashing

Server export:

/srv/nfs/projects  192.0.2.0/24(rw,sync,no_subtree_check,root_squash)

Client test:

# touch /mnt/projects/created-by-client-root
$ ls -ln /mnt/projects/created-by-client-root

The resulting owner can be the anonymous UID rather than 0. That is expected. Grant normal users or a service group the required permission instead of disabling root squashing.

Map All Users to a Dedicated Anonymous Account

# groupadd –system –gid 2001 nfsdrop
# useradd –system –uid 2001 –gid 2001 –home-dir /nonexistent \
  –shell /usr/sbin/nologin nfsdrop
# mkdir -p /srv/nfs/dropbox
# chown nfsdrop:nfsdrop /srv/nfs/dropbox
# chmod 0730 /srv/nfs/dropbox
/srv/nfs/dropbox  192.0.2.0/24(rw,sync,no_subtree_check,all_squash,anonuid=2001,anongid=2001)

This pattern deliberately removes individual ownership. It can be useful for a controlled ingest area, but it is unsuitable where per-user accountability is required.

NFSv4 ID Mapping Domain

Current Linux NFSv4 deployments often use numeric IDs directly for ordinary sec=sys operation, but idmapd can still be involved in particular paths and legacy combinations. If names appear as nobody or ownership looks inconsistent, inspect /etc/idmapd.conf, DNS domain assumptions, daemon state, and actual numeric values before changing permissions.

$ grep -Ev “^[[:space:]]*(#|$)” /etc/idmapd.conf
$ systemctl status nfs-idmapd –no-pager
$ nfsidmap -l 2>/dev/null || true
# nfsidmap -c

Clear ID-mapping caches only during troubleshooting and after correcting the underlying domain or identity source. Cache clearing is not a substitute for consistent directory data.

Kerberos-Secured NFS Server

Kerberos RPCSEC_GSS security flavours authenticate principals instead of trusting only client-supplied numeric IDs. krb5 authenticates, krb5i also protects integrity, and krb5p also encrypts NFS payload traffic. Correct DNS, synchronized time, a functioning KDC, and protected keytabs are prerequisites.

Prepare DNS, Time, and Packages

$ hostname –fqdn
$ getent hosts nfs01.example.com
$ timedatectl status
$ chronyc tracking 2>/dev/null || true
# apt install -y nfs-kernel-server krb5-user

Create the NFS Service Principal and Keytab

Run the principal-management commands according to the Kerberos platform. A typical MIT Kerberos example is:

$ kadmin -p admin/admin -q “addprinc -randkey nfs/nfs01.example.com”
# kadmin -p admin/admin -q “ktadd nfs/nfs01.example.com”
# klist -k /etc/krb5.keytab

Security note: /etc/krb5.keytab is a long-lived machine secret. Keep it owned by root, mode 0600, backed up only through an approved secret-handling process, and remove obsolete keys after a controlled rollover.

Require Kerberos on an Export

/srv/nfs/secure  192.0.2.0/24(rw,sync,no_subtree_check,root_squash,sec=krb5p)
# exportfs -rav
# systemctl restart nfs-server.service
$ systemctl status rpc-svcgssd –no-pager
$ journalctl -u rpc-svcgssd -b –no-pager

Offer Different Access by Security Flavour

Only ro/rw and squash behaviour can vary after a sec= group in the supported export syntax. One example is read-only legacy access and read-write Kerberos privacy access:

/srv/nfs/reference  192.0.2.0/24(sec=sys,ro,root_squash,sec=krb5p,rw,root_squash,sync,no_subtree_check)

Keep such entries simple and verify exportfs -v. Complex security-flavour ordering is easy to misread.

Client Verification

$ kinit projectuser@EXAMPLE.COM
$ klist
# mount -t nfs4 -o sec=krb5p nfs01.example.com:/secure /mnt/secure
$ nfsstat -m
$ sudo -u projectuser touch /mnt/secure/kerberos-test

Kerberos Troubleshooting

$ getent hosts nfs01.example.com
$ dig -x 192.0.2.10 +short
$ chronyc tracking
$ klist -k /etc/krb5.keytab
$ kvno nfs/nfs01.example.com
# journalctl -b -u rpc-svcgssd -u nfs-server
# tcpdump -ni any port 88 or port 2049

A mount that works with sec=sys but fails with sec=krb5p normally points to DNS canonicalisation, time skew, missing or mismatched service keys, principal naming, ticket acquisition, or the GSS helper rather than basic IP reachability.

RPC-with-TLS on Supported Debian and Ubuntu Releases

Recent Linux NFS server and nfs-utils releases can use RPC-with-TLS as defined by RFC 9289. Availability depends on the installed kernel, nfs-utils, ktls-utils or tlshd packaging, and distribution release. Check the release documentation and man exports for xprtsec support before making it a requirement. A VPN remains a valid alternative when the platform does not provide server-side RPC-with-TLS.

Check Capability

$ man exports | col -b | grep -A12 -i “Transport layer security”
$ command -v tlshd
$ systemctl status tlshd.service –no-pager
$ grep -R “xprtsec” /usr/share/man/man5/exports.5* 2>/dev/null

Typical Server Components

# apt install -y ktls-utils   # Package name and availability vary by release
# editor /etc/tlshd.conf
# systemctl enable –now tlshd.service
# journalctl -u tlshd.service -b

When the installed exports(5) supports policy enforcement, an export can require transport security:

/srv/nfs/private  192.0.2.0/24(rw,sync,root_squash,xprtsec=tls)

Use xprtsec=mtls only after provisioning and validating client certificates and trust. TLS protects transport confidentiality; it does not replace export permissions, local ownership, or application authorisation. Combine it with an appropriate security flavour and client allow-list.

Quotas, ACLs, Extended Attributes, and Snapshots

Enable File-System Quotas First

NFS cannot enforce a useful remote quota if the underlying file system has no local quota configuration. Enable user, group, or project quotas according to the file system, remount requirements, and storage policy, then verify locally before exposing quota information remotely.

$ findmnt -no SOURCE,FSTYPE,OPTIONS /srv/nfs/projects
# quotaon -p /srv/nfs/projects 2>/dev/null || true
# xfs_quota -x -c “state” /srv/nfs/projects 2>/dev/null || true

Provide Remote Quota Information

# apt install -y quota
$ systemctl list-unit-files | grep -E “rquota|quotad”
# systemctl enable –now rpc-rquotad.service
$ rpcinfo -p localhost | grep -i rquota

If the quota daemon uses a fixed port, allow that TCP/UDP port only from client networks and document it with the NFSv3 RPC port plan. Service names and default options can differ by release, so confirm systemctl cat rpc-rquotad and rpc.rquotad –help before changing the port.

ACL and Extended Attribute Tests

$ getfacl -p /srv/nfs/projects
$ setfacl -m u:projectuser:rwx /srv/nfs/projects/testdir
$ getfattr -d -m – /srv/nfs/projects/testfile 2>/dev/null
$ setfattr -n user.nfs_test -v yes /srv/nfs/projects/testfile

Test the real client and application. Support for a local feature does not automatically prove that every NFS version, client kernel, mount option, and application will use it as expected.

Snapshots and Backups

Take snapshots on the server storage layer, not from a client that sees only the network view. Before a snapshot intended for application recovery, quiesce or coordinate the workload. For databases and virtual-machine images, use application-aware or hypervisor-aware backup methods rather than assuming a crash-consistent file copy is sufficient.

Performance Tuning and Capacity Planning

Measure before tuning. NFS throughput can be limited by storage latency, queue depth, network loss, link speed, CPU, server thread availability, synchronous-write behaviour, client mount choices, file-size distribution, or application locking. Changing rsize, wsize, thread counts, or async without identifying the bottleneck can make reliability worse.

Establish a Baseline

$ uptime
$ free -h
$ df -hT /srv/nfs/projects
$ df -ih /srv/nfs/projects
$ iostat -xz 1
$ sar -n DEV,EDEV 1
$ nfsstat -s 1
$ ss -s
$ ethtool enp1s0
$ ip -s link show dev enp1s0

NFS Server Thread Count

The [nfsd] threads setting controls the number of server worker threads. Too few can limit concurrency; excessively many consume memory and do not repair slow storage. Increase in measured steps while observing RPC backlog, CPU, and storage latency.

[nfsd]
threads = 32
$ cat /proc/fs/nfsd/threads
# systemctl restart nfs-server
$ cat /proc/fs/nfsd/threads

Interpret sync and async Carefully

sync protects the NFS protocol guarantee that a completed stable write survives a server crash, subject to honest storage hardware. async can produce attractive benchmark results by acknowledging before stable storage, but a sudden reset can lose acknowledged data or leave application structures inconsistent. Prefer better storage, write-back cache with power-loss protection, batching, and application tuning before changing to async.

Network and Storage Tests

# iperf3 -s
# fio –name=nfs-backing-test –directory=/srv/nfs/projects \
  –rw=write –bs=1M –size=4G –direct=1 –iodepth=16 \
  –numjobs=1 –runtime=60 –time_based
$ iostat -xz 1

Run destructive benchmarks only in an isolated test directory with an approved data set. A local storage benchmark and a network iperf3 test help separate the two paths, but the final test must use the real NFS client, mount options, file sizes, concurrency, and application I/O pattern.

Common Performance Indicators

Observation

Likely direction

High disk await and utilisation; network below capacity

Underlying storage or synchronous commit latency.

Interface drops, CRC errors, retransmissions, or duplex mismatch

Physical or data-link problem before NFS tuning.

Many retransmissions with normal server storage

Loss, congestion, MTU, firewall state, or overloaded network path.

One client slow, others normal

Client route, NIC, mount options, DNS, credentials, or local workload.

Small-file metadata workload slow

Directory contention, storage metadata latency, lookup/cache behaviour, or application serialization.

All nfsd threads busy and RPC backlog grows

Consider more threads only after confirming CPU and storage headroom.

Write benchmark fast with async but unsafe for workload

Do not treat unsafe acknowledgement semantics as a storage upgrade.

 

Monitor the NFS Server

Exports, Clients, and Operations

$ exportfs -v
$ nfsstat -s
$ nfsstat -s 1
$ cat /proc/net/rpc/nfsd
$ nfsdclnts –clientinfo 2>/dev/null
$ nfsdclnts –type open 2>/dev/null
$ showmount -a localhost 2>/dev/null

showmount reflects the older mount protocol and is not a complete list of NFSv4 clients. Use nfsdclnts where available, connection state, NFSv4 recovery data, application inventory, and central monitoring together.

Sockets and Connection State

$ ss -lntup | grep -E “:2049\b|rpc”
$ ss -tn sport = :2049
$ ss -tin sport = :2049
$ conntrack -L -p tcp –dport 2049 2>/dev/null | head

Interface and Packet Monitoring

$ ip -s -s link show dev enp1s0
$ ethtool -S enp1s0
$ sar -n DEV,EDEV,TCP,ETCP 1
# tcpdump -ni enp1s0 tcp port 2049
# tcpdump -ni enp1s0 host 192.0.2.21 and port 2049 -w /var/tmp/nfs-client01.pcap

Logs

# journalctl -u nfs-server -b
# journalctl -u nfs-mountd -u nfs-idmapd -u rpc-statd -u rpc-svcgssd -b
# journalctl -k -b | grep -Ei “nfs|rpc|lockd|sunrpc|stale|I/O error”
# journalctl –since “-30 minutes” | grep -Ei “nfs|rpc|mountd|gss|quota”

Increase daemon debug logging only for a bounded troubleshooting window. Verbose RPC and authentication logs can be noisy and can expose client names or operational details. Record the prior setting and revert it after collecting evidence.

Maintenance, Backups, and High Availability

Planned Maintenance Sequence

  1. Identify active clients, open files, lock-sensitive applications, and the expected outage behaviour.
  2. Stop or quiesce applications that cannot safely tolerate a pause.
  3. Confirm backups or storage snapshots and preserve /etc/exports, /etc/nfs.conf.d, keytabs, certificates, and service metadata according to policy.
  4. Apply storage or operating-system maintenance through console access.
  5. Verify mounts, file-system health, exportfs -v, protocol versions, firewall state, and service listeners before reopening applications.
  6. Test create, read, rename, lock, and delete operations using an ordinary client account.

Configuration Backup Set

# tar –xattrs –acls -czf /root/nfs-config-$stamp.tar.gz \
  /etc/exports /etc/exports.d /etc/nfs.conf /etc/nfs.conf.d \
  /etc/idmapd.conf /etc/krb5.conf 2>/dev/null
# exportfs -v > /root/exportfs-$stamp.txt
# nfsconf –dump > /root/nfsconf-$stamp.txt 2>&1

Handle /etc/krb5.keytab and TLS private keys separately as secrets. A normal configuration archive can have a broader readership than a key archive.

High Availability Design Principles

  • Use storage that can be activated safely on only the intended server, or a supported clustered file system and NFS stack.
  • Use fencing to prevent two nodes from exporting the same non-cluster-safe writable file system simultaneously.
  • Move a stable service IP and DNS identity with the NFS service, not independently.
  • Preserve or coordinate NFSv4 recovery state and grace periods so locks and opens recover correctly after failover.
  • Keep export definitions, UID/GID sources, Kerberos keys, TLS trust, and firewall rules consistent on every eligible node.
  • Test abrupt failure, planned migration, lock recovery, long-running I/O, and client retry behaviour before declaring the service highly available.

Pacemaker and resource-agent design is environment-specific and should follow the storage vendor and cluster distribution documentation. Do not build NFS failover by merely copying /etc/exports and floating an address between two independently writable local disks.

Troubleshooting Workflow

Troubleshoot from the lowest failing layer upward. Capture evidence before restarting services, because a restart can remove the state needed to identify the original fault.

1. Confirm Server Storage

$ findmnt -R /srv/nfs
$ df -hT /srv/nfs/projects
$ df -ih /srv/nfs/projects
$ stat /srv/nfs/projects
$ touch /srv/nfs/projects/server-local-test && rm /srv/nfs/projects/server-local-test
# dmesg -T | grep -Ei “I/O error|filesystem|ext4|xfs|btrfs|nvme|scsi”

2. Confirm Service and Protocol

$ systemctl status nfs-server –no-pager
$ cat /proc/fs/nfsd/versions
$ ss -lntup | grep -E “:2049\b|rpcbind|mountd”
$ rpcinfo -p localhost
$ journalctl -u nfs-server -b –no-pager

3. Confirm the Effective Export

$ exportfs -v
$ exportfs -s
$ grep -R –line-number . /etc/exports /etc/exports.d 2>/dev/null

4. Confirm Network and Firewall

$ ip route get 192.0.2.21
$ nft list ruleset
$ ufw status verbose
# tcpdump -ni any host 192.0.2.21 and port 2049

5. Confirm Identity and Permissions

$ id projectuser
$ getent passwd projectuser
$ getent group nfswriters
$ namei -om /srv/nfs/projects
$ ls -ldn /srv/nfs/projects
$ getfacl -pn /srv/nfs/projects

6. Reproduce from the Client

$ getent hosts nfs01.example.com
$ nc -vz -w 3 nfs01.example.com 2049
# mount -vvv -t nfs4 -o vers=4.2 nfs01.example.com:/projects /mnt/projects
$ nfsstat -m
$ sudo -u projectuser touch /mnt/projects/testfile

Common Errors and Interpretations

Symptom

Likely causes

Checks and corrective direction

access denied by server while mounting

Wrong path, client not in allow-list, wrong security flavour, DNS selector mismatch, stale export table.

Compare requested path with exportfs -v; use an IP/CIDR test; run exportfs -rav; inspect mountd/GSS logs.

Permission denied after a successful mount

POSIX mode/ACL, UID/GID mismatch, root_squash, read-only export or file system, quota, application identity.

Use id, ls -ln, getfacl -n, namei -om, findmnt, quota tools, and a non-root create test.

read-only file system

Export is ro, client mounted ro, underlying file system is ro, or file-system error forced read-only mode.

Check exportfs -v, nfsstat -m, findmnt on server, and kernel I/O logs.

stale file handle

Exported object was replaced, file system was remounted with changed identity, snapshot/restore changed handles, or a subtree moved.

Correct server storage/export identity first; then unmount/remount affected clients. Avoid hiding the root cause with repeated remounts.

server not responding

Service down, firewall, route, packet loss, overloaded storage, hung kernel I/O, or address failover problem.

Check TCP 2049, tcpdump both ends, ss, nfsstat, iostat, interface errors, and server console.

NFSv4 works but showmount fails

Pure NFSv4 service does not expose the older MOUNT protocol.

Use exportfs -v and a direct NFSv4 mount; do not open NFSv3 ports only to satisfy showmount.

NFSv3 mount works but locks fail

lockd/statd port blocked, reboot notification failure, or mixed TCP/UDP policy.

Check rpcinfo -p, fixed ports, rpc-statd logs, packet capture, and a controlled lock test.

nobody / nogroup ownership

Squashing, missing identity, ID-mapping domain mismatch, or unknown numeric IDs.

Inspect export options, ls -ln, getent, idmapd settings, and client/server identity sources.

Kerberos permission or mount failure

No ticket, wrong principal, DNS mismatch, clock skew, keytab problem, GSS helper stopped, sec mismatch.

Use klist, kvno, klist -k, chronyc, forward/reverse DNS, rpc-svcgssd journal, and sec= mount options.

Slow writes

sync commit latency, storage saturation, small random I/O, network loss, too few threads, application fsync pattern.

Correlate nfsstat, iostat, sar, ss -ti, packet loss, and client workload before tuning.

Cannot unexport or unmount cleanly

Active processes, current working directory, open files, locks, or application retry loop.

Use fuser -vm, lsof +D carefully, client inventory, application shutdown, and planned maintenance.

 

Diagnostic Snapshot Collection

Collect a bounded state package before making disruptive changes. Review it for secrets before sending it outside the organisation.

# stamp=$(date +%F-%H%M%S)
# out=/var/tmp/nfs-diag-$stamp
# mkdir -p “$out”
# exportfs -v > “$out/exportfs-v.txt” 2>&1
# exportfs -s > “$out/exportfs-s.txt” 2>&1
# nfsconf –dump > “$out/nfsconf.txt” 2>&1
# cat /proc/fs/nfsd/versions > “$out/versions.txt” 2>&1
# cat /proc/net/rpc/nfsd > “$out/proc-nfsd.txt” 2>&1
# nfsstat -s > “$out/nfsstat-s.txt” 2>&1
# rpcinfo -p localhost > “$out/rpcinfo.txt” 2>&1
# ss -lntup > “$out/ss-listen.txt” 2>&1
# ss -tin sport = :2049 > “$out/ss-2049.txt” 2>&1
# ip -s -s link > “$out/ip-link.txt” 2>&1
# findmnt -R /srv/nfs > “$out/findmnt.txt” 2>&1
# df -hT > “$out/df-hT.txt” 2>&1
# df -ih > “$out/df-ih.txt” 2>&1
# journalctl -b -u nfs-server -u nfs-mountd -u rpc-statd \
  -u rpc-svcgssd –no-pager > “$out/journal.txt” 2>&1
# dmesg -T > “$out/dmesg.txt” 2>&1
# tar -C /var/tmp -czf “$out.tar.gz” “$(basename “$out”)”
# printf “%s\n” “$out.tar.gz”

Do not include /etc/krb5.keytab, TLS private keys, or confidential file names in a support archive unless the recipient and transfer method are explicitly approved.

Security Hardening Checklist

  • Prefer NFSv4 and disable NFSv3 when the complete client inventory permits it.
  • Restrict exports and firewall rules to explicit hosts or CIDR networks; do not rely on a writable * export.
  • Keep root_squash enabled and document every exception to it.
  • Use sync unless a formal risk decision accepts possible acknowledged-data loss with async.
  • Keep UID/GID data centrally managed and test an ordinary account, not only root.
  • Use sec=krb5i or sec=krb5p for stronger user authentication and protection where Kerberos is available.
  • Use RPC-with-TLS or a VPN for transport encryption on platforms that support it, and require it explicitly when policy demands it.
  • Protect keytabs and private keys as secrets; rotate and remove obsolete material.
  • Keep the server, kernel, nfs-utils, and storage firmware patched through the distribution support channel.
  • Monitor export changes, service restarts, authentication failures, file-system errors, capacity, and network drops.
  • Back up configuration and data, and test restoration to a clean system.
  • For HA, use fencing and a supported storage/cluster design; never permit split-brain writers.

Command Reference Summary

Task

Command

Install server

apt install -y nfs-kernel-server nfs-common

Start at boot

systemctl enable –now nfs-server

Show exports

exportfs -v

Apply persistent exports

exportfs -rav

Show normalised exports

exportfs -s

Unexport one client/path

exportfs -u client:/path

Dump daemon configuration

nfsconf –dump

Show enabled NFS versions

cat /proc/fs/nfsd/versions

Show RPC programs

rpcinfo -p localhost

Show listeners

ss -lntup

Server RPC statistics

nfsstat -s

Watch server RPC statistics

nfsstat -s 1

Inspect NFSv4 clients

nfsdclnts –clientinfo

Service logs

journalctl -u nfs-server -b

Kernel NFS logs

journalctl -k -b | grep -Ei “nfs|rpc|lockd”

Check path permissions

namei -om /srv/nfs/projects; getfacl -pn /srv/nfs/projects

Capture NFSv4 traffic

tcpdump -ni any tcp port 2049 -w nfs.pcap

UFW NFSv4 allow

ufw allow from 192.0.2.0/24 to any port 2049 proto tcp

 

Authoritative References

Use the manual pages installed on the exact server because option availability follows the installed kernel and nfs-utils version:

Validate every example against the release documentation, local man pages, security policy, storage design, and a non-production test client before applying it to a live service.

 

Check out our other Cheat Sheets and Blogs and if you would like us to write a cheat sheet for you, for FREE, (and we find it suitable) Contact Us.