Kerberos for Birds (not dummies)

A basic howto for installing kerberos.

Introduction

This document describes the basics for setting up kerberos. If you are wondering what kerberos is, or how it works, you should read this brief overview

Setting things up

The following describes how to setup the primary and secondary Kerberos Key Distribution Centers on Debian.

Set up the Primary KDC (key distribution center)

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

debconf will open up some dialog boxes for you to fill. You’ll need to set up your “realm” e.g. RISEUP.NET
You can set kerberos v4 compatibility to “none”. You may be asked for the names of your kerberos servers (KDC’s). Ensure that dns resolves them. (also, ensure that your servers’ network time is relatively accurate). Finally, you provide the name of the administrative server: this should be the fqdn of the host you’re working on.

Once the packages are installed, you create your first realm:

krb5_newrealm

You’ll be prompted for a few items, which will be used to create your first krb5.conf file. You will be prompted for a “master password”. You must keep this, but will rarely use it (except, e.g. to set up the secondaries). You can and should edit this after running the command. An example /etc/krb5.conf is this:

[libdefaults]
        default_realm = RISEUP.NET

# The following krb5.conf variables are only for MIT Kerberos.
        krb4_config = /etc/krb.conf
        krb4_realms = /etc/krb.realms
        kdc_timesync = 1
        ccache_type = 4
        forwardable = true
        proxiable = true

# The following encryption type specification will be used by MIT Kerberos
# if uncommented.  In general, the defaults in the MIT Kerberos code are
# correct and overriding these specifications only serves to disable new
# encryption types as they are added, creating interoperability problems.
#
# The only time when you might need to uncomment these lines and change
# the enctypes is if you have local software that will break on ticket
# caches containing ticket encryption types it doesn't know about (such as
# old versions of Sun Java).

#       default_tgs_enctypes = des3-hmac-sha1
#       default_tkt_enctypes = des3-hmac-sha1
#       permitted_enctypes = des3-hmac-sha1

[realms]
        RISEUP.NET = {
                kdc = krb1.riseup.net
                kdc = krb2.riseup.net
                admin_server = krb-admin.riseup.net
                default_domain = riseup.net
        }

[domain_realm]
        riseup.net = RISEUP.NET
        .riseup.net = RISEUP.NET

[login]
        krb4_convert = true
        krb4_get_tickets = false

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

[appdefaults]
        pam = {
                debug = false
                forwardable = true
                krb4_convert = false
                minimum_uid = 100
                renew_lifetime = 36000
                ticket_lifetime = 36000
                banner = Riseup.Net.ID
        }

Test the Primary (admin) server

The first reference suggests the following.

kadmin.local

should get you into a ‘shell’ in which you cah type commands. ‘listprincs’ should give you a list of the default new-realm principals:

K/M@RISEUP.NET
kadmin/admin@RISEUP.NET
kadmin/changepw@RISEUP.NET
kadmin/history@RISEUP.NET
krbtgt/SPINLOCK.HR@RISEUP.NET

kadmin is the admin command. kadmin.local can only be run on the administrative server. kadmin can be run on the secondaries, but (see below for more)…

Edit /etc/krb5kdc/kadm5.acl so that it at least has a line */admin * which allows any ‘admin’ principal to have an administrative role.

Now add an admin user:

kadmin.local:   addprinc  root/admin

You will be asked for the password, and again to confirm. Now, if you run kadmin on a secondary, as ‘root’ you’ll get prompted for that password. ‘quit’ from kadmin.local, and type ‘kadmin’ and use the password. If you run ‘listprincs’ you should see root/admin@RISEUP.NET listed.

Now you can start adding users.

> kadmin
Authenticating as principal root/admin@RISEUP.NET with password.

Password for root/admin@RISEUP.NET: PASSWORD

kadmin:  addprinc micah

WARNING: no policy specified for micah@RISEUP.NET; defaulting to no policy
Enter password for principal "micah@RISEUP.NET": anotherPASSWORD
Re-enter password for principal "micah@RISEUP.NET": anotherPASSWORD
Principal "micah@RISEUP.NET" created.
kadmin:  quit

Note here that the user must already exist, either in /etc/passwd or your ldap or mysql or … backend prior to adding to the kerberos database.

Now, if you edit the following, to include use of kerberos, you’re much of the way there. (of course, apt-get install libpam-krb …)

/etc/pam.d/common-auth

auth sufficient /lib/security/pam_unix.so nullok_secure
auth sufficient /lib/security/pam_krb5.so use_first_pass
auth required   /lib/security/pam_deny.so

/etc/pam.d/common-account

account sufficient  pam_unix.so
account sufficient  pam_krb5.so
account required    pam_deny.so

/etc/pam.d/common-passwd

#password  sufficient   pam_unix.so obscure sha512 min=6 max=12 nullok try_first_pass
password  sufficient   pam_unix.so nullok obscure md5
password  sufficient   pam_krb5.so use_first_pass
password  required     pam_deny.so

/etc/pam.d/common-session

session optional pam_unix.so
session optional pam_krb5.so

Set up secondary server(s)

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

Add the principals for the admin and secondary server(s) (on the admin server).

shell:kadmin

kadmin: addprinc -randkey host/krb-admin.riseup.net
WARNING: no policy specified for "host/krb-admin.riseup.net@RISEUP.NET";
defaulting to no policy.
Principal "host/krb-admin.riseup.net@RISEUP.NET" created.

kadmin: addprinc -randkey host/krb1.riseup.net
WARNING: no policy specified for "host/krb1.riseup.net@RISEUP.NET";
defaulting to no policy.
Principal "host/krb1.riseup.net@RISEUP.NET" created.

