Problem
After upgrading to UCS 5.2, administrators may observe that the UCR variable nfs/ports=static no longer results in static port assignments for NFS-related services. Despite the variable being configured as documented, services such as rpc.mountd may continue to use dynamically assigned ports.
This behavior differs from UCS 5.0, where static NFS port assignments were automatically applied through the NFS service configuration.
This article explains the root cause, how to verify the issue, and how to implement a workaround to restore static NFS port assignments.
According to the UCR variable documentation, configuring the following setting should enforce static NFS ports:
nfs/ports: static
If this variable is set to 'static', fixed ports are used for the NFS services:
32767 for RPC mounts,
32765/32766 for statd and
32769 for the quota service.
Otherwise the ports are assigned dynamically.
Despite the configuration being present, systems running UCS 5.2 may still assign dynamic ports to rpc.mountd.
netstat -tulpen | grep rpc.mountd
tcp 0 0 0.0.0.0:35401 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:44333 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:57059 0.0.0.0:* LISTEN
tcp6 0 0 :::51221 :::* LISTEN
tcp6 0 0 :::48273 :::* LISTEN
tcp6 0 0 :::37089 :::* LISTEN
udp 0 0 0.0.0.0:38389 0.0.0.0:*
udp 0 0 0.0.0.0:59057 0.0.0.0:*
udp 0 0 0.0.0.0:51186 0.0.0.0:*
udp6 0 0 :::36656 :::*
udp6 0 0 :::41513 :::*
udp6 0 0 :::46866 :::*
The rpc.mountd process is started without any static port parameters:
ps aufx | grep rpc.mountd
root 672 0.0 0.0 5040 436 ? Ss May18 0:00 /usr/sbin/rpc.mountd
The RPC registration confirms dynamically assigned ports:
rpcinfo -p localhost | grep mountd
100005 1 udp 51186 mountd
100005 1 tcp 35401 mountd
100005 2 udp 38389 mountd
100005 2 tcp 44333 mountd
100005 3 udp 59057 mountd
100005 3 tcp 57059 mountd
Environment
- Univention Corporate Server (UCS) 5.2
- Systems running
nfs-kernel-server - Environments requiring static NFS ports for firewall rules, network segmentation, or compliance requirements
Example affected system:
UCS: 5.2-5 errata410
Installed: cups=2.4.2 dhcp-server=16.0 samba4=4.21 squid=5.7 ucsschool=5.2v4 5.0/ucsschool-veyon-proxy=4.9.1.12-ucs1
Upgradable: ucsschool
Root Cause
The behavior is caused by upstream changes in nfs-utils.
The following upstream commit removed the legacy nfs-config.service:
commit 2662e1ba98707014b6167e1e5bd3162d6d8f52af
Author: Neil Brown
Date: Tue Dec 6 13:27:22 2016 -0500
systemd: Remove the nfs-config.service
The changelog explains:
Now that we have /etc/nfs.conf, a lot of configuration can be read directly. So nfs-config isn’t really needed any more.
The upstream documentation further states that distributions relying on environment files should provide dedicated systemd drop-in files to continue passing daemon-specific command-line parameters.
As a consequence, the UCS mechanism that previously supplied UCR-generated values through:
/run/sysconfig/nfs-utils
is no longer consumed by the active service definitions on UCS 5.2. Therefore, parameters such as:
RPCMOUNTDOPTS="--manage-gids --port 32767"
are never passed to rpc.mountd.
Investigation
Comparison with UCS 5.0
The same configuration works as expected on UCS 5.0.
Reference system:
UCS: 5.0-10 errata1362
Installed: collabora-online=24.04.12.4 fetchmail=6.3.26 mailserver=12.0 nextcloud=31.0.9-0 ox-connector=2.3.3 oxseforucs=7.10.6-ucs5
Verification:
ucr search --brief nfs/ports
nfs/ports: static
Listening sockets:
netstat -tulpen | grep rpc.mountd
tcp 0 0 0.0.0.0:32767 0.0.0.0:* LISTEN
tcp6 0 0 :::32767 :::* LISTEN
udp 0 0 0.0.0.0:32767 0.0.0.0:*
udp6 0 0 :::32767 :::*
Process arguments:
ps aufx | grep rpc.mountd
root 716 0.0 0.0 31676 152 ? Ss May19 0:00 /usr/sbin/rpc.mountd --manage-gids --port 32767
RPC registration:
rpcinfo -p localhost | grep mountd
100005 1 udp 32767 mountd
100005 1 tcp 32767 mountd
100005 2 udp 32767 mountd
100005 2 tcp 32767 mountd
100005 3 udp 32767 mountd
100005 3 tcp 32767 mountd
Systemd Unit Comparison
On UCS 5.0 the NFS service unit references the generated runtime configuration:
Wants=nfs-config.service
After=nfs-config.service
EnvironmentFile=-/run/sysconfig/nfs-utils
ExecStart=/usr/sbin/rpc.nfsd $RPCNFSDARGS
The generated runtime file exists:
ls -lah /run/sysconfig/nfs-utils
Output:
-rw-r--r-- 1 root root 159 Dec 19 16:36 /run/sysconfig/nfs-utils
The effective service definition also confirms that runtime arguments are passed to the NFS daemons:
systemctl show nfs-kernel-server -p ExecStart
Output:
ExecStart={ path=/usr/sbin/rpc.nfsd ; argv[]=/usr/sbin/rpc.nfsd $RPCNFSDARGS ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }
On UCS 5.2 the integration is no longer present.
Relevant section of the service unit:
ExecStart=/usr/sbin/rpc.nfsd
Verification:
systemctl show nfs-kernel-server -p ExecStart
Output:
ExecStart={ path=/usr/sbin/rpc.nfsd ; argv[]=/usr/sbin/rpc.nfsd ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }
The generated runtime file is also missing:
ls -lah /run/sysconfig/nfs-utils
Output:
ls: cannot access '/run/sysconfig/nfs-utils': No such file or directory
Workaround
Create a dedicated systemd override for nfs-mountd.service.
Create the Drop-In Directory
mkdir -p /etc/systemd/system/nfs-mountd.service.d
Create the Override Configuration
cat >/etc/systemd/system/nfs-mountd.service.d/ucr.conf <<'EOF'
[Service]
EnvironmentFile=/etc/default/nfs-kernel-server
ExecStart=
ExecStart=/usr/sbin/rpc.mountd $RPCMOUNTDOPTS
EOF
Reload systemd
systemctl daemon-reload
Restart the Service
systemctl restart nfs-mountd
Verification
Verify the RPC registration:
rpcinfo -p localhost | grep mountd
Expected output:
100005 1 udp 32767 mountd
100005 1 tcp 32767 mountd
100005 2 udp 32767 mountd
100005 2 tcp 32767 mountd
100005 3 udp 32767 mountd
100005 3 tcp 32767 mountd
Verify the listening sockets:
netstat -tulpen | grep rpc.mountd
Expected output:
tcp 0 0 0.0.0.0:32767 0.0.0.0:* LISTEN
tcp6 0 0 :::32767 :::* LISTEN
udp 0 0 0.0.0.0:32767 0.0.0.0:*
udp6 0 0 :::32767 :::*
Verify the process arguments:
ps aufx | grep rpc.mountd
Expected output:
/usr/sbin/rpc.mountd --manage-gids --port 32767
References
Upstream nfs-utils changelog:
Relevant upstream change:
commit 2662e1ba98707014b6167e1e5bd3162d6d8f52af
Author: NeilBrown <neilb@suse.com>
Date: Tue Dec 6 13:27:22 2016 -0500
systemd: Remove the nfs-config.service
Now that we have /etc/nfs.conf, a lot of configuration can be
read directly. So nfs-config isn't really needed any more.
Some distributions allow command-line arguments for various
daemons to be set in an environment file (/etc/sysconfig,
/etc/defaults).
Passing these through /etc/nfs.conf is not possible.
Instead, a distro that needs this functionality can create drop-in
files which select the required value. As no commands are given
default arguments by systemd unit files, the drop-in can just add
distro-specific args.
For example
/lib/systemd/system/nfs-mountd.service.d/local.conf
[Service]
EnvironmentFile=/etc/sysconfig/nfs
ExecStart=
ExecStart=/usr/sbin/rpc.mountd $RPCMOUNTDOPTS
Note the need for the empty assignment to remove existing definitions
first.
Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
Conclusion
On UCS 5.2, the UCR variable nfs/ports=static may no longer be sufficient to enforce static NFS port assignments because the legacy nfs-config.service integration from older nfs-utils releases is no longer present. As a result, UCR-generated parameters are not automatically passed to rpc.mountd, causing dynamic port allocation.
Until the integration is adapted to the current upstream architecture, administrators requiring static NFS ports can restore the previous behavior by creating a systemd drop-in that explicitly passes the generated mountd parameters to the service.
This issue is currently tracked by Univention as Bug #59467. For the latest status and implementation progress, please refer to: