Imagine you could log on to your workstation in the morning, enter your username and password, and forget about authenticating to any service throughout the day. You’d have been authenticated by the system and could then open your e-mail with, say, Mutt, connect to SSH servers, manipulate a PostgreSQL database table or two, access restricted pages on your Web servers, access NFS shares, and maybe launch an Amanda backup, all without entering your credentials again (nor having them stored in any configuration files). You can, with a system called Kerberos.

Kerberos is a network protocol for authenticating users. It works on the basis of tickets which allow users and services to prove their identities to each other. Very basically, when authenticating to a Kerberos network service, a user enters her password and an encrypted ticket (sans password) is sent to the Kerberos Key Distribution Center (KDC) for validation. If the KDC can decrypt the ticket the user is authenticated and a so-called Ticket Granting Ticket (TGT) is returned to the user’s workstation and cached there for a certain time, typically eight hours. Whenever a user wants to access a service (e.g. a mail server, and LDAP server, etc.) the client obtains an authenticator for the service from the KDC and uses that to prove to the service who he is.

Users of a Kerberos system are organized in a domain called a realm. This realm is typically an all-caps version of your DNS domain but it can differ. Kerberos users are called “principals”, and there are two kinds of principals:

  • user principals are typically associated with a user who has a password with which to decrypt the principal key.
  • service principals have a system-generated key (services read the key from a file called a keytab).

Let’s see a typical session (and I promise I don’t have an SSH key hidden anywhere!):

$ kinit jpm		# obtain a TGT
Please enter the password for jpm@MENS.DE: 

$ klist			# show ticket cache
Kerberos 5 ticket cache: 'API:Initial default ccache'
Default principal: jpm@MENS.DE

Valid Starting     Expires            Service Principal
06/04/12 13:42:36  06/04/12 23:42:32  krbtgt/MENS.DE@MENS.DE
	renew until 06/04/12 13:42:36

$ ldapwhoami		# use a service (here: LDAP)
SASL/GSSAPI authentication started
SASL username: jpm@MENS.DE
SASL data security layer installed.
dn:uid=jpm,ou=users,dc=mens,dc=de	# note

$ ssh	# use another service (SSH)
Last login: Mon Jun  4 13:54:38 2012 from
jpm@kdc-master:~> exit
Connection to closed.

$ klist			# show ticket cache
Kerberos 5 ticket cache: 'API:Initial default ccache'
Default principal: jpm@MENS.DE

Valid Starting     Expires            Service Principal
06/04/12 13:42:36  06/04/12 23:42:32  krbtgt/MENS.DE@MENS.DE
	renew until 06/04/12 13:42:36

06/04/12 13:53:45  06/04/12 23:42:32  ldap/
	renew until 06/04/12 13:42:36

06/04/12 13:54:06  06/04/12 23:42:32  host/
	renew until 06/04/12 13:42:36

Quite a lot happened there:

  1. With kinit I attempt to obtain a Ticket Granting Ticket (TGT) from the KDC. A user will typically have to enter their password at this point to prove they know it. If the KDC cannot be contacted or the password is incorrect, an appropriate diagnostic is issued and the TGT is not retrieved. Note that kinit is a command-line utility: the functionality is usually built-in to graphical login interfaces, obliviating the need to invoke kinit manually. (Even so, kinit is a useful utility for testing or even for switching to a different principal.)
  2. klist displays the content of my ticket cache, which is typically stored in a temporary file. (I’m on a Mac here, which is why the cache name looks a bit different; ignore that.) klist shows me the default principal name (jpm@MENS.DE) and the validity period of the TGT.
  3. I call the first service using ldapwhoami to contact my Kerberos-enabled LDAP server. Note how the LDAP server has translated my principal name to a distinguished name (DN) corresponding to my entry in the directory server.
  4. I then connect with SSH to the specified server. Here again: I promise there’s no SSH public key lying around anywhere! :) The ssh client is forwarding my ticket to the server which authenticates me and lets me log in.
  5. Finally I use klist once again and we see two additions from step #2: we’ve obtained service tickets for the ldap/ and host/ service principals.

A very large number of services support Kerberos either natively or through an interface called GSSAPI, and I’ve mentioned some above already. This makes it relatively easy to kerberize a large part of the Unix/Linux environment we’re typically used to.

As a special case, let me discuss SSH.

SSH is very often used with public keys which allow a user to login to systems without using a password: if a private key on the client machine corresponds to the public key contained in authorized_keys on the server, then the client may connect without a password to the server. This works very well and is extremely useful. However, in large environments it is difficult to manage SSH-key distribution and lockout:

  • If a key gets compromised, it must be removed from all authorized_keys files on all hosts.
  • The same happens if a user wants to roll (i.e. replace) his keys.
  • If a user leaves the organization but you want to keep his /etc/passwd entry, say, because files should still be marked as belonging to that user, you have to remove all keys from all hosts.
  • Public keys on servers can be “forgotten” there.
  • There’s no way to force key rollover.

Kerberos as a central authentication system, mitigates those issues by allowing me to

  • reset a pricipal’s password, an thus the key.
  • force a principal to change her password (regularly or on-demand)
  • implement password quality and password history.
  • delete a principal, whereupon it disappears immediately and everywhere.

Kerberos is relatively easy to set up, and is worth a good look.

Recommended reading: