This episode secures NFS file sharing with Kerberos: the classic NFS weaknesses that trust IPs and UIDs, creating the nfs service principal, configuring exports with sec=krb5, krb5i, and krb5p, the roles of rpc.gssd and rpc.svcgssd, and troubleshooting when share access fails.

In episode 13 you made SSH part of the single sign-on ecosystem with GSSAPI — every login no longer depends on passwords or scattered keys. Now we lift the same principle to the next layer: file sharing. NFS is the most common way to share storage across Linux networks, and unfortunately its classic version is very easy to fool. This episode connects NFS to Kerberos through three security modes: sec=krb5, sec=krb5i, and sec=krb5p.
If you understood episode 13, half of this episode already feels familiar. The service principal changes from host to nfs, the daemons are different, but the core is the same: a ticket proves who you are, and a keytab proves who the server is.
The classic NFS weakness. Older NFS versions rely on two things that are very easy to forge. First, access is determined by the client's IP address — anyone who can spoof the IP 10.0.0.50 inherits all the rights of that machine. Second, identity is carried as raw UID/GID in the AUTH_SYS protocol; a client can send uid=0 at any time. No encryption, no integrity, and no verification of who the real user is.
The benefits of Kerberized NFS. With GSSAPI, the server checks the Kerberos service ticket presented by the client and proves the identity of the user, not the IP address. Data can also be protected with checksums (integrity) or full encryption (privacy) according to the chosen mode.
Identity mapping. Kerberos calls you by a principal like alice@EXAMPLE.COM, while NFS works with UIDs. That's where identity mapping comes in: a mapping daemon (such as nfsidmap) translates principals to local UID/GID so files can get normal permissions. If alice has no local account with the same UID on both client and server, the result is a mess — a topic that lands in the troubleshooting section.
| Aspect | Classic NFS (AUTH_SYS) | Kerberos NFS (sec=krb5) |
|---|---|---|
| Identity | Raw UID/GID from the client | Principal inside the service ticket |
| Trust | IP address | KDC cryptography |
| Data integrity | None | Optional (krb5i) |
| Encryption | None | Optional (krb5p) |
The first step on the server side is giving NFS an identity on the KDC. Just like the host principal for SSH, NFS uses the special principal nfs/server.example.com:
kadmin.local -q "addprinc -randkey nfs/fileserver.example.com"
kadmin.local -q "ktadd -k /etc/krb5.keytab nfs/fileserver.example.com"Make sure the hostname is the FQDN exactly as the client uses it when mounting — if the client says fileserver only, the requested service ticket is nfs/fileserver, and the KDC answers that no such principal exists. Verify the keytab with klist -k /etc/krb5.keytab, and make sure its permissions allow only root to read it (chmod 600 /etc/krb5.keytab).
Next, configure the exports with the sec= option. This value determines the allowed GSSAPI security mode:
/srv/home 10.0.0.0/24(rw,sync,sec=krb5p)
/srv/public *(ro,sec=krb5)After changing exports, apply with exportfs -ra and check the GSSAPI support daemons. Kerberized NFS needs two daemons: rpc.gssd on the client side and rpc.svcgssd on the server side. rpc.svcgssd is what opens the service ticket to validate incoming requests.
systemctl enable --now rpc-gssd.service rpc-svcgssd.service
systemctl status nfs-server.serviceImportant
The server needs a keytab for all sec=krb5 modes, including the authentication-only ones. Without the nfs/fileserver key in the keytab, every Kerberized mount fails with a message like Server not found in Kerberos database. Always check klist -k after ktadd and make sure the KVNO in the keytab matches the KDC database.
On the client side, the rpc.gssd daemon takes the user's Kerberos credentials and turns them into a GSSAPI context for the mount. Make sure it's running:
systemctl enable --now rpc-gssd.serviceClients generally don't need a keytab for user mounts — rpc.gssd uses the user's TGT from the Kerberos cache. A client keytab is only needed for special scenarios like a boot-time mount by a service, or an NFS mount as root without interaction. If that's what you need, extract the nfs/<client hostname> key into the client keytab.
The mount itself is very simple:
kinit alice
mount -t nfs4 -o sec=krb5p fileserver.example.com:/srv/home /mnt/homeCredential forwarding here means file access follows the user identity, not the machine. When alice does kinit and then mounts, all I/O operations under that mount are authenticated as alice — not as the UID of the client machine. This is very different from classic NFS, where a single machine could claim to be anyone.
These three modes are a spectrum between speed and protection. sec=krb5 only proves identity; sec=krb5i adds a checksum to every RPC so data can't be modified in transit; sec=krb5p encrypts the entire payload — data becomes unreadable to eavesdroppers.
| Mode | Authentication | Integrity | Encryption | Overhead |
|---|---|---|---|---|
sec=krb5 | Yes | No | No | Lightest |
sec=krb5i | Yes | Yes | No | Medium |
sec=krb5p | Yes | Yes | Yes | Heaviest |
Performance considerations. sec=krb5p gives the best security but is the slowest because every RPC (even tiny ones like attribute reads) is subjected to cryptography. For non-sensitive data, sec=krb5 or sec=krb5i makes far more sense. A common strategy: use sec=krb5p for shares containing sensitive data, sec=krb5i for balance, and sec=krb5 when only strong identity is needed. You can also write multiple values in exports, e.g. sec=krb5p:krb5i, and let the client pick the strongest one it supports.
When a mount or file access fails, the first reflex is klist on the client — is there a still-valid TGT? Then check the keytab on the server with klist -k. Some of the most common problems:
1. rpc.gssd logs. Enable verbosity to see the GSSAPI conversation, or check the journal:
journalctl -u rpc-gssd.service -fLook for messages like a failed accept_sec_context or cannot find key for principal — both point to the keytab or KDC.
2. Expired tickets. The NFS service ticket follows the age of the user's TGT. A morning mount can succeed, then stop working at noon when the ticket runs out. The answer is a fresh kinit or enabling a renewal cron / k5start for long sessions. This is the most common cause of "suddenly can't access".
3. Permission and identity mapping problems. The mount succeeds but ls shows nobody. That means the principal was verified, but there's no mapping to a matching local UID. Synchronize UID/GID between client and server (e.g. via LDAP or an identical /etc/passwd) and check nfsidmap -d.
4. Credential cache problems. rpc.gssd uses the Kerberos cache; if the cache is corrupted or uses the KEYRING type that disappears on reboot, the GSSAPI context won't form. Make sure KRB5CCNAME points to a cache readable by the rpc.gssd process.
Tip
Build a sequential diagnostic routine: klist on the client, then klist -k /etc/krb5.keytab on the server, then exportfs -v to make sure sec= has been picked up, and finally the rpc.gssd logs. These four steps cover the majority of problematic NFS Kerberos cases. Quick tips: every new exports configuration must be followed by exportfs -ra, and every new keytab must be followed by a restart of rpc.svcgssd.
This episode closed the biggest security gap in classic NFS: the identity that could be forged through IP and UID is replaced with Kerberos service tickets. You built the nfs/fileserver.example.com service principal, placed its key in the server keytab, configured /etc/exports with sec=krb5, sec=krb5i, and sec=krb5p, activated rpc.gssd and rpc.svcgssd, then debugged failures from daemon logs to identity mapping.
Key takeaways:
sec=krb5 is authentication only, sec=krb5i adds integrity, sec=krb5p adds encryption — choose according to data sensitivity and the overhead you can afford.nfs/server.example.com principal.rpc.gssd.In episode 15 we bring Kerberos to the browser: web authentication with SPNEGO/Negotiate — the mechanism that lets your intranet recognize users without a single password prompt. See you there!