[Network Administration]: Kerberos Authentication Service

First thing that I need is a system for authentication. This means a method where systems can verify the identity of anything that wants to access services. This is different than authorization, which will determine what services are granted access. I’m just saying services instead of machines since being able to log into a machine does not necessarily mean that the user would have access to every service that a machine can provide. I’ll be using a system developed at MIT called Kerberos.

Previously, I’ve used an LDAP directory for both authentication and authorization. This authorization system was based on passwords stored in the LDAP directory itself. There are also local machine accounts which are not located in the LDAP directory, but for our sake, I’m looking at a method to authenticate users and services across the entire network. Even after setting up Kerberos, there are still local accounts on machines. Kerberos also has some nice features in that it is secure, and allows for single sign-on. As an additional service it provides mutual authentication, but this is less important to me as the local network that I’m on is pretty tightly controlled. Traffic compliant to the kerberos protocol is encrypted and doesn’t send passwords through the network. Single sign-on means that a user will only have to prove their identity once when they first log onto the network, and afterwards their credentials are passed around the network. Mutual authentication means that not only are servers assured the identity of clients, but also in the other direction. Clients are assured that servers are also who they claim to be.

There are some good resources out there. I used Kerberos: The Definitive Guide which I found on Amazon for $1. There are also pages which describe setting up Kerberos services on Ubuntu Linux servers both in the LTS official documentation and on the community page. Of course, MIT has a site devoted to Kerberos.

There are some packages that should be installed as a prerequisite to a Kerberos system setup. The first is that Kerberos relies on machines having system times in sync. For ubuntu machines the package is ntp. Other machines are set up differently. Another requirement is that machines need to have their hostnames both forward and reverse resolvable. This means that hostnames need to map to IP addresses, and those IP addresses need to map back to their hostnames. This was already taken care of when we had setup our DNS servers..

I’ll be using the MIT release of Kerberos. There are other versions out there. For example, Microsoft’s Active Directory also implements Kerberos, as does Apple’s OS X server. The MIT release is open source, but (maybe?) subject to export controls due the strength of the encryption that’s used. It’s available in Linux packages, and also source downloadable from the MIT Kerberos website. I’ve actually built it from the source package. I’ve got my machine, and ensured that I’ve got the proper DNS entries for the machine, and also added the kdc1 alias to the DNS entries so that I can easily find this machine just by an alias for the service that it provides.

Installing the packages or compiling the source
The binaries and libraries are also available in package form. For Ubuntu, the packages are krb5-kdc and krb5-admin-server. Installing the packages is as simple as:

apt-get install krb5-kdc krb5-admin-server

There is some configuration steps that are done when the package is installed.

To go a different route, the source package is available from MIT here. The package comes with a PGP signature that can be used to verify the integrity of the tarball. Once the package is un compressed and untared, it needs to be configured with the configure command. The package is compiled in the src directory.

cd krb5-<version>/src
./configure <configure flags>

I’ve built mine with these flags

conf_flags      = --prefix=/usr/local \
                  --exec-prefix=/usr/local \
                  --localstatedir=/srv \
                  --sysconfdir=/usr/local/etc \
                  --with-system-verto=no \
                  --enable-dns-for-realm \
                  --enable-shared
# These are no longer options
#                 --without-krb4 \
#                 --enable-dns \
#                 --enable-dns-for-kdc \
#

I used the Linux From Scratch Kerberos guide for looking at the compile flags. I’ve compiled mine to be installed to /usr/local since I’m compiling this as a separate package to be installed on this machine in particular. I did give a non-default location for the localstatedir configure flag to put the Kerberos database under the /srv partition of my machine. Also, I want to use shared libraries, which means that I can updated them as needed without recompiling the Kerberos source from scratch each time. I don’t need Kerberos V4 support, but it looks like it’s not an option anymore. It also seems like it’s enabled DNS now.

Once I’ve configured the build, you just build it:

make

This part takes a while. Go have a beer.

Once, it’s compiled, there is a make target that allows for testing the build. It needs to have a YACC package installed on the machine. I’ve used bison as my YACC parser. The testing target is called check. For more extensive testing, it requires TCL and some other packages which I didn’t want to install. It’ll still test what it can, but will skip the parts that it can’t verify with a warning message.

sudo apt-get install bison
make check

Once it’s tested, it can be installed. I use check install to install packages that I’ve compiled myself. It creates essentially a package that you can manage with dpkg like other debian packages. It also allows me to insert the compile flags into the package description so that I can keep track of how the packages were built. The install target is install

make install

