For some time now, I have been working on how to set up a Single Sign-On (SSO) solution in my company. As a big fan of Open Source solutions, I have obviously proposed the implementation of a solution based on Kerberos. What I mean by that is a solution based on the true Kerberos, i. e. MIT Kerberos. Indeed, Kerberos was originally a research project at the Massachusetts Institute for Technology (MIT) in the early 1980s.

Before starting this kind of project, it’s important to clearly define and have in mind the following points:

  • Architecture of the enterprise
  • Operating systems used by end users
  • Operating systems used by applications which must be kerberized
  • Is it difficult to kerberized these applications?

The answers to these elements provide insight on which types of solutions are possible. For example if there is no restrictions on which operating system an end user can use (Windows or different Linux distribution or …) then the introduction of a solution based on a Linux Kerberos could be a good idea. That’s why in this blog, I will first explain how to install a MIT Kerberos Server. In the second part, I will focus on how to manage this Server.

1. Install MIT Kerberos

It’s important to note that the server and the client share the same release and that the MIT Keberos server could only be installed on a Unix-like. The Mac release is available as part of the Mac OS X since version 10.3 (the current release is Mavericks: 10.9). The Key Distribution Center (KDC) is the Kerberos Server where all identities (users, computers and kerberized applications) will be stored.

For this installation, let’s define the followings properties/variable:

  • example.com = the DNS Domain
  • EXAMPLE.COM = the KDC REALM which should be the DNS Domain in UPPERCASE. In case where there should be more than one KDC, all names must be unique and self descriptive
  • kdc01oel.example.com = the FQDN of the KDC
  • 192.168.1.2 = the IP of kdc01oel.example.com

So let’s begin the installation. Obviously, the first thing to do is to download the current release of the MIT Kerberos distribution for the target operating system. This could be done at the following URL: http://web.mit.edu/kerberos/dist/index.html. The current Linux release is krb5-1.12.1-signed.tar:

[root@oel opt]# wget http://web.mit.edu/kerberos/dist/krb5/1.12/krb5-1.12.1-signed.tar
--2014-04-01 14:00:28--  http://web.mit.edu/kerberos/dist/krb5/1.12/krb5-1.12.1-signed.tar
Resolving web.mit.edu... 23.58.214.151
Connecting to web.mit.edu|23.58.214.151|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 11950080 (11M) [application/x-tar]
Saving to: “krb5-1.12.1-signed.tar”
100%[===============================================>] 11,950,080  1.52M/s   in 7.3s
2014-04-01 14:00:38 (1.56 MB/s) - “krb5-1.12.1-signed.tar” saved [11950080/11950080]
[root@oel opt]# tar -xvf krb5-1.12.1-signed.tar
krb5-1.12.1.tar.gz
krb5-1.12.1.tar.gz.asc

 

As you could see, this file is signed and you could (should) verify the integrity and identity of the software. This can be done, for example, using GNU Privacy Guard (need another file that can be found on the MIT Kerberos download page):

[root@oel opt]# gpg --verify krb5-1.12.1.tar.gz.asc

 

After that, just extract the MIT Kerberos source code and build it:

[root@oel opt]# tar -zxf krb5-1.12.1.tar.gz
[root@oel opt]# cd krb5-1.12.1/src/
[root@oel src]# ./configure
...
[root@oel src]# yum install *yacc*
...
[root@oel src]# make
...
[root@oel src]# make install
...

 

At this step, Kerberos should be installed properly and the binaries, libraries and the documentation should be under /usr/local. The default location is sufficient in almost all cases:

[root@oel src]# krb5-config --all
Version:     Kerberos 5 release 1.12.1
Vendor:      Massachusetts Institute of Technology
Prefix:      /usr/local
Exec_prefix: /usr/local

As Kerberos should be installed properly, the next step is to configure it. This is done through a configuration file named krb5.conf:

[root@oel src]# vi /etc/krb5.conf
[libdefaults]
  default_realm = EXAMPLE.COM
  forwardable = true
  proxiable = true
[realms]
  EXAMPLE.COM = {
    kdc = kdc01oel.example.com:88
    admin_server = kdc01oel.example.com:749
    default_domain = example.com
  }
[domain_realm]
  .example.com = EXAMPLE.COM
  example.com = EXAMPLE.COM