kadmin: addprinc -randkey host/krb2.riseup.net
WARNING: no policy specified for "host/krb2.riseup.net@RISEUP.NET";
defaulting to no policy.
Principal "host/krb2.riseup.net@RISEUP.NET" created.

On the admin/master, do the following to extract the keytab:

kadmin:  ktadd host/krb-admin.riseup.net
kadmin: Entry for principal host/krb-admin.riseup.net@RISEUP.NET with
     kvno 1, encryption type DES-CBC-CRC added to keytab
     WRFILE:/etc/krb5.keytab.

Copy the krb5.conf and kdb.conf files from the admin server to the secondary(s).

On the secondary(s), do likewise:

kadmin:  ktadd host/krb1.riseup.net
kadmin: Entry for principal host/krb1.riseup.net@RISEUP.NET with
     kvno 1, encryption type DES-CBC-CRC added to keytab
     WRFILE:/etc/krb5.keytab.

Add a kpropd.acl file containing a list of the admin and slave/secondary servers):

vi /etc/krb5kdc/kpropd.acl

to look something like this:

host/krb1.riseup.net@RISEUP.NET
host/krb2.riseup.net@RISEUP.NET

Then set up the master and secondary(s) for propagating the database. On the secondary/slave:

apt-get install inetutils-inetd  krb5-rsh-server

and ensure that /etc/inetd.conf (or xinetd configs have something like this or analogous:

krb5_prop       stream  tcp     nowait  root    /usr/sbin/kpropd kpropd
eklogin         stream  tcp     nowait  root    /usr/sbin/klogind klogind -k -c -e
kshell          stream  tcp     nowait  root    /usr/sbin/tcpd  /usr/sbin/kshd -5ec

try to propagate. may fail. if so, dump the database, copy, and load.

On the admin/master server, dump the kerberos database, and try to propagate it to the secondary:

kdb5_util  dump /var/lib/krb5kdc/slave_datatrans
kprop -f /var/lib/krb5kdc/slave_datatrans   krb2.riseup.net

If that fails, scp the dump file, slave_datatrans, to the secondary, and manually import it – first you have to create an empty database, and then import….

kdb5_util create -s
kdb5_util load -verbose  /tmp/slave_datatrans

After that, you set up cron jobs to transfer the database from admin/primary to secondary/slave.

Other notes

Kerberos 1.8

In Debian Squeeze, the kerberos version was bumped to 1.8 (MIT Kerberos 1.8). In order to interoperate with older versions, it is necessary to add the following line to your /etc/krb5.conf [libdefaults] section

 allow_weak_crypto = true

and perhaps also

 default_tkt_enctypes = +des DEFAULT
 default_tgs_enctypes = +des DEFAULT
 permitted_enctypes   = +des DEFAULT

The /etc/krb5.conf file

In general, a system will have only one krb5.conf file. What happens if you have some situation where you might need a different version in order to accomplish some task? You can define the environment variable KRB5_CONFIG first:

export KRB5_CONFIG=/etc/some_other_krb5.conf

for that particular task.

The single krb5.conf file is related to one of kerberos’ design/weakness, that a “principal” (user, service, machine) belongs to only one “realm” but we know, that in reality, e.g., a person may belong to more than one.

note
The particular situation faced by me in doing this was that kerberos for user authentication was needed, and users were identified under one realm, but there was also a need for machines/services to be under a separate realm in order to get those services to interact. Now, kerberos does have a way which could deal with this, i.e. setting up a “trust” relation between realms; alternatively, I could have gotten the realm admins to put the machines/services into their realm. But that would have broken DNS differences, which can be fairly critical in the kerberos auth process for machines.

References

Kerberos Howto set up a Primary KDC
Like above, slightly more detailed
Kerberos, Primary and Secondary

see also: Kerberos and nfs4

 

what kind of data store does kerberos use? is it possible to switch this? or perhaps can we add/remove users and permissions via some API?

 
 

It seems to use its own data-store, I’m guessing it is some btree storage format. It contains policies (a simple set of rules about what sort of passwords are legal and how often they need to be refreshed), and principals (a named identifying string within one of the realms served by the KDC and an associated shared or “password”). There is a way to store your kerberos stuff in LDAP, but I think I’ve heard that referred to as like solving a constipation problem with a hole saw.

There are some ways to add/remove/change users using different libraries, for example libkrb5-ruby provides basic Kerberos bindings for ruby which allow authentication, password changes, adding principals, and deleting principals. libauthen-krb5-admin-perl is a perl module that allows creation, deletion, renaming, and examination of Kerberos principals, changing passwords or keys, and changing policy settings in the KDC. I imagine the perl library is more full featured. I know someone who recently used that to translate a list of users and passwords to krb5 principals and keys.

There is also this interesting pam module called libpam-krb5-migrate-heimdal:

 A stackable authentication module that takes a username and password from an
 earlier module in the stack and attempts to transparently add the user to a
 Kerberos realm using the Kerberos 5 kadmin service. The module can be used to
 ease the administrative burdens of migrating a large installed userbase from
 pre-existing authentication methods to a Kerberos-based setup.
 .
 This package allows updating the database of a remote Heimdal server.

Its for Heimdal, which is the Swedish next-generation kerberos implementation that doesn’t have as wide of an adoption base as MIT’s kerberos, so I’m not sure if it would work or not.

 
 

Also note that LDAP + Kerberos = ActiveDirectory, basically. So there has to be some ways to do this. :) It’s a path Koumbit is seeing in the long term.

 
   

I do use LDAP and kerberos at work, but there is also a way to store kerberos stuff inside LDAP, and I have not done that yet(/at-all); not sure I want to. I have read the docs, though.