So about two weeks ago I
started playing
with Kerberos. And I'm still not finished with it, kerberizing one
service after the other. Really fun, that.
Kerberizing a network protocol involves somehow sending the Kerberos
ticket in-band with the rest of the conversation. This is not entirely
defined by the Kerberos protocol, and indeed, different network
protocols have come up with different ways of sending the Kerberos
ticket to the service. So far, I've encountered SPNEGO for HTTP, GSSAPI
for IMAP and SSH, and SASL for LDAP. It sounds like a complex mess, but
it really isn't; in general, kerberizing a service involves three
steps:
- Installing the Kerberos plugin (if any) for both the server and the
client;
- Generating the service principal, and adding it to a/the keytab;
- Configuring the service so that it knows it can do Kerberos, and so
that it knows how to act when a Kerberos request is sent
Yes, in the cases I've seen it's really that simple. Although I'm
skipping step 0 here–reading the documentation. But I've done that
for you already ;-)
The hardest part is the initial setup. But even that isn't very hard,
because the process is very well documented. For starters, install the
krb5-doc package, and read the excellent
/usr/share/doc/krb5-doc/README.KDC which explains just enough
of the system to get you started. The rest will be explained to you
through debconf and the like; and if you want more, the
krb5-doc package also contains three info files which explain
concepts and usage very well. There's an alternative implentation called
heimdal, which I presume works similar; but I haven't tried it,
so I don't have much details on that one. The process of installing
krb5 is very straightforward; the only thing I'll let you know
is that you should ensure that any host you're going to kerberize should
have reverse name lookups configured and working correctly; otherwise,
you're going to run into a bunch of serious problems.
After the initial setup, you'll have a Kerberos realm, usually your
domain name in upper case (GREP.BE in my case). You'll now want to set
up principals for your users and principals for your hosts. Now, let me
show you how to configure Kerberos for LDAP, PAM, HTTP, IMAP, and
SSH:
- PAM
- By installing and using the libpam-krb5 package, you'll
log in to kerberos and receive your
TGT immediately at login
time; the alternative would be having to use kinit (in the
krb5-user package) afterwards. pam_krb5.so also takes
care of destroying your tickets when you log out, so that you don't have
to worry about that. This is very handy, but not really required; you
could just use kinit all the time. Of course, using
pam_krb5.so also means you have only one password for
everything—and that is a very good argument to use it.
- Anyway; our three steps:
- Installing the plugin
As you've guessed, libpam-krb5 is the package you'll
need. That, or the heimdal implementation.
- Generating and installing the service principal
In the case of any service such as PAM that will give you a shell
(thus, as we'll see later on, also SSH), the principal is supposed to be
host/<hostname>@<REALM>. For instance, on
rock.grep.be, the principal PAM will use is
host/rock.grep.be@GREP.BE. We'll create it with kadmin (which
can be done on any kerberized host):
wouter@rock:~$ sudo kadmin
Password for root/admin@GREP.BE:
kadmin: addprinc -randkey host/rock.grep.be@GREP.BE
WARNING: no policy specified for host/rock.grep.be@GREP.BE; defaulting to no policy
Principal "host/rock.grep.be@GREP.BE" created.
kadmin: ktadd host/rock.grep.be@GREP.BE
Entry for principal host/rock.grep.be@GREP.BE with kvno 3, encryption type Triple DES cbc mode with HMAC/sha1 added to keytab WRFILE:/etc/krb5.keytab.
Entry for principal host/rock.grep.be@GREP.BE with kvno 3, encryption type DES cbc mode with CRC-32 added to keytab WRFILE:/etc/krb5.keytab.
kadmin: q
Generating the principal can really be done as any /admin
user; but as the same isn't true for writing the keytab, I'm using
sudo in the above example to become root.
- Configuring
account required pam_krb5.so ignore_root
auth sufficient pam_krb5.so ignore_root forwardable
password optional pam_krb5.so ignore_root
session optional pam_krb5.so ignore_root
After adding the above lines to the relevant files in
/etc/pam.d, you should log off, then log on again, run 'klist',
and marvel.
If you add the lines to your passwd file as shown above, and don't
remove the pam_unix.so lines, then local passwd-based
authentication will still work. This can be nice if, for
example, the Kerberos server is down, or you're working on a laptop that
isn't always within reach of the Kerberos server. It doesn't do any
harm; the worst that can happen is that at some point you happen to be
on a network where there's a firewall which drops packets on the floor
rather than sending you an ICMP port unreachable; in that case, you need
to wait for the Kerberos login to time out, which takes half a minute or
so (I haven't timed).
- SSH
- Installation
If you're running unstable, you don't need to do anything. The
OpenSSH packages in unstable are all set to understand Kerberos.
If, however, you're running stable, you'll want to replace your
ssh package by the ssh-krb5 package, which is the
regular SSH package plus some patches to enable GSSAPI (read: Kerberos)
authentication.
- Service principal
If you've done the PAM setup above, you're all set; SSH, being a
service which gives you a shell, also uses the host/ service
principal.
- Configuration
Make sure both the server and the client have the
GSSAPIAuthentication option enabled. After you've done so,
restart the server.
- IMAP
- I'm using dovecot as my IMAP
server, which has builtin support for GSSAPI authentication (at least in
unstable; haven't checked stable in this regard).
- Installation
As dovecot comes with everything compiled in, there is no need for
installing extra packages.
- Service principal
You'll need the imap/ principal (e.g.,
imap/rock.grep.be@GREP.BE). Note that the host name which is
found by doing a reverse lookup on the ip of the server is what counts,
not the name of the server as you're using it (so not, e.g.,
imap/imap.grep.be@GREP.BE)
- Configuration
Edit your dovecot.conf, and find the line that starts with
"mechanisms" in the auth default stanza. Make sure it
contains at least the word gssapi. Restart dovecot.
I haven't found a Free (as in speech) IMAP client that supports
GSSAPI authentication. My client of choice, offlineimap,
doesn't seem to support it; mutt doesn't either (unless I'm missing
something); and while thunderbird in unstable is
supposed to support it, I haven't been able to configure it
correctly yet. Probably me. I have, however, been able to verify that it
works by using a non-free software package. Obviously, this
isn't good enough. In addition, I found that horde and imp don't like an
IMAP server that has GSSAPI enabled if they don't, while enabling GSSAPI
in horde requires a PHP extension that isn't packaged in Debian. So I've
disabled it for the time being. Stay tuned.
- LDAP
- Installation
LDAP requires uses SASL for authentication, which doesn't have GSSAPI
modules in the default package; for those, you need the
libsasl2-modules-gssapi-heimdal package.
Attentive readers will have noticed that this package contains the
string heimdal in it, rather than krb5, and that this is not
the same implementation that I've been using previously. Yes, true. But
since there's no libsasl2-modules-gssapi-krb5, and since
Kerberos is, after all, a well-defined protocol, this is not an
issue—except in that you need a bit more diskspace for the
additional libraries.
Note that the modules have to be installed on both the client and the
server.
- Service principal
You need a service principal that starts with ldap/,
obviously followed by the hostname and the realm.
- Configuration
For those people whom you want to allow to authenticate themselves
using Kerberos, make sure they have ' SASL <principal>'
in their userPassword attribute set (e.g., I have
userPassword: SASL wouter@GREP.BE). You can have that in
addition to a regular encrypted password; the userPassword
attribute is a multi-value attribute. Now if you use ldapsearch
or anything similar, it will try to negotiate GSSAPI authentication as
the SASL mechanism. If it doesn't do so, you can force it by adding
-Y GSSAPI to the command line.
- HTTP
- Installation
You need the libapache-mod-auth-kerb or
libapache2-mod-auth-kerb modules on the server. For the client,
you need a browser which has SPNEGO support; Konqueror and Firefox are
two examples of browsers that do.
- Service principal.
The prefix here should be HTTP/. That's right, in upper
case, contrary to previous examples where this wasn't the case.
HTTP is also different in that apache usually isn't running as root.
This is a good thing; however, it does mean that the kerberos
authentication module is unable to read /etc/krb5.keytab. You'll have to
write the service principal to a different keytab for apache; I've used
the -k option to the ktadd command in kadmin to specify the
keytab as /etc/apache2/keytab; I'll assume you do the same.
- Configuration
Something like this, on the server:
<Location /some/URL>
AuthType Kerberos
KrbMethodNegotiate on
Require valid-user
Krb5Keytab /etc/apache2/keytab
</Location>
This will enable SPNEGO authentication; and if SPNEGO authentication
fails for some reason (for example, because the used browser doesn't
support SPNEGO, or because the user isn't logged in to Kerberos), it
will fall back to Basic Authentication.
While the latter is usually a good idea, it's less of a good idea if
you're not using SSL, since then your password would be sent over the
wire in cleartext. Luckily, the basic authentication can be switched
off, by using KrbMethodK5Passwd off. If you go to my webserver logs,
you'll see that you'll get a 401 right away, while the HTTPS version of the
same allows you to try to log in by using basic authentication.
On the client side, if you're using Firefox, you need to go to
about:config, and set the option
network.negotiate-auth.trusted-uris to a string that will
identify the servers that may do SPNEGO authentication in your realm. In
my case, I've set it to grep.be. For konqueror, doing something
similar is not required—it'll do SPNEGO authentication out of the
box.
So, that's what I've got set up on my network currently. Next on the
list: NFS4 kerberos auth (requires updated nfs utilities, which aren't
in Debian yet because of issues with NFS2, IIRC), PostgreSQL (it
does
seem to support it), and finding out if or how I can create
principals can't be used for one authentication scheme or the other.
Phew, that was a long post. I'll stop now.