Using NFS over TLS

This procedure shows how to mount an NFS share over a Transport Layer Security (TLS) channel on systems that run either RHEL 9 / Rocky Linux 9 or Ubuntu 24.04 LTS.

1. Prerequisites

  • A server that exports an NFS share and supports RFC 9289 - Towards Remote Procedure Call Encryption by Default.
  • The kernel needs to be new enough to have been built with CONFIG_NET_HANDSHAKE=y. Examples: RHEL 9.x or upstream kernel 6.7 and above.
  • Access to certificates that the client will trust (either a private CA certificate or the server certificate itself)

2. Install the required packages

RHEL 9 / Rocky Linux 9

sudo dnf install nfs-utils ktls-utils

The ktls-utils package delivers tlshd, the user‑space handshake daemon that enables kTLS.

Ubuntu 24.04 LTS

sudo apt update
sudo apt install nfs-common ktls-utils (>= 0.11)

If your mirror does not yet carry version 0.11 or later, download the package manually:

wget -4 https://archive.ubuntu.com/ubuntu/pool/universe/k/ktls-utils/ktls-utils_0.11-1_amd64.deb
sudo dpkg -i ktls-utils_0.11-1_amd64.deb

3. Enable the tlshd handshake daemon

sudo systemctl enable --now tlshd.service

Verify that the service is active:

systemctl --no-pager status tlshd

4. Provide certificates

The client must present a certificate chain that it trusts. Use one of the following options:

Option A — use an existing Enterprise CA

  1. Copy the CA certificate that signed the NFS server’s certificate to the client.
  2. Continue with Section 5.

Option B — generate a private CA and a server certificate (lab use)

WARNING: Self‑signed certificates are suitable only for testing. Use a trusted CA in production environments.

# Create a private CA (valid for 10 years)
openssl req \
  -x509 -nodes -new -sha256 -days 3650 \
  -newkey rsa:2048 \
  -keyout RootCA.key \
  -out   RootCA.crt \
  -subj  "/CN=Demo‑Root‑CA"

# Create a server key and CSR (replace with real FQDN / IP)
openssl req \
  -new -nodes -newkey rsa:2048 \
  -keyout server.key \
  -out   server.csr \
  -subj  "/CN=nfs.example.com"

cat > domains.ext <<'EOF'
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage=digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment
subjectAltName=DNS:nfs.example.com,IP:192.0.2.10
EOF

# Sign the CSR with the private CA (valid for ~3 years)
openssl x509 -req -in server.csr \
  -CA RootCA.crt -CAkey RootCA.key -CAcreateserial \
  -out server.crt -days 1024 -sha256 -extfile domains.ext

NOTE: subjectAltName field must contain DNS names / IP addressees of server, used by client during connection establishing.

Copy RootCA.crt (or server.crt if you pinned only the server certificate) to the client.

5. Configure tlshd

Edit /etc/tlshd.conf and set the path to the certificate or trust store that you copied in the previous step. For example:

[authenticate.client]
x509.truststore=/etc/pki/ca-trust/source/anchors/RootCA.crt

NOTE: On Ubuntu, place the file in /usr/local/share/ca-certificates/ and run sudo update-ca-certificates.

Reload the daemon:

sudo systemctl restart tlshd.service

6. Mount the NFS share over TLS

  1. Create a mount point:

    sudo mkdir -p /mnt/nfs_tls
    
  2. Mount the share. Replace nfs.example.com:/export with your export path:

    sudo mount -o xprtsec=tls nfs.example.com:/export /mnt/nfs_tls
    

    The -o xprtsec=tls option tells the NFS client to negotiate a kTLS session with the server via tlshd.

To make the mount persistent, add an entry to /etc/fstab:

nfs.example.com:/export  /mnt/nfs_tls  nfs4  xprtsec=tls  0  0

7. Verify the TLS session

Run ss or nfsstat and check that the connection uses tls:

ss -tna | grep nfs

A line similar to the following confirms that the mount is encrypted:

ESTAB 0 0 192.0.2.100:915 192.0.2.10:2049 tls

8. Troubleshooting

SymptomPossible causeResolution
mount returns permission deniedThe client does not trust the server certificateVerify that the correct CA / certificate is listed in tlshd.conf and restart tlshd
mount hangstlshd is not runningStart the service with systemctl enable --now tlshd

9. Additional resources

  • man nfs
  • man tlshd

Document generated on 2025.11.10 10:07 for v4.5.2~prerelease-1-g37d710094, branch 4.5