Kerberos KDC¶
Dependencies¶
In our current configuration, our kdc.conf
lives in AFS. See
file:///afs/acm.jhu.edu/readonly/group/admins.pub/kdc.conf and
The Special Case of admins.pub. As such, the KDCs and kadminds should depend on:
- the local entropy source (e.g. haveged)
- ntpd
- AFS client functionality
Note that depending on AFS does not introduce a circular dependency, as the krb5.conf file is public and the AFS servers do not depend on the KDC to get going.
Using Kadmin¶
Kerberos software seems not to use DNS to resolve admin servers.
Add to /etc/krb5.conf
on any machine from which you want to run
kadmin
at least
[realms]
ACM.JHU.EDU = {
admin_server = kdc1.acm.jhu.edu
}
It should then suffice to run kadmin
(assuming your default realm and
user ID match ours) or kadmin -r ACM.JHU.EDU -p ${YOU}/admin
(if not).
The ACLs for kadmin
are very simple: */admin *
and that’s it.
Please only run kadmin on machines you trust (or that you’re forced to trust); running it on random hosts within the cluster increases the odds that someone will snarf an admin password, and that’d be unfortunate.
Common kadmin tasks: changing a password.¶
Perhaps the most frequent thing we need to do using kadmin is change a user’s password, who has forgotten it. This can be done pretty simply; upon opening kadmin, simply run the following command from inside kadmin:
cpw principal
This will prompt for a password and then set the password for principal
to whatever the user enters.
If you know what you are doing, the optional -pw password
argument
will set the principal’s password to the string “password”. I
strongly suggest you only do this if you are, e.g. using pwgen
to
give a user a temporary password. But really, you shouldn’t be doing
that, since you should only be changing a user’s password when they
are in the room (for hopefully obvious security reasons).
Using Multiple Instances¶
Creating an Instance¶
When users want long-running jobs or noninteractive jobs or other such things, we should give them alternate hats (and keytabs for them) to do that with, since that’s really the right thing to do. (See also User keytabs and maintained tokens. Note that instances are also used for administrative commands; see Administrator Credentials.)
Fire up kadmin, then:
addprinc -randkey username/instancename
ktadd -k /path/to/put/the.keytab username/instancename
and give the user the keytab. Also do:
pts createuser username.instancename
Note the dot instead of a slash for pts.
The user then gives this brand new alternate hat the minimum permissions on the parts of their homedir needed for the job, remembering to include at least “l” on all parent directories thereof.
(Cross-realmed people can, of course, do the above themselves with a hat in their own realm; the pts part automatically happens the first time the user aklogs to the ACM with it, once we’ve done the proper cross-realming dance.)
Then, for non-long-running but noninteractive things, the user can do something like:
export KRB5CCNAME=/somewhere/besides/the/default
kinit -k -t the.keytab username/instancename
aklog -setpag
# do stuff
For long-running things started interactively (like screen sessions), stump’s solution is running a script similar to the following inside screen:
#!/bin/sh -e
TMPDIR=`mktemp -d /tmp/stump_irc_XXXXXX`
trap 'rm -rf "$TMPDIR"' 0 1 2 15
cp -a ~/irc.keytab "$TMPDIR"/keytab
k5start -U -f "$TMPDIR"/keytab -k "$TMPDIR"/krb5cc -t irssi
(The temp dir dance here is needed because k5start drops your AFS tokens before it reads the keytab, so if your keytab is in AFS, you’re going to be very sad otherwise. mktemp sets the dir it creates 0700, so you’re fairly safe permissions-wise with the copied keytab.)
How to use an alternate hat¶
You probably want to spawn a separate PAG; so first, run
pagsh -c $SHELL
After that, set yourself a private credential cache. I suggest the nice and modern
export KRB5CCNAME=KEYRING:session
which doesn’t use files and, if you’re feeling paranoid, can be locked out from even other instances of your uid, restricting to “possessor”. In any case, the next thing you want is
kinit ${USER}/admin
and finally
aklog
stump has the following in his .bashrc
to more easily manage putting
on his other hats
# The "grep ^" looks useless, but it causes the functions to return error
# if I have no Kerberos tickets.
kprincipal () { klist 2>/dev/null | grep '^Default principal: ' | sed -e 's/.*: //' | grep ^; }
krealm () { kprincipal | sed -e 's/.*@//' | grep ^; }
krbsh () { (set -e
TMPDIR="`mktemp -d /tmp/krbsh_XXXXXX`"
trap 'rm -rf "$TMPDIR"' 0 1 2 3 15
export KRB5CCNAME=FILE:"$TMPDIR"/krb5cc
kinit "$@"
set +e
pagsh -e -c "aklog '`krealm | tr 'A-Z' 'a-z'`' && exec bash"
RETVAL="$?"
kdestroy
return "$RETVAL"); }
PS1="\`kprincipal | sed 's/.*/(&) /'\`$PS1"
alias put-admin-hat-on="krbsh stump/admin@ACM.JHU.EDU"
Configuration¶
Our KDC configuration is visible at file:///afs/acm.jhu.edu/readonly/group/admins.pub/kdc.conf . Note that this does not induce a circular dependency as the AFS servers can come up and begin talking to each other without the KDCs (as they all share a keytab) and this is a publicly readable file.
Replication¶
The master kdc, every few minutes, runs a script which dumps the database and
then pushes it to all slaves. We use wrapsrv
and DNS to maintain the set
of slave KDCs (isn’t that cute; note that kpropd.acl
still needs to be
up-to-date, but it only contains host/typhon.acm.jhu.edu@ACM.JHU.EDU
for
the moment).
/usr/sbin/kdb5_util dump ${DUMPFILE}
/usr/bin/wrapsrv _krb_prop._udp.acm.jhu.edu "/bin/bash -c \"/usr/sbin/kprop -d -f ${DUMPFILE} -P %p %h; exit 1\""
Creating a new replica¶
Non-secret configuration details:
ln -s /afs/acm.jhu.edu/readonly/group/admins.pub/kdc.conf /etc/krb5kdc/kdc.conf
echo host/typhon.acm.jhu.edu@ACM.JHU.EDU > /etc/krb5kdc/kpropd.acl
Enable kpropd in /etc/inetd.conf (or equivalent service):
update-inetd --add "krb5_prop stream tcp nowait root /usr/sbin/kpropd kpropd"
SECURELY copy /etc/krb5kdc/stash
from an existing master or replica to
the new replica.
Manually run kpropd on the master:
kprop -d -f /tmp/krb5kdc-slave-datatrans echidna.acm.jhu.edu
Check that it succeeded. (Note that the file name here is the path used by our
automagic replication script; i.e. it is ${DUMPFILE}
from above. You may
need to manually run kdb5_util dump
if it doesn’t exist.)
Update DNS to also answer with the new replica as a SRV response to
_krb_prop._udp.acm.jhu.edu
. The master will begin propagation regularly.
Update DNS to also answer with the new replica for the other Kerberos
records, namely a kdcN
CNAME
and _kerberos._udp
(Strictly speaking,
only the latter is necessary, but our convention is to use both.) This
machine will now be used by clients.
Cross-Realming¶
Todo
The ACM will happily cross-realm with anyone who asks; our admins have a history of running their own vanity domains. However, it’s not always straightforward and so the process should be documented here.
Incoming¶
Use kadmin to create the cross-realm service principal
ank -policy service krbtgt/ACM.JHU.EDU@${REALM}
Choose a big password and share it SECURELY with the other side, or let them choose a big password and just use theirs, or use a shared-key derivation scheme, whatever. Same password on both sides.
Verify that the list of enctypes that exist for the cross-realm service
principal is exactly the same on both ends. You may have to specify some
-e
options if there are different defaults. Mysterious issues may
arise later otherwise.
Create an AFS PTS group for users from the remote realm, and optionally set the group quota
pts creategroup system:authuser@${realm} -owner system:administrators
pts setfields system:authuser@${realm} -groupquota 100
Test that it works by having the remote end obtain Kerberos tickets and then
run aklog -d acm.jhu.edu
. Afterwards, their Kerberos ticket cache should
contain a service key for krbtgt/ACM.JHU.EDU@${REALM}
and
afs/acm.jhu.edu@ACM.JHU.EDU
and aklog
should have announced the
successful first-time login creation of a UID on our side.
Outgoing¶
Same thing, but with the realm names, the realm in which you do each command, and any other reference to either end reversed (-;
If the other end doesn’t have AFS, try accessing some other service on
the other end with an ACM ticket. If there isn’t a good one to try, just
run kvno
against some service principal on the other end with an ACM
ticket and see if the resulting contents of your ticket cache look right.
The passwords don’t have to match between directions (though they of course need to match within each direction) - in fact, they probably shouldn’t.
Cross-realming with someone using a Samba 4 KDC¶
Have them create a user to hold the cross-realm service principal, mark its password as not expiring, and then create the service name
samba-tool user create JHUACM
samba-tool user setexpiry --noexpiry JHUACM
samba-tool spn add krbtgt/ACM.JHU.EDU JHUACM
Note
I do not know if this is the right approach, but it does seem to work, at least in the one direction. As of the time of this writing, Samba 4 does not support the other direction.