2020-01-11: On using multiple Kerberos realms and AFS rak =============================================================== Several people have asked me over the past months how to simultaneously authenticate against multiple Kerberos realms and how to hook this up with AFS. To help with this, I've decided to write it all up once and for all. For the sake of example, I'm going to assume that you want to authenticate against the realms `ANDREW.CMU.EDU` and `CS.CMU.EDU` using the username `gandalf`. The first step is to set your Kerberos credentials cache to be a directory so that individual Kerberos tickets from different realms do not conflict each other. I use the directory `${HOME}/.cache/krb5cc`, but you can set this to whatever you would like. Make sure that the directory exists. Then add the following line to your `~/.profile` (or other appropriate shell configuration file): ``` export KRB5CCNAME=DIR:${HOME}/.cache/krb5cc # kerberos credentials cache ``` For more details on this environment variable, see the Credential cache [1] page in the MIT Kerberos documentation. [1]: https://web.mit.edu/kerberos/krb5-1.12/doc/basic/ccache_def.html Next, I define an alias `kinits` that lets me get new tokens from multiple realms. I pass the `-r 200h` argument to `kinit` that lets me renew my tokens for up to 200 hours (about 8 days) without having to re-enter my password. Again, add the following to your shell configuration file: ``` alias kinits="kinit -r 200h -f rkavanag@CS.CMU.EDU && kinit -r 200h -f rkavanag@ANDREW.CMU.EDU" ``` Once you have your tokens (using the `kinits` alias), you should see that your tokens for each realm are split into two different cache files: ``` rak@zeta:~$ klist -A Ticket cache: DIR::/home/rak/.cache/krb5cc/tktqina73 Default principal: gandalf@ANDREW.CMU.EDU Valid starting Expires Service principal 2020-01-09 15:51:46 2020-01-10 15:51:44 krbtgt/ANDREW.CMU.EDU@ANDREW.CMU.EDU renew until 2020-01-17 23:51:44 Ticket cache: DIR::/home/rak/.cache/krb5cc/tktUhVKu8 Default principal: gandalf@CS.CMU.EDU Valid starting Expires Service principal 2020-01-09 15:51:44 2020-01-10 15:51:42 krbtgt/CS.CMU.EDU@CS.CMU.EDU renew until 2020-01-17 23:51:42 ``` Next, I define the following two helper functions `rkinits` and `aklogs` in my shell. The `rkinits` function renews all of my kerberos tokens without needing my password. `aklogs` refreshes my AFS tokens using my kerberos tokens. The `club.cc.cmu.edu` line in `aklogs` also refreshes my AFS tokens on that host using my existing Kerberos tokens. You should drop it if you do not have an account on that host. You should put these in a configuration file read by each invocation of your shell so that cron can find them (see below). ``` aklogs () { for r in CS.CMU.EDU ANDREW.CMU.EDU; do KRB5CCNAME=`KRB5CCNAME=DIR:$HOME/.cache/krb5cc klist -l | grep $r | sed -e s'/.*:://g'` aklog -c $r -k $r done KRB5CCNAME=DIR:$HOME/.cache/krb5cc aklog club.cc.cmu.edu } rkinits () { for r in CS.CMU.EDU ANDREW.CMU.EDU; do KRB5CCNAME=`KRB5CCNAME=DIR:$HOME/.cache/krb5cc klist -l | grep $r | sed -e s'/.*:://g'` kinit -R rkavanag@$r done KRB5CCNAME=DIR:$HOME/.cache/krb5cc aklogs } ``` After calling `aklogs`, I then see the following AFS tokens, again split up by realm into two different cache files: ``` rak@zeta:~$ klist -A Ticket cache: DIR::/home/rak/.cache/krb5cc/tktqina73 Default principal: gandalf@ANDREW.CMU.EDU Valid starting Expires Service principal 2020-01-09 15:51:46 2020-01-10 15:51:44 krbtgt/ANDREW.CMU.EDU@ANDREW.CMU.EDU renew until 2020-01-17 23:51:44 2020-01-09 15:54:27 2020-01-10 15:51:44 afs/andrew.cmu.edu@ANDREW.CMU.EDU renew until 2020-01-17 23:51:44 2020-01-09 15:54:27 2020-01-10 15:51:44 krbtgt/CLUB.CC.CMU.EDU@ANDREW.CMU.EDU renew until 2020-01-17 23:51:44 2020-01-09 15:54:27 2020-01-10 15:51:44 afs/club.cc.cmu.edu@CLUB.CC.CMU.EDU renew until 2020-01-17 23:51:44 Ticket cache: DIR::/home/rak/.cache/krb5cc/tktUhVKu8 Default principal: gandalf@CS.CMU.EDU Valid starting Expires Service principal 2020-01-09 15:51:44 2020-01-10 15:51:42 krbtgt/CS.CMU.EDU@CS.CMU.EDU renew until 2020-01-17 23:51:42 2020-01-09 15:54:27 2020-01-10 15:51:42 afs@CS.CMU.EDU renew until 2020-01-17 23:51:42 ``` I have a crontab entry that renews my tokens once an hour. This lets me go a week without having to enter my password to get Kerberos working. Once I reach the renewal limit, I just manually call `kinits`. To edit your list of crontab entries, go `crontab -e`. You will need to make sure that the shell that you use reads the config file containing `aklogs` and `rkinits`. For example, if you are using `ksh`, then the `ENV` environment variable should point to the file containing `aklogs` and `rkinits`. ``` 0 * * * * zsh -c "rkinits" ``` I have the following in my `~/.ssh/config`. Setting `GSSAPIAuthenticate yes` lets me use Kerberos tokens to authenticate to authenticate against the listed hosts. Setting `GSSAPIDelegateCredentials yes` lets the remote host automatically mount my home directory over AFS when I log in without needing me to enter my password. ``` Host unix.andrew.cmu.edu linux.gp.cs.cmu.edu GSSAPIAuthentication yes GSSAPIDelegateCredentials yes User gandalf ``` As always, feel free to reach out to me if you have any questions.