[logging]
  kdc = FILE:/var/log/krb5kdc.log
  admin_server = FILE:/var/log/kadmin.log
  default = FILE:/var/log/krb5lib.log

 

To avoid hostname resolution issues, the file /etc/hosts must contain the fully qualified domain name of the server as well as the IP address:

[root@oel src]# vi /etc/hosts
127.0.0.1         localhost   kdc01oel
192.168.1.2       kdc01oel.example.com   kdc01oel

 

The next thing to do is to create the realm and the KDC database. Let’s begin with the creation of the database parent folder:

[root@oel src]# cd /usr/local
[root@oel local]# mkdir /usr/local/var
[root@oel local]# mkdir /usr/local/var/krb5kdc
[root@oel local]# chmod 700 /usr/local/var/krb5kdc

 

The file krb5.conf (just above) is the generic Kerberos configuration file but the KDC also has is own configuration file (kdc.conf). Create this file and populate it as follow:

[root@oel local]# cd /usr/local/var/krb5kdc/
[root@oel krb5kdc]# vi kdc.conf
[kdcdefaults]
  kdc_ports = 749,88
[realms]
  EXAMPLE.COM = {
    database_name = /usr/local/var/krb5kdc/principal
    admin_keytab = /usr/local/var/krb5kdc/kadm5.keytab
    acl_file = /usr/local/var/krb5kdc/kadm5.acl
    key_stash_file = /usr/local/var/krb5kdc/.k5.EXAMPLE.COM
    kdc_ports = 749,88
    max_life = 10h 0m 0s
    max_renewable_life = 7d 0h 0m 0s
  }

 

So let’s create the Kerberos database using this configuration file:

[root@oel krb5kdc]# /usr/local/sbin/kdb5_util create -s
Loading random data
Initializing database '/usr/local/var/krb5kdc/principal' for realm 'EXAMPLE.COM',
master key name 'K/[email protected]'
You will be prompted for the database Master Password.
It is important that you NOT FORGET this password.
Enter KDC database master key: 
Re-enter KDC database master key to verify:
[root@oel krb5kdc]#

 

If there is any error at this point, it is certainly due to a misconfiguration of the /etc/krb5.conf file or because Kerberos can’t resolve the hostname (the /etc/hosts file isn’t configure properly).

This finaly conclude the first part about the installation of the MIT Kerberos Server.

2. Manage the KDC

For this part, I assume that the KDC is set up according to what I’ve explain above. In the previous part, I just shown how to install the KDC but in fact the KDC isn’t running for the moment. So the first thing to do is to configure which will be able to connect to the KDC (that mean obtain a ticket) and with which permissions.

To enter to the KDC administration console, use the kadmin.local (only for the local machine):

[root@oel krb5kdc]# /usr/local/sbin/kadmin.local
Authenticating as principal root/[email protected] with password.
kadmin.local:

Once in the kadmin.local, several command can be used to manage the KDC. The following command can be used to list them all:

kadmin.local:  ?
Available kadmin.local requests:
add_principal, addprinc, ank
                         Add principal
delete_principal, delprinc
                         Delete principal
modify_principal, modprinc
                         Modify principal
rename_principal, renprinc
                         Rename principal
change_password, cpw     Change password
get_principal, getprinc  Get principal
list_principals, listprincs, get_principals, getprincs
                         List principals
add_policy, addpol       Add policy
modify_policy, modpol    Modify policy
delete_policy, delpol    Delete policy
get_policy, getpol       Get policy
list_policies, listpols, get_policies, getpols
                         List policies
get_privs, getprivs      Get privileges
ktadd, xst               Add entry(s) to a keytab
ktremove, ktrem          Remove entry(s) from a keytab
lock                     Lock database exclusively (use with extreme caution!)
unlock                   Release exclusive database lock
purgekeys                Purge previously retained old keys from a principal
get_strings, getstrs     Show string attributes on a principal
set_string, setstr       Set a string attribute on a principal
del_string, delstr       Delete a string attribute on a principal
list_requests, lr, ?     List available requests.
quit, exit, q            Exit program.

So for example let’s create two principal. One with administrator capabilities (xxx/admin) and another one without:

