# Kerberos, ssh, and Principal Selection



## jef (Mar 15, 2015)

Please forgive me if this is "obvious" but this is my first venture into setting up Kerberos.

The end goal for me is to be able to have NFSv4 be able to properly recognize the user _jeff _as the same person, no matter if the mount is on FreeBSD, Mac OS X, or Ubuntu. As I understand it, properly setting up Kerberos will mitigate the ancient UID/GID mapping problems.

Rather than complicating things with integration of MIT Kerberos with FreeBSD, I decided to start off with the as-shipped Kerberos tools. I _may _shift over to security/krb5 in the future, but, for now, at least I'm under the belief that the Kerberos is "properly" integrated with the various bits of FreeBSD, be it things like _PAM _or standard utilities, like _ssh._

To this end, I've set up Kerberos on a build of 10.1-STABLE FreeBSD 10.1-STABLE #1 r279921 using the instructions at https://www.freebsd.org/doc/en/books/handbook/kerberos5.html (with the changes to /etc/rc.conf variable names to the current `kdc_enable="YES"`and `kadmind_enable="YES"`)

This machine has various DNS mappings in two domains, call them _b-domain.com_ and _w-domain.com _for now. So all of the following resolve to the host's IP address:

13.b-domain.com
port13.b-domain.com
port13.pn.w-domain.com
The reverse mapping is to port13.pn.w-domain.com and agrees with what `hostname` returns.

The Kerberos realm is B-DOMAIN.COM

/etc/krb5.conf contains

```
[domain_realm]
    .b-domain.com = B-DOMAIN.COM
    .w-domain.com = B-DOMAIN.COM
```
I've set up principals for myself, both as a user and as an admin.

I'm able to obtain TGT as either, as well as to run `kadmin` with the admin credential.

I've created and believe properly exported host keys for each of the DNS names above.

I can successfully use `kinit` with either my user or admin principal.

My first "quick check" was to see if I could use GSSAPI to authenticate an ssh session to the local host.

I've updated /etc/sshd_conf and /etc/ssh_conf to use
`GSSAPIAuthentication yes` in both cases. I've turned off cleanup with `GSSAPICleanupCredentials no` so that I can see what was created along the way.

If I run `ssh -v jeff@port13.pn.w-domain.com` it _will _log me in using Kerberos.

However, any of the other hostnames fail (without anything useful in the _ssh -v _output) and move on to password authentication. Using the host's IP address didn't resolve this (thinking that _ssh _was asking for credentials based on the target host's concept of its own name).

I see host-type credentials for all DNS names used present in the output of `klist`:

```
[jeff@port13 ~]$ klist
Credentials cache: FILE:/tmp/krb5cc_1001
        Principal: jeff@B-DOMAIN.COM

  Issued                Expires               Principal

Mar 15 02:48:30 2015  Mar 15 12:48:30 2015  krbtgt/B-DOMAIN.COM@B-DOMAIN.COM
Mar 15 03:42:54 2015  Mar 15 12:48:30 2015  host/13.b-domain.com@B-DOMAIN.COM
Mar 15 03:46:30 2015  Mar 15 12:48:30 2015  host/port13.b-domain.com@B-DOMAIN.COM
Mar 15 03:47:27 2015  Mar 15 12:48:30 2015  host/port13.pn.w-domain.com@B-DOMAIN.COM
```

This leaves me with a couple questions that I haven't been able to find in the _Handbook,_ `info heimdal` or searching the web:

*How does ssh (or a service, in general) determine the credential(s) requested/used for a given command-line connection request?*

*What am I missing in my configuration that is preventing ssh from successfully using GSSAPI authentication for the other host names?*​
Any guidance to additional resources, especially as I move on to NFSv4, would be appreciated as well. It seems that _Kerberos: The Definitive Guide _isn't so definitive any more, with it not even appearing in O'Reilly's Safari Books Online at this time.


----------



## Juanitou (Mar 16, 2015)

May I suggest you to try asking this on FreeBSD-net or FreeBSD-security lists?


----------



## scottro (Mar 16, 2015)

If you do, please come back with the answer.  At one point, we considered using Kerebos for some single sign on stuff, and ran into similar issues.  I just figured the docs were written for someone smarter than me and did something else, but if you do get this working, I, for one, would love to hear how you did.


----------



## Oko (Mar 16, 2015)

scottro said:


> If you do, please come back with the answer.  At one point, we considered using Kerebos for some single sign on stuff, and ran into similar issues.  I just figured the docs were written for someone smarter than me and did something else, but if you do get this working, I, for one, would love to hear how you did.


+1


----------



## jef (Mar 17, 2015)

Well, no answer yet, but I believe a strong clue comes from /usr/src/crypto/heimdal/krb5/principal.c

```
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_sname_to_principal (krb5_context context,
                        const char *hostname,
                        const char *sname,
                        int32_t type,
                        krb5_principal *ret_princ)
{
    krb5_error_code ret;
    char localhost[MAXHOSTNAMELEN];
    char **realms, *host = NULL;
[...]
    if(hostname == NULL) {
        ret = gethostname(localhost, sizeof(localhost) - 1);
        if (ret != 0) {
            ret = errno;
            krb5_set_error_message(context, ret,
                                  N_("Failed to get local hostname", ""));
            return ret;
        }
        localhost[sizeof(localhost) - 1] = '\0';
        hostname = localhost;
    }
```
At least with the heimdal implementation, if a service is looking to find it's principal, if it doesn't "know" the hostname to pass, that code sets the hostname to that which gethostname(3) returns.

By manually changing the hostname using hostname(1), the hostname that works for ssh(1) follows.

This is a rather unfulfilling answer, as a "nice" behavior would be to try the various keys in the key table and see what (if anything) works.

If my _guess _is correct, it means that you can't expect ssh(1) to gracefully handle hosts that have multiple host names. I didn't see anything in sshd_config(5) that suggested that you could even specify the host name to use with a different instance running on different interfaces or ports.

I don't know if the behavior is different for MIT Kerberos, but I also suspect that unless you've messed with your build environment, ssh(1) has been built with HEIMDAL defined and adopted its conventions.

_Edit -- I didn't see anything in make.conf(5) or src.conf(5) that allowed you to specify _which _Kerberos implementation to use. Looking in to building from ports source as a possibility for having MIT-Kerberos versions. (I don't see openssh in 10.1 ports, nor a clear option for security/openssl to change the Kerberos library.)_

_Edit -- I'm not holding out much hope for MIT Kerberos behaving differently, based on http://web.mit.edu/kerberos/krb5-latest/doc/appdev/h5l_mit_apidiff.html_

_Edit -- There is apparently a patch for OpenSSH that permits _any _key in the host's key table to be checked for access. It also apparently has significant security impact if improperly configured. See http://www.sxw.org.uk/computing/patches/openssh.html for details of the patch. See https://lists.debian.org/debian-ssh/2012/02/msg00028.html for one discussion of the security implications. Note that, due to the security implications, I can't recommend this patch._


----------



## jef (Mar 18, 2015)

From what I can tell, dealing with multi-homed hosts is a long-standing issue with OpenSSH and Kerberos. The issue of different DNS names for the host appears to be closely related. 

See https://bugzilla.mindrot.org/show_bug.cgi?id=928 and the above notes for details.


----------

