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 [email protected] && kinit -r 200h -f [email protected]"
```

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: [email protected]

Valid starting       Expires              Service principal
2020-01-09 15:51:46  2020-01-10 15:51:44  krbtgt/[email protected]
               renew until 2020-01-17 23:51:44

Ticket cache: DIR::/home/rak/.cache/krb5cc/tktUhVKu8
Default principal: [email protected]

Valid starting       Expires              Service principal
2020-01-09 15:51:44  2020-01-10 15:51:42  krbtgt/[email protected]
               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: [email protected]

Valid starting       Expires              Service principal
2020-01-09 15:51:46  2020-01-10 15:51:44  krbtgt/[email protected]
               renew until 2020-01-17 23:51:44
2020-01-09 15:54:27  2020-01-10 15:51:44  afs/[email protected]
               renew until 2020-01-17 23:51:44
2020-01-09 15:54:27  2020-01-10 15:51:44  krbtgt/[email protected]
               renew until 2020-01-17 23:51:44
2020-01-09 15:54:27  2020-01-10 15:51:44  afs/[email protected]
               renew until 2020-01-17 23:51:44

Ticket cache: DIR::/home/rak/.cache/krb5cc/tktUhVKu8
Default principal: [email protected]

Valid starting       Expires              Service principal
2020-01-09 15:51:44  2020-01-10 15:51:42  krbtgt/[email protected]
               renew until 2020-01-17 23:51:42
2020-01-09 15:54:27  2020-01-10 15:51:42  [email protected]
               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.