Name: ~parafin/linux/nfs4krb5
Summary: why and how to switch from AUTH_SYS (AUTH_UNIX) to RPCSEC_GSS security for NFS version 4 mounts
Author: parafin
Created: Thu, 08 Sep 2011 15:17:25 GMT
Last update: Thu, 19 Mar 2015 17:23:27 GMT by parafin
Atom feed
Modify access level: moderator

NFSv4 with Kerberos security

This is a guide about setting up Kerberos authentication for NFSv4 exports. It is assumed that you already have working NFSv4 server and client setup and no Kerberos infrastructure.

Important: Change EXAMPLE.COM to your domain name in upper case, server.example.com to server's FQDN, client.example.com to client's FQDN and user to your login. Make sure that DNS is working properly (those hostnames should resolve to IPs and back to the same names) or else mount will probably fail to determine the right principle names. Check both IPv4 and IPv6 (if you have it).

Why?

Default sec=sys provides host authentication only via IP address, which in our era is close to no security at all. User authentication is even worse, it's lacking completely - client can put any UID and GID in NFS packets. Besides these security implications there's one more reason to switch to sec=krb5 - complete support for user ID mapping. While NFSv4 introduced rpc.idmapd daemon, which maps UID/GID to names and back (so that names will be used in NFS protocol), this is only applied to file attributes, not permission checking or setting owner for new files. For example, if you have accounts both on the client and the server with the same user and group names, but with different numbers corresponding to them, then ls will show the same names on server and client, but if user will touch some file on remote share, it will be created with the same UID/GID, which will correspond to different names. It's quite annoying and unexpected.

Installing necessary packages

Basically what you need is nfs-utils with Kerberos support and MIT Kerberos server and utilities. In Gentoo just enable kerberos USE flag and run emerge nfs-utils.

Kernel configuration

Besides obvious "NFS client/server support for NFS version 4" you will need only one more kernel config option enabled to get Kerberos support (both on server and client): "Secure RPC: Kerberos V mechanism" (CONFIG_RPCSEC_GSS_KRB5). I've seen some reports saying that this option has to be compiled as a module, but my experience is that it works fine when linked directly into kernel image too.

Configuring Kerberos server

There are just 3 config files - one generic Kerberos settings for the machine, and two is for so-called KDC. Here they go:

/etc/krb5.conf
[libdefaults]
        default_realm = EXAMPLE.COM

[realms]
        EXAMPLE.COM = {
                admin_server = server.example.com
                kdc = server.example.com
        }
/var/lib/krb5kdc/kdc.conf
[realms]
        EXAMPLE.COM = {
                database_name = /var/lib/krb5kdc/principal
                admin_keytab = FILE:/var/lib/krb5kdc/kadm5.keytab
                acl_file = /var/lib/krb5kdc/kadm5.acl
                key_stash_file = /var/lib/krb5kdc/.k5.EXAMPLE.COM
                max_life = 10h 0m 0s
                max_renewable_life = 7d 0h 0m 0s
                default_principal_flags = +preauth
        }
/var/lib/krb5kdc/kadm5.acl
*/admin *

After creating these files, run kdb5_util -r EXAMPLE.COM create -s

Then you have to create necessary principles:

Run as root
kadmin.local -q "addprinc user" #this command will ask to set password
kadmin.local -q "addprinc root/admin" #optional, only needed for remote administration of Kerberos database
kadmin.local -q "addprinc -randkey nfs/client.example.com"
kadmin.local -q "addprinc -randkey nfs/server.example.com"
kadmin.local -q "ktadd nfs/server.example.com"
kadmin.local -q "ktadd -k /root/krb5.client.keytab nfs/client.example.com"

Configuration is done, now we need to start Kerberos daemons and add them to auto-start. On gentoo run /etc/init.d/mit-krb5kdc start; /etc/init.d/mit-krb5kadmind start; rc-update add mit-krb5kadmind default; rc-update add mit-krb5kdc default.

Configuring Kerberos client

On client machine you'll just need to copy from server /etc/krb5.conf and /root/krb5.client.keytab renaming it to /etc/krb5.keytab (you can delete /root/krb5.client.keytab after that).

Configuring NFSv4 server

You will need rpc.svcgssd running on server (besides rpc.idmapd). On Gentoo run /etc/init.d/rpc.svcgssd start; rc-update add rpc.svcgssd default. Then you'll have to add sec= option to /etc/exports file. There are 3 variants of Kerberos support in NFSv4: krb5 - just authentication, krb5i - also sign the data (integrity protection), krb5p - encrypt everything (privacy protection). You can list them separated by colons in the order of preference (beginning with the most preferred). If you want to keep support for Kerberos-less mounts add to this list also sys. Here's example:

/etc/exports
/export -sec=krb5:sys,rw,async,no_root_squash,no_subtree_check,fsid=root client.example.com

After changing exports list you'll of course need to reload it. On Gentoo run /etc/init.d/nfs reload.

Configuring NFSv4 client and testing

You need rpc.gssd daemon on client machine. On Gentoo run /etc/init.d/rpc.gssd start; rc-update add rpc.gssd default. Now everything is ready for a successful mount: mount -t nfs4 -o sec=krb5 server:/ /mnt/nfs4krb5/. For user to have access to NFS share, he needs to obtain Kerberos ticket first. Just run kinit and provide password. Be aware that this ticket has limited lifetime after which it becomes invalid. You can check expiration time with klist command. To update ticket run kinit again.

no_root_squash

If you're using no_root_squash option for exporting your NFS shares, you will notice that it has stopped working. The reason for that can be found in man rpc.gssd (see description of -n option). If you don't want to create another Kerberos principle for root, you can just make a small change to /etc/idmapd.conf on server and restart rpc.svcgssd (be aware though that there seems to be some caching of ID mappings in kernel, so re-exporting/re-mounting or some waiting will probably be needed for changes to take effect).

/etc/idmapd.conf
#this section you should have already had
[General]
Domain = example.com
#following sections are the changed ones
[Translation]
GSS-Methods = static,nsswitch
[Static]
nfs/client.example.com@EXAMPLE.COM = root

How to automate Kerberos ticket obtaining and refreshing for user (password-less NFS)

If you want to emulate Kerberos-less NFS, which didn't require user to run any additional commands periodically or provide some additional password for access to NFS share, here's how you can do it. First, export user key kadmin.local -q "ktadd -k /root/krb5.user.keytab -norandkey user" (-norandkey option leaves password you've entered when creating user principle active, if you don't need it, you can leave this option out), then copy it to your homedir on client machine (I suggest renaming it to ~/.krb5.keytab and removing world-read permissions). After that you can run kinit -k -t ~/.krb5.keytab user@EXAMPLE.COM to obtain ticket without entering password (network access to server is still needed though). Run this command every hour via cron and you are done with headache-free setup.

Links