Automating Kerberos Authentication

Sometimes you need unattended authentication. Sometimes you are just lazy. Whatever the reason, if a user (human or otherwise) wants to fetch a Ticket Granting Ticket (TGT) from a Kerberos Key Distribution Center (KDC) automatically, the Global Security Services API (GSSAPI) library shipped with most recent distributions support it.

Kerberos is based on symmetric cryptography. If a user needs to store a symmetric key in a filesystem, she uses a file format known as a Key table, or keytab for short. Fetching a keytab is not a standard action, but FreeIPA has shipped with a utility to make it easier: ipa-getkeytab

Before I attempt to get a keytab, I want to authenticate to my KDC and get a TGT manually:

$ kinit ayoung@YOUNGLOGIC.NET
Password for ayoung@YOUNGLOGIC.NET: 
$ klist
Ticket cache: KEYRING:persistent:14370:krb_ccache_H4Ss9cA
Default principal: ayoung@YOUNGLOGIC.NET
 
Valid starting       Expires              Service principal
05/01/2015 09:07:06  05/02/2015 09:06:55  krbtgt/YOUNGLOGIC.NET@YOUNGLOGIC.NET

To fetch a keytab and store it in the users home directory, you can run the following command. I’ve coded it to talk to my younglogic.net KDC, so modify it for yours.

ipa-getkeytab -p $USER@YOUNGLOGIC.NET -k $HOME/client.keytab -s ipa.younglogic.net

You can get your own principal from the klist output:

export KRB_PRINCIPAL=$(klist | awk '/Default principal:/ {print $3}')

If you are running on an ipa-client enrolled machine, much of the info you need is in /etc/ipa/default.conf.

$ cat   /etc/ipa/default.conf
#File modified by ipa-client-install
[global]
basedn = dc=younglogic,dc=net
realm = YOUNGLOGIC.NET
domain = younglogic.net
server = ipa.younglogic.net
host = rdo.younglogic.net
xmlrpc_uri = https://ipa.younglogic.net/ipa/xml
enable_ra = True

You can convert these values into environment variables with:

 $(awk '/=/ {print "export IPA_" toupper($1)"="$3}' < /etc/ipa/default.conf)

Now a user could manually kinit using that keytab and the following commands:

$(awk '/=/ {print "export IPA_" toupper($1)"="$3}' < /etc/ipa/default.conf)
kinit -k -t $HOME/client.keytab $USER@$IPA_REALM

We can skip the kinit step by putting the keytab in a specific location. If you look in the man page for krb5.conf you can find the following section:

default_client_keytab_name
This relation specifies the name of the default keytab for obtaining client credentials. The default is FILE:/var/kerberos/krb5/user/%{euid}/client.keytab. This relation is subject to parameter expansion

What is %{euid}? It is the numeric userid for a user. For yourself, the value is set in $EUID. What if you need it for a different user? Use the getent command to configure the name service switch configured database for this value:

$ getent passwd ayoung
ayoung:*:622800001:622800001:Adam Young:/home/ayoung:/bin/sh

It is that third value. Again, if you want to automate:

export AYOUNG_EUID=getent passwd ayoung | cut -d: -f3

You need to create that directory before you can put something in it. You only want the user to be able to read or write in that directory.

sudo mkdir  /var/kerberos/krb5/user/$EUID
sudo chown $USER:$USER  /var/kerberos/krb5/user/$EUID 
chmod 700  /var/kerberos/krb5/user/$EUID

Now use that to store the keytab:

 ipa-getkeytab -p $KRB_PRINCIPAL -k   /var/kerberos/krb5/user/$EUID/client.keytab -s $IPA_SERVER

To test out the new keytab, kdestroy to remove the existing TGTS then try performing an action that would require a service ticket.

Here I show an initially cleared credential cache that gets automatically populated when I connect to a remote system via ssh.

