[Linux] How to setup NFS Server on RHEL 8

Jack Kim
10 min readApr 21, 2022

Network File System (NFS) is a distributed file system protocol originally developed by Sun Microsystems (Sun) in 1984, allowing a user on a client computer to access files over a computer network much like local storage is accessed. NFS, like many other protocols, builds on the Open Network Computing Remote Procedure Call (ONC RPC) system. NFS is an open IETF standard defined in a Request for Comments (RFC), allowing anyone to implement the protocol. — wikipedia.org

Table of contents

  1. Install NFS RPM files
  2. Start and Enable the “nfs-server” service
  3. Manage SELinux for NFS service
  4. Configuring SELinux and Firewall
  5. Create an NFS (/home/usershare) share for the user
  6. Check NFS (/home/usershare) configuration for the user
  7. Mount NFS(/home/usershare) directory in the client1
  8. Create an NFS (/home/groupshare) share for the group
  9. Check NFS(home/groupshare) configuration for the group
  10. Mount NFS(/home/groupshare) directory in the client1
  11. Unmounting NFS File Systems
  12. Automatically mounting NFS File Systems with /etc/fstab

Troubleshooting #1 — “RPC: Port mapper failure” message

Troubleshooting #2 — “Permission denied” message

Troubleshooting #3 — “device is busy” message

1. Install NFS RPM files

  • Install nfs-utils and nfs4-acl-tools RPMs
# yum install -y nfs-utils nfs4-acl-tools
  • Check installed nfs-utils and nfs4-acl-tools RPMs
# rpm -ql nfs-utils | egrep "mount|nfsstat" | grep bin
/sbin/mount.nfs
/sbin/mount.nfs4
/sbin/umount.nfs
/sbin/umount.nfs4
/usr/sbin/mountstats
/usr/sbin/nfsstat
/usr/sbin/rpc.mountd
/usr/sbin/showmount
# rpm -ql nfs4-acl-tools | grep acl | grep bin
/usr/bin/nfs4_editfacl
/usr/bin/nfs4_getfacl
/usr/bin/nfs4_setfacl

2. Start and Enable the “nfs-server” service

  • Start the “nfs-server” service
# systemctl status nfs-server.service
● nfs-server.service - NFS server and services
Loaded: loaded (/usr/lib/systemd/system/nfs-server.service; disabled; vendor preset: disabled)
Active: inactive (dead)
# systemctl start nfs-server
  • Enable the “nfs-server” service
# systemctl enable nfs-server
Created symlink /etc/systemd/system/multi-user.target.wants/nfs-server.service → /usr/lib/systemd/system/nfs-server.service.
  • Check the “nfs-server” service
# systemctl status nfs-server
● nfs-server.service - NFS server and services
Loaded: loaded (/usr/lib/systemd/system/nfs-server.service; enabled; vendor preset: disabled)
Active: active (exited) since Thu 2022-04-21 12:17:13 PDT; 43s ago
Main PID: 2147936 (code=exited, status=0/SUCCESS)
Tasks: 0 (limit: 35096)
Memory: 0B
CGroup: /system.slice/nfs-server.service

3. Manage SELinux for NFS service

  • Check the selinux configuration
# sestatus
SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted
Current mode: enforcing
Mode from config file: enforcing
Policy MLS status: enabled
Policy deny_unknown status: allowed
Memory protection checking: actual (secure)
Max kernel policy version: 33
# ps -eZ | egrep "nfs|rpc"
system_u:system_r:kernel_t:s0 563 ? 00:00:00 rpciod
system_u:system_r:rpcbind_t:s0 881 ? 00:00:00 rpcbind
system_u:system_r:rpcd_t:s0 892 ? 00:00:00 rpc.idmapd
system_u:system_r:unconfined_service_t:s0 893 ? 00:00:00 nfsdcld
system_u:system_r:rpcd_t:s0 1310 ? 00:00:00 rpc.statd
system_u:system_r:nfsd_t:s0 1340 ? 00:00:00 rpc.mountd
system_u:system_r:kernel_t:s0 1348 ? 00:00:00 nfsiod
system_u:system_r:kernel_t:s0 1407 ? 00:00:00 nfsd
system_u:system_r:kernel_t:s0 1409 ? 00:00:00 nfsd
system_u:system_r:kernel_t:s0 1410 ? 00:00:00 nfsd
system_u:system_r:kernel_t:s0 1411 ? 00:00:00 nfsd
system_u:system_r:kernel_t:s0 1412 ? 00:00:00 nfsd
system_u:system_r:kernel_t:s0 1413 ? 00:00:00 nfsd
system_u:system_r:kernel_t:s0 1414 ? 00:00:00 nfsd
system_u:system_r:kernel_t:s0 1415 ? 00:00:00 nfsd
  • Check the /etc/exports file of selinux