The install step will install the files determined by the prefix flags during configuration. The binaries are found at ${exec-prefix}/bin and ${exec-prefix}/sbin. The configuration files are expected to be under ${sysconfdir}. The install target will not create the state directory under the location defined by the variable ${localstatedir}. We’ll have to create this ourselves. It expects a directory called krb5kdc for the KDC’s data.

install -v -dm700 -o root -g root /srv/krb5kdc

This will create the directory, set the owner:group to root:root, and give it owner read/write/execute permissions only, and revoke everything else.

At this point the daemons should be able to start up. To get them to start up automatically at boot time, I added an Upstart script for both the KDC and the Admin Server. The Ubuntu packages come with the old style init.d scripts, but since those are being deprecated, and they are pretty simple, I just went with the newer system.

/etc/init/krb5-kdc.init – KDC upstart init script:

# Kerberos service script

description "MIT Kerberos KDC"
author "admin@example.com"

# Stanzas
#
#

# When to start the service
start on runlevel [2345]

# When to stop the service
stop on runlevel [016]

# Automatically restart the service if crashed
respawn

# Let upstart know that the service will detach itself to the background
expect fork

env KRB5_KDC=/usr/local/sbin/krb5kdc

# Run beforehand
pre-start script
  test -x $KRB5_KDC || { stop; exit 0; }
end script
 

# Start the service
exec $KRB5_KDC

/etc/init/krb5-admin-server.init – Kadmin server Upstart init script:

# Kerberos service script

description "MIT Kerberos Admin Server"
author "admin@example.com"

# Stanzas
#
#

# When to start the service
start on runlevel [2345]

# When to stop the service
stop on runlevel [016]

# Automatically restart the service if crashed
respawn

# Let upstart know that the service will detach itself to the background
expect fork

env KRB5_ADMIN_SERVER=/usr/local/sbin/kadmind

# Run beforehand
pre-start script
  test -x $KRB5_ADMIN_SERVER || { stop; exit 0; }
end script
 

# Start the service
exec $KRB5_ADMIN_SERVER

Configuring the Services
If the package is installed, it will create a krb5.conf file which is used to describe the Kerberos realm. If the source was compiled, then this will need to be created. The one generated by the package install is found at /etc/krb5.conf. If the source was compiled, it will expect it located at ${sysconfdir}/.krb5.conf.

krb5.conf:

[libdefaults]
        default_realm = EXAMPLE.COM

[realms]
        EXAMPLE.COM = {
                kdc = kdc1.internal.example.com:88
                admin_server = kdc1.internal.example.com:749
                default_domain = example.com
        }

[domain_realm]
        example.com = EXAMPLE.COM
        .example.com = EXAMPLE.COM

[logging]
        kdc = FILE:/var/log/krb5/krb5kdc.log
        admin_server = FILE:/var/log/krb5/kadmin.log
        default = FILE:/var/log/krb5/krb5lib.log

This file is going to be used also for the clients in some form. This is the documentation for this file from the MIT site. It has four parts.

[libdefaults]
        default_realm = EXAMPLE.COM

This part sets the default realm used if there isn’t one specified.

[realms]
        EXAMPLE.COM = {
                kdc = kdc1.internal.example.com:88
                admin_server = kdc1.internal.example.com:749
                default_domain = example.com
        }

These are the realms that the server, and values that are defined per realm. We define a KDC and an administration server for our realm. In my case, I’ve stated that both the KDC and the admin server are on the same machine, kdc1.internal.example.com.

[domain_realm]
        example.com = EXAMPLE.COM
        .example.com = EXAMPLE.COM

I’ve also mapped the domains to the realm. This is fairly straight forward, I’ve mapped my entire domain to the realm.

[logging]
        kdc = FILE:/var/log/krb5/krb5kdc.log
        admin_server = FILE:/var/log/krb5/kadmin.log
        default = FILE:/var/log/krb5/krb5lib.log

This contains some logging information. I’ve specified logging locations, giving the KDC, the admin server, and the rest separate files to write to.

Setting up the realms
At this point it’s pretty much at the same point as if you installed the packages, but the KDC still needs to be configured. The KDC configuration file is located at <code</etc/krb5kdc/kdc.conf if the package was installed, or at ${localstatedir}/krb5kdc/kdc.conf if it was compiled.

kdc.conf:

[kdcdefaults]
        kdc_ports = 88,750