$ kdestroy -A
$  klist -A 
$ ssh -K rdo.younglogic.net Last login: Fri May  1 16:42:28 2015 from c-1-2-3-4.imadethisup.net -sh-4.2$ exit logout Connection to rdo.younglogic.net closed. 
$ klist -A Ticket cache: KEYRING:persistent:14370:krb_ccache_WotXvlm Default principal: ayoung@YOUNGLOGIC.NET Valid starting       Expires              Service principal 05/01/2015 12:42:46  05/02/2015 12:42:45  host/rdo.younglogic.net@YOUNGLOGIC.NET 05/01/2015 12:42:46  05/02/2015 12:42:45  host/rdo.younglogic.net@ 05/01/2015 12:42:45  05/02/2015 12:42:45  krbtgt/YOUNGLOGIC.NET@YOUNGLOGIC.NET

I would not recommend doing this for normal users. But for service users that need automated access to remote services, this is the correct approach.

10 thoughts on “Automating Kerberos Authentication

  1. Really nice article and Blog, thanks !
    I had the same objective – allow some services to access kerberized storage servers – and solved it using k5start, a daemon version of kinit for Kerberos v5. (from EPEL repository) It seems it gets to the same point with much less efforts. It’s also able to renew tickets at a predetermined intervall.
    Also be aware that requesting a keytab for a principal will reset it, i.e. a user principal password will no longer be valid for example.

  2. THAAAAAAAAAAANKSSSSSS! You helped me soooo muuuuch!
    I write here down my steps if anyone will face with this issue like me!

    I added credential to file:
    #ktutil
    #ktutil: addent -password -p administrator@SKUNKWORKS.LOCAL -k 1 -e RC4-HMAC
    Password for administrator@SKUNKWORKS.LOCAL:
    #ktutil: wkt username.keytab
    #ktutil: q
    And try it out
    kinit administrator@SKUNKWORKS.LOCAL -k -t username.keytab

    but this is working only with AD users!
    Your way helped me to do it with local ipa users. Yes, I read the doc but I did not understood it well.

    So, thanks again!

  3. FYI .. If you don’t have ipa, you can do this on a windows box to get a usable keytab for an AD user:

    ktpass /princ username@MYDOMAIN.COM /pass password /ptype KRB5_NT_PRINCIPAL /out username.keytab

  4. Adam,

    Is it possible to authenticate via SSH, to an ipa registered client with an rsa public key, and at authentication time, renew, or retrieve a new (if expired) kerberos ticket, for accessing a kerberized service like an automounted NFS home directory? Perhaps via modification to pam?

    I’m using the kernel keyring, and the public key comes from a smart card.

    The idea here being that the private key is loaded via an agent on a trusted workstation, and the public key used to authenticate via authorizedkeys is the already online, forwardable token of trust, that one needed to authenticate already in order to get.

    Can one obtain a new tgt for the user principle, if they have a trusted (enrolled in the schema) public ssh rsa key? Is it possible?

    Thanks.

  5. I’d suggest you ask in the FreeIPA IRC. There is a lot of PKI/Kerberos integration, but I am not up on the particulars. I think the use case you suggest is supported. It sounds like a PKINIT variation, but I am not sure.

  6. Hi,
    I have tried above steps its working fine but it is not working with HDFS
    what I need to do to work with HDFS as well.?
    out Hadoop cluster is kerberos authenticated

    Thank you in Advance

  7. There is not nearly enough information for me to say here. I suspect that what you have happening is a conflict between the ticket you use to authenticate and the ticket used to perform some work. But this blog is really not the forum for a debugging session.

  8. Hi Adam,
    As I mentioned in my previous comment we have a Hadoop cluster with Kerberos authentication.so when I implemented the above steps for automating authentication and then run hdfs dfs -ls / command on a Hadoop cluster. it fails with no valid token found authentication failed.

    Let me know if you require more information

    Best Regards,
    RM

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.