# ls -lZ /etc/exports
-rw-r--r--. 1 root root system_u:object_r:exports_t:s0 0 Sep 10 2018 /etc/exports

4. Configuring SELinux and Firewall

  • Set the “nfs_export_all_ro” and “nfs_export_all_rw” value to “on”.
# setsebool -P nfs_export_all_ro on
# setsebool -P nfs_export_all_rw on
  • Check the SELinux boolean value
# getsebool -a | grep nfs_export_all
nfs_export_all_ro --> on
nfs_export_all_rw --> on
  • Add “mountd”, “rpc-bind”, and “nfs” service in the firewalld
# firewall-cmd --permanent --add-service mountd
success
# firewall-cmd --permanent --add-service rpc-bind
succes
# firewall-cmd --permanent --add-service nfs
success
  • Reload firewalls service
# firewall-cmd --reload
success
  • Check RPC ports
# rpcinfo -p
program vers proto port service
100000 4 tcp 111 portmapper
100000 3 tcp 111 portmapper
100000 2 tcp 111 portmapper
100000 4 udp 111 portmapper
100000 3 udp 111 portmapper
100000 2 udp 111 portmapper
100024 1 udp 42480 status
100024 1 tcp 60487 status
100005 1 udp 20048 mountd
100005 1 tcp 20048 mountd
100005 2 udp 20048 mountd
100005 2 tcp 20048 mountd
100005 3 udp 20048 mountd
100005 3 tcp 20048 mountd
100003 3 tcp 2049 nfs
100003 4 tcp 2049 nfs
100227 3 tcp 2049 nfs_acl
100021 1 udp 52563 nlockmgr
100021 3 udp 52563 nlockmgr
100021 4 udp 52563 nlockmgr
100021 1 tcp 44961 nlockmgr
100021 3 tcp 44961 nlockmgr
100021 4 tcp 44961 nlockmgr

5. Create an NFS (/home/usershare) share for the user

  • Create a /home/usershare directory
# mkdir /home/usershare
# ls -lZ /home/
total 0
drwx------. 3 jack jack unconfined_u:object_r:user_home_dir_t:s0 92 Aug 12 2021 jack
drwxr-xr-x. 2 root root unconfined_u:object_r:user_home_dir_t:s0 6 Apr 21 12:39 usershare
  • Change the owner and group from root to jack user
# id jack
uid=1000(jack) gid=1000(jack) groups=1000(jack)
# chown jack:jack /home/usershare
# ls -lZ /home/

total 0
drwx------. 3 jack jack unconfined_u:object_r:user_home_dir_t:s0 92 Aug 12 2021 jack
drwxr-xr-x. 2 jack jack unconfined_u:object_r:user_home_dir_t:s0 6 Apr 21 12:39 usershare
  • Open the /etc/exports file with your text editor and add the following line to the file
# grep client1 /etc/hosts
192.168.16.211 client1
# vim/etc/exports
/home/usershare client1(rw)
  • Reexport all directories and synchronizing /var/lib/nfs/etab with /etc/exports.
# ping -c 3 client1# exportfs -avr
exporting client1:/home/usershare

6. Check NFS(/home/usershare) share for the user

# cat /var/lib/nfs/etab
/home/usershare client1(rw,sync,wdelay,hide,nocrossmnt,secure,root_squash,no_all_squash,no_subtree_check,secure_locks,acl,no_pnfs,anonuid=65534,anongid=65534,sec=sys,rw,secure,root_squash,no_all_squash)
# grep 65534 /etc/passwd
nobody:x:65534:65534:Kernel Overflow User:/:/sbin/nologin
# grep -i nfs /etc/passwd
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin

7. Mount NFS(/home/usershare) directory in the client1

  • Log into client1
# ssh client1
  • Check nfs-utils and nfs4-acl-tools RPMs in the client1
