============ 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 :doc:`../afsdoc/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). .. index:: single: Kerberos ; Instance .. _kdc-instances: 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 :ref:`webserver-keytabs`. Note that instances are also used for administrative commands; see :doc:`admin-hats`.) 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" .. _krb_config: 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.