Cron jobs on Kerberized NFS

Jurjen Bokma

November 2013, last updated: november 2019


How to give a cron job access to an NFS share that is protected by Kerberos.

Table of Contents

We have a system where $HOME is on NFS, protected by Kerberos. When the user logs in, they type a password, and obtain Kerberos credentials - a ticket, giving access to $HOME. But when cron starts a job for the user, it doesn't type a password. So access to $HOME is denied to cron jobs.

We can give cron access to $HOME by creating a keytab file. This keytab is worth a password in that whoever can read it can do anything the user could do to $HOME.

  1. In the case of Heimdal Kerberos:

    apprentice@host:~$ ktutil --keytab=/tmp/keytab.krb-username add -p krb-username --enctype=aes256-cts-hmac-sha1-96 --kvno=1

    Or in the case of MIT Kerberos:

    apprentice@host:~$ ktutil
    ktutil:  add_entry -password -p p123456 -k 1 -e aes256-cts-hmac-sha1-96
    Password for p123456@MYDOMAIN>COM: 
    ktutil:  write_kt /tmp/keytab.p123456
    ktutil:  quit
    jurjen@haytabo:~$ ls -trl /tmp/keytab.p123456
    -rw------- 1 apprentice apprentice 80 Nov 11 11:15 /tmp/keytab.p123456

    In either case, you will be asked for a password (twice with Heimdal). If you mistype, you will not receive a warning, but the keytab won't work.

  2. Don't put the keytab in $HOME if $HOME is what it unlocks!

    Ensure tight permissions on the keytab. It can be used as a password after all.

  3. Destroy any existing credentials:

    apprentice@host:~$ kdestroy

    ... before trying to use the keytab for Kerberos authentication.

    With Heimdal:

    apprentice@host:~$ kinit -t /tmp/keytab.krb-username krb-username ls $HOME

    Or with MIT:

    apprentice@host:~$ kinit -kt /tmp/keytab.p123456  p123456
    apprentice@host:~$ ls -l $HOME

  4. Heimdal offers this:

    * *  * * *  kinit -t /tmp/keytab.krb-username krb-username

    I.e. runs as a child of kinit.

    With MIT, this construction is impossible. Instead, the kinit command must be inside the script.


    You cannot do this:

    * *  * * *  kinit -t /tmp/keytab.krb-username krb-username < $HOME/myinput > $HOME/myoutput

    ... because if you did, cron would start a shell, arrange the redirection of stdin and stdout, and only then would it start kinit. Thus, the shell would wait for I/O forever, lacking permission, and never get to the kinit part. It doesn't matter that kinit would later proceed to get the very permission its parent is waiting for. It just never gets to that point. To make matters worse, cron would start many of these processes, and none would ever finish.

    Permission on $HOME is only available to kinit itself and its children. So you have to arrange the redirection inside itself.


Although Active Directory is 'case agnostic', it may be necessary here to use the precise principal name that is in the AD LDAP. So not 'Krb-Username' if AD thinks it is 'KRB-USERNAME'.