# rpm -qa | grep ^nfs
nfs-utils-1.3.0-0.68.el7.x86_64
nfs4-acl-tools-0.3.3-21.el7.x86_64
  • Check a list of exported directories in the client1
# grep server /etc/hosts
192.168.16.210 server
# ping -c 3 server# showmount -e server
Export list for server:
/home/usershare client1
  • Create /home/usershare directory in the client1
# mkdir /home/usershare
  • Mount NFS (/home/usershare) directory in the client1
# mount -t nfs server:/home/usershare /home/usershare
  • Check mounted NFS directory in the client1
# mount | grep nfs
sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw,relatime)
server:/home/usershare on /home/usershare type nfs4 (rw,relatime,vers=4.1,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=192.168.16.211,local_lock=none,addr=192.168.16.210
# df -hT
Filesystem Type Size Used Avail Use% Mounted on
devtmpfs devtmpfs 1.8G 0 1.8G 0% /dev
tmpfs tmpfs 1.8G 0 1.8G 0% /dev/shm
tmpfs tmpfs 1.8G 19M 1.8G 1% /run
tmpfs tmpfs 1.8G 0 1.8G 0% /sys/fs/cgroup
/dev/sda3 xfs 888G 8.6G 880G 1% /
/dev/sda1 xfs 1014M 184M 831M 19% /boot
tmpfs tmpfs 369M 40K 369M 1% /run/user/1000
tmpfs tmpfs 369M 0 369M 0% /run/user/0
server:/home/usershare nfs4 425G 416G 9.4G 98% /home/usershare

8. Create an NFS(/home/groupuser) share for the group

  • Create a new user (user name: kelly)
# useradd kelly
# id kelly

uid=1001(kelly) gid=1001(kelly) groups=1001(kelly)
# passwd kelly
Changing password for user kelly.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
  • Create a new group (group name:eit)
# groupadd -g 6000 eit
  • Add a new group(eit) to users (jack and kelly)
# usermod -a -G eit jack
# id jack

uid=1000(jack) gid=1000(jack) groups=1000(jack),6000(eit)
# usermod -a -G eit kelly
# id kelly

uid=1001(kelly) gid=1001(kelly) groups=1001(kelly),6000(eit)
# grep eit /etc/group
eit:x:6000:jack,kelly
  • Create a /home/groupshare directory
# mkdir /home/groupshare
  • Change the owner and group from root:root to nobody:eit
# id nobody
uid=65534(nobody) gid=65534(nobody) groups=65534(nobody)
# chown nobody:eit /home/groupshare
  • Set set-gid bit on the /home/groupshare directory
# chmod 2770 /home/groupshare# ls -ldZ /home/groupshare
drwxrws---. 2 nobody eit unconfined_u:object_r:user_home_dir_t:s0 6 Apr 22 12:26 /home/groupshare
  • Open the /etc/exports file with your text editor and add the following line to the file
# vim /etc/exports
/home/usershare client1(rw)
/home/groupshare client1(rw,no_root_squash)
  • Reexport all directories and synchronizing /var/lib/nfs/etab with /etc/exports.
# exportfs -avr
exporting client1:/home/groupshare
exporting client1:/home/usershare

9. Check NFS(/home/groupshare) configuration for the group

# cat /var/lib/nfs/etab
/home/groupshare client1(rw,sync,wdelay,hide,nocrossmnt,secure,no_root_squash,no_all_squash,no_subtree_check,secure_locks,acl,no_pnfs,anonuid=65534,anongid=65534,sec=sys,rw,secure,no_root_squash,no_all_squash)
/home/usershare client1(rw,sync,wdelay,hide,nocrossmnt,secure,root_squash,no_all_squash,no_subtree_check,secure_locks,acl,no_pnfs,anonuid=65534,anongid=65534,sec=sys,rw,secure,root_squash,no_all_squash)

10. Mount /home/grouphare directory in the client1

  • Log into client1
# ssh client1
  • Create a new user (user name: kelly) in the client1
# useradd kelly
# id kelly

uid=1001(kelly) gid=1001(kelly) groups=1001(kelly)
# passwd kelly
Changing password for user kelly.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
  • Create a new group (group name:eit) in the client1
# groupadd -g 6000 eit
  • Add a new group(eit) to users (jack and kelly) in the client1
# usermod -a -G eit jack
# id jack

uid=1000(jack) gid=1000(jack) groups=1000(jack),6000(eit)
# usermod -a -G eit kelly
# id kelly

uid=1001(kelly) gid=1001(kelly) groups=1001(kelly),6000(eit)
# grep eit /etc/group
eit:x:6000:jack,kelly
  • Check a list of exported directories in the client1
# showmount -e server
Export list for server:
/home/groupshare client1
/home/usershare client1
  • Create /home/groupshare directory in the client1
# mkdir /home/groupshare
  • Mount NFS (/home/groupshare) directory in the client1
# mount -t nfs server:/home/groupshare /home/groupshare
  • Check mounted NFS directory in the client1
# mount | grep nfs
sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw,relatime)
server:/home/usershare on /home/usershare type nfs4 (rw,relatime,vers=4.1,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=192.168.16.211,local_lock=none,addr=192.168.16.210
server:/home/groupshare on /home/groupshare type nfs4 (rw,relatime,vers=4.1,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=192.168.16.211,local_lock=none,addr=192.168.16.210)
# df -hT
Filesystem Type Size Used Avail Use% Mounted on
devtmpfs devtmpfs 1.8G 0 1.8G 0% /dev
tmpfs tmpfs 1.8G 0 1.8G 0% /dev/shm
tmpfs tmpfs 1.8G 19M 1.8G 1% /run
tmpfs tmpfs 1.8G 0 1.8G 0% /sys/fs/cgroup
/dev/sda3 xfs 888G 8.6G 880G 1% /
/dev/sda1 xfs 1014M 184M 831M 19% /boot
tmpfs tmpfs 369M 40K 369M 1% /run/user/1000
tmpfs tmpfs 369M 0 369M 0% /run/user/0
server:/home/usershare nfs4 425G 416G 9.4G 98% /home/usershare
server:/home/groupshare nfs4 425G 416G 9.4G 98% /home/groupshare
  • Create a test file in the /home/groupshare directory
# su - jack$ id jack
uid=1000(jack) gid=1000(jack) groups=1000(jack),10(wheel),6000(eit)
$ touch /home/groupshare/test1.file
$ ls -l /home/groupshare/test1.file

-rw-rw-r--. 1 jack eit 0 Apr 22 15:04 /home/groupshare/test1.file

11. Unmounting NFS File Systems

  • Run the “umount” command followed by either the directory where it has been mounted or the remote share
# umount /home/usershare
# umount server:/home/groupshare

12. Automatically mounting NFS File Systems with /etc/fstab

  • Open the /etc/fstab file with your text editor
# vim /etc/fstab
  • Add the following line to the /etc/fstab file
server:/home/usershare  /home/usershare      nfs     defaults 0 0
server:/home/groupshare /home/groupshare nfs defaults 0 0
  • Run the “mount” command with the ‘-a’ option
# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 1.8G 0 1.8G 0% /dev
tmpfs 1.8G 0 1.8G 0% /dev/shm
tmpfs 1.8G 19M 1.8G 1% /run
tmpfs 1.8G 0 1.8G 0% /sys/fs/cgroup
/dev/sda3 888G 8.6G 880G 1% /
/dev/sda1 1014M 184M 831M 19% /boot
tmpfs 369M 40K 369M 1% /run/user/1000
tmpfs 369M 0 369M 0% /run/user/0
# mount -a# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 1.8G 0 1.8G 0% /dev
tmpfs 1.8G 0 1.8G 0% /dev/shm
tmpfs 1.8G 19M 1.8G 1% /run
tmpfs 1.8G 0 1.8G 0% /sys/fs/cgroup
/dev/sda3 888G 8.6G 880G 1% /
/dev/sda1 1014M 184M 831M 19% /boot
tmpfs 369M 40K 369M 1% /run/user/1000
10.93.16.10:/global 1.9T 1.5T 411G 78% /global
tmpfs 369M 0 369M 0% /run/user/0
server:/home/usershare 425G 416G 9.4G 98% /home/usershare
server:/home/groupshare 425G 416G 9.4G 98% /home/groupshare

Troubleshooting #1 — “RPC: Port mapper failure” message

Issue: “RPC: Port mapper failure” message

[client ~]# showmount -e server
clnt_create: RPC: Port mapper failure - Unable to receive: errno 113 (No route to host)

Solution: Add the mountd and rpc-bind in the firewalld service

  • Stop the firewalld server in the server
[server ~]# systemctl stop firewalld
  • Check it in the client
[client ~]# showmount -e server
Export list for server:
/home/usershare client1
  • Add the mountd and rpc-bind in the firewalld service
[server ~]# systemctl start firewalld[server ~]# firewall-cmd --permanent --add-service mountd
success
[server ~]# firewall-cmd --permanent --add-service rpc-bind
success
[server ~]# firewall-cmd --reload
success
  • Check it in the client
[client ~]# showmount -e server
Export list for server:
/home/usershare client1

Troubleshooting #2 — “Permission denied” message

Issue: “Permission denied”

[client ~]# touch /home/usershare/file1.txt
touch: cannot touch ‘/home/usershare/file1.txt’: Permission denied
  • Check the /home/usershare directory permission
[server ~]# ls -ld /home/usershare/
drwxr-xr-x. 2 jack jack 6 Apr 21 12:39 /home/usershare/

Solution: Change /home/usershare directory permission

[server ~]# chmod 777 /home/usershare/
[server ~]# ls -ld /home/usershare/
drwxrwxrwx. 2 jack jack 6 Apr 21 12:39 /home/usershare/
  • Check it in the client
[client ~]# touch /home/usershare/file1.txt

Solution2: The /home/usershare directory set the NFS group configuration

Troubleshooting #3 — “device is busy” message

Issue: “device is busy” message

# umount /home/groupshare
umount.nfs4: /home/groupshare: device is busy
  • Check the /home/groupshare directory via fuser command
# fuser -vm /home/groupshare/
USER PID ACCESS COMMAND
/home/groupshare: root kernel mount /home/usershare
jack 16798 ..c.. bash

Solution1: Run the “umount” command with “-l’ option

  • -l, — lazy
    Lazy unmount. Detach the filesystem from the file hierarchy
    now, and clean up all references to this filesystem as soon as
    it is not busy anymore.

    A system reboot would be expected in near future if you’re going
    to use this option for network filesystem or local filesystem
    with submounts. The recommended use-case for umount -l is to
    prevent hangs on shutdown due to an unreachable network share
    where a normal umount will hang due to a downed server or a net‐
    work partition. Remounts of the share will not be possible.
# umount -l /home/groupshare
# df -h

Filesystem Type Size Used Avail Use% Mounted on
devtmpfs devtmpfs 1.8G 0 1.8G 0% /dev
tmpfs tmpfs 1.8G 0 1.8G 0% /dev/shm
tmpfs tmpfs 1.8G 19M 1.8G 1% /run
tmpfs tmpfs 1.8G 0 1.8G 0% /sys/fs/cgroup
/dev/sda3 xfs 888G 8.6G 880G 1% /
/dev/sda1 xfs 1014M 184M 831M 19% /boot
tmpfs tmpfs 369M 40K 369M 1% /run/user/1000
tmpfs tmpfs 369M 0 369M 0% /run/user/0
server:/home/usershare nfs4 425G 416G 9.4G 98% /home/usershare

Solution2: Run the “fuser” command with “-km” option

  • -k, — kill
    Kill processes accessing the file. Unless changed with -SIGNAL, SIGKILL is sent. An fuser process never kills
    itself, but may kill other fuser processes. The effective user ID of the process executing fuser is set to its
    real user ID before attempting to kill.
  • -m NAME, — mount NAME
    NAME specifies a file on a mounted file system or a block device that is mounted. All processes accessing files on
    that file system are listed. If a directory file is specified, it is automatically changed to NAME/. to use any
    file system that might be mounted on that directory.
# fuser -km /home/groupshare
/home/groupshare: 16798c
# umount /home/groupshare# df -hT
Filesystem Type Size Used Avail Use% Mounted on
devtmpfs devtmpfs 1.8G 0 1.8G 0% /dev
tmpfs tmpfs 1.8G 0 1.8G 0% /dev/shm
tmpfs tmpfs 1.8G 19M 1.8G 1% /run
tmpfs tmpfs 1.8G 0 1.8G 0% /sys/fs/cgroup
/dev/sda3 xfs 888G 8.6G 880G 1% /
/dev/sda1 xfs 1014M 184M 831M 19% /boot
tmpfs tmpfs 369M 40K 369M 1% /run/user/1000
tmpfs tmpfs 369M 0 369M 0% /run/user/0
server:/home/usershare nfs4 425G 416G 9.4G 98% /home/usershare

Reference site

If you liked the article, please click the follow button.

--

--