[realms]
        EXAMPLE.COM = {
                database_name = /srv/krb5kdc/principal
                admin_keytab = /usr/local/etc/krb5kdc/kadm5.keytab
                acl_file = /usr/local/etc/krb5kdc/kadm5.acl
                dict_file = /usr/local/etc/krb5kdc/kadm5.dict
                key_stash_file = /srv/krb5kdc/.k5.EXAMPLE.COM
                kadmind_port = 749
                max_life = 10h 0m 0s
                max_renewable_life = 7d 0h 0m 0s
                master_key_type = des3-hmac-sha1
                supported_enctypes = aes256-cts:normal arcfour-hmac:normal des3-hmac-sha1:normal des-cbc-crc:normal des:normal des:v4 des:norealm des:onlyrealm des:afs3
                default_principal_flags = +preauth
        }

This file configures the KDC. It has documentation on the MIT website, or on the man page.

[kdcdefaults]
        kdc_ports = 88,750

These are the default ports that KDC listens on. Kerberos uses port 88, and historically Kerberos V4 uses 750. Port 750 could probably be removed if only Kerberos V5 is implemented.

[realms]
        EXAMPLE.COM = {
                database_name = /srv/krb5kdc/principal
                admin_keytab = /usr/local/etc/krb5kdc/kadm5.keytab
                acl_file = /usr/local/etc/krb5kdc/kadm5.acl
                dict_file = /usr/local/etc/krb5kdc/kadm5.dict
                key_stash_file = /srv/krb5kdc/.k5.FOODCLAW.NET
                kadmind_port = 749
                max_life = 10h 0m 0s
                max_renewable_life = 7d 0h 0m 0s
                master_key_type = des3-hmac-sha1
                supported_enctypes = aes256-cts:normal arcfour-hmac:normal des3-hmac-sha1:normal des-cbc-crc:normal des:normal des:v4 des:norealm des:onlyrealm des:afs3
                default_principal_flags = +preauth
        }

These define the behavior for the realm. A number of the file locations are defined here including the database location, and some configuration files. Also defined is the kadmin port at port 749. This with the ports listed above means that Kerberos opens ports 88, 749, and 750. I set my time limits for tickets, and the supported encryption types. I enable preauthorization with the default_principal_flags. When I first wrote the kdc.conf file, I used the values from the O’Reilly Kerberos book, but that gave me a number of errors when reading the configuration file until I updated it to the values that come with the Ubuntu package.

Setup the acl file for access control

# This file Is the access control list for krb5 administration.
# When this file is edited run /etc/init.d/krb5-admin-server restart to activate
# One common way to set up Kerberos administration is to allow any principal 
# ending in /admin  is given full administrative rights.
# To enable this, uncomment the following line:
*/admin *

The first “*” will match any principal with "/admin" at the end of the principal name. Convention is that admin accounts have "/admin" at the end. The second “*” means that the admin has full rights. There is more detail here.

Now I can create my realm.

# /usr/local/sbin/kdb5_util create -s

Loading random data
Initializing database '/var/lib/krb5kdc/principal' for realm 'EXAMPLE.COM',
master key name 'K/M@EXAMPLE.COM'
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: 

At this point, the domain should be created and a number of principals created

# kadmin.local
Authenticating as principal root/admin@EXAMPLE.COM with password.
kadmin.local:  listprincs
K/M@EXAMPLE.COM
kadmin/admin@EXAMPLE.COM
kadmin/server1.internal.example.com@EXAMPLE.COM
kadmin/changepw@EXAMPLE.COM
krbtgt/EXAMPLE.COM@EXAMPLE.COM

We’ll add a user principal. You can get the documentation for kadmin from the MIT web site.

kadmin.local:  addprinc user1
WARNING: no policy specified for user1@EXAMPLE.COM; defaulting to no policy
Enter password for principal "user1@EXAMPLE.COM": 
Re-enter password for principal "user1@EXAMPLE.COM": 
Principal "user1@EXAMPLE.COM" created.

Now we can start our services and we should be able to get a kerberos ticket.

# service krb5-kdc start
 * Starting Kerberos KDC krb5kdc                                                                                                                         [ OK ] 
# service krb5-admin-server start
 * Starting Kerberos administrative servers kadmind                                                                                                      [ OK ] 
# kinit user1
Password for user1@EXAMPLE.COM: 
# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: user1@EXAMPLE.COM

Valid starting       Expires              Service principal
07/21/2015 13:38:12  07/21/2015 23:38:12  krbtgt/EXAMPLE.COM@EXAMPLE.COM
	renew until 07/22/2015 13:38:09

Configuration and Data Backup
I backup the directories /usr/local/etc/krb5.conf and /srv/krb5kdc. The general configuration file is stored in /usr/local/etc/krb5.conf and the KDC configuration files and database are stored in /srv/krb5kdc. I should be able to fully recreate my server with the configuration directory in the backup once the binaries are rebuild and re-installed.

Advertisements

5 thoughts on “[Network Administration]: Kerberos Authentication Service

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s