NFSv4 (nfs4) + Kerberos in Debian

Some pointers to getting NFSv4 going with a Kerberos system, perhaps even one similar to LDAP/Kerberos.

Start by installing:

Read through /usr/share/doc/nfs-common/README.Debian.nfsv4. It's a great introduction to this. From here on, it is assumed that you've read this document and may still be struggling to get it going.

Client and Server

Create an nfs Kerberos principal for your client and server machines. This should be in the form of nfs/hostname@REALM. Each host should have a copy of its own key inside /etc/krb5.keytab. For each host, locally run kadmin -p adminuser/admin (adminuser/admin is an admin principal) with the commands:

addpriv -randkey nfs/hostnamename@REALM
ktadd nfs/clientname@REALM

The correct hostname can be found out with the command

getent hosts $(hostname) | awk '{print $1; exit}' | xargs getent hosts | awk '{print $2}'

Please note that the ktadd command invaidates all previously-issued keys reference.

Keytab location for rpc.svcgssd

Check out gssproxy

Before you proceed, please check out gssproxy. It is recommended by upstream and makes this section obsolete.

On servers it may make sense to isolate privileges for different services in separate keytabs stored in /etc/keytab/*. From a security perspective, that can be an improvement over the unified default location in /etc/krb5.keytab. For consistency across machines, you may end up doing so even on your clients.

When using custom keytab locations via the -k switches in /etc/default/nfs-common, the systemd scripts that ship with nfs-utils will still prevent the two services rpc-svcgssd and rpc-gssd from starting. You may have to drop the following statements from those service files:

ConditionPathExists=/etc/krb5.keytab

The GSS services for NFSv4 run as root already, so they are not by themselves a good reason to split up the keytabs. The question arises when you also offer services like LDAP or PostgreSQL.

Keytab location for gssproxy

If you use gssproxy, you may specify the keytab location by incorporating the following snippet into /etc/gssproxy/gssproxy.conf. You may even need this snippet if your keytab is in the default location, i.e., /etc/krb5.keytab.

[service/nfs-server]
mechs = krb5
socket = /run/gssproxy.sock
cred_store = keytab:/etc/krb5.keytab
trusted = yes
kernel_nfsd = yes
euid = 0

Server

There is the myth that one needs to create an export root directory (having fsid=0) and bind all exported directories into it. This works, but the regular exporting as in nfs3 works and is less error-prone. I.e., the command showmount --exports works only without an export root.

Say we wish to expose /home on the server. In your /etc/exports would read:

# 'no_subtree_check' is specified to get rid of warning messages
#    about the default value changing. This is the default value
/home   192.168.1.0/24(rw,sync,no_subtree_check,sec=krb5)

(Replace the network 192.168.1.0/24 according to your desired export configuration. Please note that the older notation "gss/krb5" instead of the network results at least in some situations in errors on the client side about non-existing mount points although "showmount -e" displays them.)

There are three different modes that nfs can operate in with Kerberos, which should be specified in the mount/export options:

Client

On the client side, mount in the following way:

$ mount -t nfs4 -o sec=krb5 nfs4-server.example.com:/home /home

If you don't specify the type, it may fall back on nfs3, which will probably error on you.

Tips

See also