Set up NFS
You have a Fedora machine with a large storage array and you want a laptop on the same network to access files without copying them over SSH. You run mount -t nfs and the command hangs. Or the mount succeeds but you get Permission denied when you try to create a file. Or the system boots but the share is missing because the network wasn't ready in time. NFS is a mature protocol, but Fedora's security stack treats network shares with suspicion until you configure the firewall, SELinux, and systemd mount dependencies explicitly.
What's actually happening
NFS stands for Network File System. It allows a client to mount a remote directory and interact with files as if they were local. The protocol relies on RPC (Remote Procedure Call) to negotiate ports and services. The server runs rpcbind to act as a switchboard, telling clients which ports to use for NFS operations. The nfs-server service handles the actual file reads and writes.
Fedora enforces three layers of control. The firewall blocks NFS ports by default. SELinux labels every file with a security context; if a file lacks the nfs_t context, the kernel blocks access even if standard Linux permissions allow it. Systemd manages boot order; if the network interface isn't up when systemd tries to mount the share, the mount fails or the boot hangs. You must configure all three layers for a reliable setup.
Server configuration
Install the NFS utilities and enable the services. The nfs-utils package provides both server and client tools. rpcbind must start before nfs-server because the NFS daemon registers its ports with the portmapper.
sudo dnf install nfs-utils -y
# Install nfs-utils which contains server and client binaries
sudo systemctl enable --now nfs-server rpcbind
# Enable and start nfs-server and rpcbind. rpcbind must run first for port mapping
Configure the firewall to allow NFS traffic. NFS uses multiple ports. The nfs service covers the main NFS ports, rpc-bind covers the portmapper, and mountd handles export requests. Always reload the firewall after adding rules. The runtime configuration and persistent configuration diverge if you skip this step.
sudo firewall-cmd --permanent --add-service=nfs --add-service=rpc-bind --add-service=mountd
# Add NFS, rpc-bind, and mountd services to the permanent zone configuration
sudo firewall-cmd --reload
# Reload the firewall to apply permanent rules to the running configuration
Define the shared directories in /etc/exports. This file controls which directories are exported and which clients can access them. The syntax is directory client(options). Options are comma-separated. rw allows read-write access. sync forces the server to write data to disk before replying, preventing data loss on crash. no_subtree_check improves performance by skipping checks for file existence in subdirectories, but reduces safety if files are renamed during access.
/srv/nfs/data 192.168.1.0/24(rw,sync,no_subtree_check)
# Export /srv/nfs/data to the 192.168.1.0/24 subnet with read-write access
# sync ensures data integrity. no_subtree_check improves performance
Apply the export configuration. The exportfs command reads /etc/exports and updates the kernel's export table. Use -r to re-export all entries and -a to affect all clients.
sudo exportfs -ra
# Re-export all directories defined in /etc/exports to active clients
Verify the exports are active. The -v flag prints verbose output showing the effective options for each export.
sudo exportfs -v
# List all active exports with their options to verify configuration
Client configuration
Install nfs-utils on the client. Create a mount point directory. Mount the share to test connectivity. The -t nfs flag specifies the filesystem type. NFSv4 is the default on modern Fedora systems and handles security better than NFSv3.
sudo dnf install nfs-utils -y
# Install nfs-utils for client-side mounting tools
sudo mkdir -p /mnt/nfs-share
# Create the local mount point directory
sudo mount -t nfs 192.168.1.10:/srv/nfs/data /mnt/nfs-share
# Mount the remote share. NFSv4 is used by default on Fedora
Make the mount persistent across reboots by adding an entry to /etc/fstab. The _netdev option is mandatory. It tells systemd to wait for the network to be available before attempting the mount. Without _netdev, the system may try to mount the share before the network interface is up, causing boot delays or mount failures.
192.168.1.10:/srv/nfs/data /mnt/nfs-share nfs defaults,_netdev 0 0
# Mount remote share at boot. _netdev ensures network is ready first
# 0 0 disables dump and fsck for network filesystems
Mount all filesystems defined in fstab to verify the entry works without rebooting.
sudo mount -a
# Mount all filesystems listed in /etc/fstab to test the new entry
SELinux and permissions
SELinux is the most common cause of NFS failures on Fedora. The server denies access if the exported directory lacks the correct security context. The default context for NFS exports is nfs_t. If you share a directory that was created outside the NFS workflow, it likely has a different context like user_home_t or var_t.
Check the current context of the exported directory.
ls -Zd /srv/nfs/data
# Display the SELinux context of the directory. Look for nfs_t
Set the correct context. Use chcon to change the context recursively. The -R flag applies the change to all files and subdirectories. The -t nfs_t flag sets the type to the NFS label.
sudo chcon -Rt nfs_t /srv/nfs/data
# Recursively set the SELinux type to nfs_t for the export directory
If you create new files in the directory, they inherit the parent context. However, if you move files from elsewhere, they retain their original context. Use restorecon to reset contexts to the default policy for the path.
sudo restorecon -Rv /srv/nfs/data
# Restore default SELinux contexts recursively. -v prints changes
Some setups require SELinux booleans to allow NFS to export all directories. The nfs_export_all_rw boolean permits read-write exports of any directory, not just those explicitly labeled for NFS. Use this if you encounter denials despite correct contexts. The -P flag makes the change persistent across reboots.
sudo setsebool -P nfs_export_all_rw 1
# Enable read-write NFS exports for all directories persistently
Check for SELinux denials in the audit log. The setroubleshoot service provides human-readable summaries of denials.
sudo journalctl -t setroubleshoot
# View SELinux denial summaries. Look for NFS-related messages
SELinux denies silently. If you get Permission denied, check the logs before disabling SELinux. Disabling SELinux breaks the security model and is not a fix.
UID and GID mapping
NFS relies on numeric UIDs and GIDs, not usernames. If a user has UID 1000 on the client and UID 1000 on the server, the file ownership matches. If the UIDs differ, the client sees files owned by a different user, and permissions may break.
Ensure UIDs match across machines. Check the UID of a user on both systems.
id username
# Display UID and GID for the user. Compare values on server and client
If UIDs differ, you have two options. Change the UID on one system to match the other, or use NFSv4 ID mapping. NFSv4 ID mapping translates usernames to IDs automatically. Fedora supports NFSv4 ID mapping via nfs-idmap. Enable the service and configure the domain.
sudo systemctl enable --now nfs-idmap
# Enable the NFS ID mapping service for NFSv4 username translation
Edit /etc/idmapd.conf on both server and client. Set the Domain to match your network domain.
[General]
Domain = example.local
# Set the NFSv4 domain. Must match on server and client for ID mapping
Restart the idmap service after editing the config.
sudo systemctl restart nfs-idmap
# Restart idmap to apply domain configuration changes
Use NFSv4 ID mapping when UIDs cannot be synchronized. Use numeric UID matching when you control all systems and want maximum compatibility with NFSv3 clients.
Verify the setup
Check that the mount is active and accessible. List the mount point to confirm files appear. Write a test file to verify permissions.
ls -l /mnt/nfs-share
# List files in the mount point to verify visibility
echo "test" | sudo tee /mnt/nfs-share/testfile
# Write a test file to verify write permissions
Check the mount options. The mount command shows the active options for the share.
mount | grep nfs
# Display active NFS mounts and their options
Verify SELinux contexts on the client. The client sees the server's contexts. Files should show nfs_t.
ls -Z /mnt/nfs-share
# Check SELinux contexts of files in the mount
Run journalctl -xe on the server if you encounter errors. The -x flag adds explanatory text, and -e jumps to the end of the journal. Filter by unit to focus on NFS logs.
sudo journalctl -xeu nfs-server
# View NFS server logs with explanations. Check for export or permission errors
Run `journalctl first. Read the actual error before guessing.
Common pitfalls
The mount command returns Connection refused when the firewall blocks NFS ports or rpcbind is not running on the server. Check the firewall rules and ensure rpcbind is enabled.
The mount succeeds but you get Permission denied when writing files. This is usually SELinux. Check the context of the exported directory. Ensure it is nfs_t. Check journalctl -t setroubleshoot for denial messages.
The mount fails with Stale file handle. This happens when the server reboots or the export configuration changes while the client has the share mounted. Unmount and remount the share on the client.
The system hangs at boot waiting for the NFS mount. The _netdev option is missing from /etc/fstab. Add _netdev to the options field. For complex setups, consider using x-systemd.automount to mount the share on first access rather than at boot.
The exportfs command fails with exportfs: /etc/exports [1]: Neither 'subtree_check' or 'no_subtree_check' specified. The export line is malformed. Check the syntax. Options must be in parentheses immediately after the client specification.
When to use NFS versus alternatives
Use NFS when you need high-performance file sharing between Linux systems on a trusted network. Use Samba when you need to share files with Windows or macOS clients. Use SSHFS when you need secure file access over untrusted networks without configuring a server. Use iSCSI when you need block-level storage access for databases or virtual machines. Stay on NFSv4 when you want automatic ID mapping and better security. Stay on NFSv3 only when you must support legacy clients that lack NFSv4 support.
Snapshot the system before the upgrade. Future-you will thank you.