kadmin.local:  addprinc mpatou/admin
WARNING: no policy specified for mpatou/[email protected]; defaulting to no policy
Enter password for principal "mpatou/[email protected]": 
Re-enter password for principal "mpatou/[email protected]": 
Principal "mpatou/[email protected]" created.
kadmin.local:  addprinc mpatou
WARNING: no policy specified for [email protected]; defaulting to no policy
Enter password for principal "[email protected]": 
Re-enter password for principal "[email protected]": 
Principal "[email protected]" created.

With a new “listprincs”, the two new principals should be displayed but for now, mpatou/admin has no administrative access because this account isn’t declared in the access control list. In the ACL file, permissions can be defined by using the following characters:

  • A = Addition of users or policies into the KDC database
  • D = Deletion of users or policies from the KDC database
  • M = Modification of users or policies in the KDC database
  • C = Changing principals’ passwords in the KDC database
  • I = Inquiries into the database, to list principal information
  • L = Listing of the principals contained in the database
  • * = Grants the user all of the above permissions

Moreover, the wildcard (*) can be used to match more than one user. For example */admin will match all administrative account. Let’s create the ACL file as define in the KDC configuration file (kdc.conf):

kadmin.local:  exit
[root@oel krb5kdc]# vi /usr/local/var/krb5kdc/kadm5.acl
*/[email protected]        ADMCIL

 

So there is a kadmin.local for local administration but there is also a remote administration console which is kadmin. This remote access can’t be used for now because it need a file that doesn’t exist. This file (a “keytab”), is a file that store a principal and an encryption key derived from the principal’s password. It could be used to log into Kerberos without being prompted for a password and that’s why this is useful for all kerberized applications.

[root@oel krb5kdc]# /usr/local/sbin/kadmin.local
Authenticating as principal root/[email protected] with password.
kadmin.local:  ktadd -k /usr/local/var/krb5kdc/kadm5.keytab kadmin/admin kadmin/changepw
Entry for principal kadmin/admin with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/usr/local/var/krb5kdc/kadm5.keytab.
Entry for principal kadmin/admin with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:/usr/local/var/krb5kdc/kadm5.keytab.
Entry for principal kadmin/admin with kvno 2, encryption type des3-cbc-sha1 added to keytab WRFILE:/usr/local/var/krb5kdc/kadm5.keytab.
Entry for principal kadmin/admin with kvno 2, encryption type arcfour-hmac added to keytab WRFILE:/usr/local/var/krb5kdc/kadm5.keytab.
Entry for principal kadmin/changepw with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/usr/local/var/krb5kdc/kadm5.keytab.
Entry for principal kadmin/changepw with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:/usr/local/var/krb5kdc/kadm5.keytab.
Entry for principal kadmin/changepw with kvno 2, encryption type des3-cbc-sha1 added to keytab WRFILE:/usr/local/var/krb5kdc/kadm5.keytab.
Entry for principal kadmin/changepw with kvno 2, encryption type arcfour-hmac added to keytab WRFILE:/usr/local/var/krb5kdc/kadm5.keytab.
kadmin.local:  exit

The location of this kadm5.keytab is also define in the kdc.conf file. Now the KDC server process is ready to start:

[root@oel krb5kdc]# /usr/local/sbin/krb5kdc
[root@oel krb5kdc]# /usr/local/sbin/kadmind

If there is no error, then the KDC should be running and ready to reply to any client with a valid principal. The easiest way to test it is to try to obtain a TGT (Ticket Granting Ticket) using the kinit command:

[root@oel krb5kdc]# cd /usr/local/bin
[root@oel bin]# klist 
klist: Credentials cache file '/tmp/krb5cc_0' not found
[root@oel bin]# kinit mpatou
Password for [email protected]: 
[root@oel bin]# klist 
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: [email protected]
Valid starting       Expires              Service principal
04/03/2014 09:54:48  04/03/2014 19:54:48  krbtgt/[email protected]
    renew until 04/04/2014 09:54:47
[root@oel bin]# kdestroy
[root@oel bin]# klist 
klist: Credentials cache file '/tmp/krb5cc_0' not found

 

The klist command can be used to list all existing tickets whereas the kdestroy is used to remove them. The KDC is now fully operational and some possible additional steps can be done (e.g. set up slaves KDC).

This finally concludes this blog about how to install a MIT Kerberos Server. If you need more information about Kerberos (MIT or Heimdal or Active Directory implementation), I strongly suggest you to read the book “Kerberos, The Definitive Guide” by Jason Garman. This book was for me the best source of knowledge on this subject.