Kerberos

From Livedoc - The Documentation Repository
Revision as of 11:50, 8 April 2016 by 2016fwilson (talk | contribs)
Jump to: navigation, search

Kerberos is a network authentication service, which allows for authentication with passwords without transmitting the password itself. This page is not an explanation on Kerberos; for that, look at RFC 4120.

Implementations

There are multiple implementations of Kerberos. In addition to the free ones, such as the MIT, Heimdal, and Shishi implementations, Microsoft has also made an implementation for Windows, and Sun Microsystems has an implementation for their Java programming language. Right now, all of the CSL's Kerberos servers run the Heimdal implementation built into OpenBSD. The clients are a mix of the MIT and Heimdal implementations. The Heimdal client is notable for its integration with AFS.

Server Layout

Right now, the kadmin and kpasswd servers are running on agni. KDCs are running on agni (the 'master') and scylla (the 'slave'). The service IPs kdc1 and kdc2 are configured so that agni will bring up kdc1 and scylla will bring up kdc2. All clients should be configured to try kdc1 first as it will always be pointed to the primary server where changes are reflected most rapidly. In addition, agni is configured to bring up the kerberos service IP which should always point to the admin server.

Outages

The layout is designed such that a single outage will not cause much disruption. If the slave KDC fails, there should be no change felt by the clients. If the master KDC fails, then it will be impossible to add, delete, or modify principals in any way (which includes changing passwords), but they will still be able to be read properly, which means that services will be able to authenticate without a problem.

Replication

The hprop command, paired with the hpropd daemon, allows for database replication (and propagation, hence the name) to occur. To propogate database changes to a slave server, the hprop command must be run, and the hpropd daemon must be configured in inetd on the slave server. In addition, the slave server needs to have a the principal hprop/<slave FQDN> in its system keytab.

hprop is called every 30 minutes from cron on agni to replicate changes to the slave KDC(s). If you are adding a slave KDC, you must add a line in root's crontab on agni.

# propagate the heimdal kerberos DB to the slave KDCs
*/30    *       *       *       *       /usr/libexec/hprop scylla.csl.tjhsst.edu
*/30    *       *       *       *       /usr/libexec/hprop nebula.csl.tjhsst.edu

Cross-realm Authentication

Currently, we have a two-way cross-realm trust with the Windows Domain LOCAL.TJHSST.EDU (which can be considered the same as a Kerberos Realm for purposes of this article). This trust allows our systems (which operate in the CSL.TJHSST.EDU realm) to verify and trust user principals from the LOCAL Domain as well as allowing the LOCAL Domain Controllers to verify the identity of our systems (which have keytabs in the CSL realm). Note that this alone does not give access to AFS from windows tickets. For information on that, see OpenAFS/cross-cell.

To re-create this trust, first generate a long random string to use as a Trust Password. Then, on the primary KDC, create two principals, krbtgt/CSL.TJHSST.EDU@LOCAL.TJHSST.EDU and krbtgt/LOCAL.TJHSST.EDU@CSL.TJHSST.EDU. For security, it is recommended to add the attributes disallow-renewable, disallow-tgt-based, and disallow-forwardable to both principals. Finally, on a LOCAL domain controller, go to Admin Tools -> Active Directory Domains and Trusts, and create a new two-way trust in the LOCAL domain using the same Trust Password. Alternatively, to setup the LOCAL domain side of the trust, you can use:

netdom TRUST CSL.TJHSST.EDU /add /realm /passwordt:<password> /twoway

History

Prior to the creation of the two-way trust, we had a one-way trust with the LOCAL.TJHSST.EDU Domain (CSL.TJHSST.EDU trusting LOCAL.TJHSST.EDU) to allow for users to login to CSL systems with their LOCAL domain passwords. This trust was created similar to the above example except with only the krbtbt/CSL.TJHSST.EDU@LOCAL.TJHSST.EDU principal being created on the primary KDC and only a one-way trust being created on the LOCAL domain controller. One downside to this system was that CSL systems needed to have computer accounts (keytabs) in the LOCAL domain (since the LOCAL domain controller would not trust a CSL keytab to verify the identity of a client system).

Client Configuration

/etc/krb5.conf

This is the primary configuration file for a kerberos client. On Solaris systems, this file is located at /etc/krb5/krb5.conf and on OpenBSD systems, this file is located at /etc/kerberosV/krb5.conf.

Add or modify the following lines in the [libdefaults] section. This will set the default realm of the system to CSL.TJHSST.EDU and allow the client to use the weaker (broken) encryption types. Yhe latter is necessary for interoperation with our Windows Server 2003 DCs which only support the weaker encryption types.

[libdefaults]
  default_realm = CSL.TJHSST.EDU
  allow_weak_crypto = true

Add the following lines to the [realms] section to allow the clients to find the KDCs for each server.

[realms]
  CSL.TJHSST.EDU = {
    kdc = kdc1.tjhsst.edu
    kdc = kdc2.tjhsst.edu
    admin_server = kerberos.tjhsst.edu
    auth_to_local = RULE:[1:$1@$0](^.*@LOCAL\.TJHSST\.EDU$)s/@.*$//
    auth_to_local = DEFAULT
  }
  LOCAL.TJHSST.EDU = {
    kdc = tj04.local.tjhsst.edu
    kdc = tj05.local.tjhsst.edu
    admin_server = tj04.local.tjhsst.edu
  }

Add the following lines to the [domain_realm] section to allow clients to map DNS names to Kerberos realms.

[domain_realm]
  tjhsst.edu = CSL.TJHSST.EDU
  .tjhsst.edu = CSL.TJHSST.EDU
  csl.tjhsst.edu = CSL.TJHSST.EDU
  .csl.tjhsst.edu = CSL.TJHSST.EDU
  local.tjhsst.edu = LOCAL.TJHSST.EDU
  .local.tjhsst.edu = LOCAL.TJHSST.EDU

Add the following lines to the [appdefaults] section so that the pam_krb5 module will not attempt to authenticate system accounts.

[appdefaults]
  pam = {
    minimum_uid = 1000
  }

/etc/krb5.keytab

This file serves as an equivalent to a password to allow computers and services to authenticate themselves and acquire Kerberos tickets. On Solaris systems, this file is located at /etc/krb5/krb5.keytab and on OpenBSD systems, this file is located at /etc/kerberosV/krb5.keytab. The permissions on this file should be 0400 for security reasons since with this file it is possible to spoof the identity of the system to the KDCs.

A keytab can be generated on a system with Heimdal Kerberos installed by using the command:

ktutil -k /etc/krb5.keytab get -p <username>/admin host/<FQDN>

Using MIT Kerberos, the commands are:

kadmin
  addprinc -randkey host/FQDN
  ktadd -k /etc/krb5.keytab host/FQDN

Note that if you are generating a keytab for a system other than the one that you are on, you will want to change the path after -k to someplace besides the current system's keytab. FQDN must be the Fully Qualified Domain Name of the system and must match the result of a reverse look-up of the system's IP address.

PAM

In order to allow users to actually log in using their Kerberos passwords, pam_krb5 must be added to the PAM Auth stack. On our Gentoo systems, we modify /etc/pam.d/system-auth

auth            sufficient      pam_unix.so likeauth nullok
auth            sufficient      pam_krb5.so use_first_pass
auth            sufficient      pam_krb5.so use_first_pass realm=LOCAL.TJHSST.EDU
auth            required        pam_deny.so
session         optional        pam_krb5.so

On Solaris systems, pam_krb5 needs to be installed and appropriate lines added to /etc/pam.conf for any services that require Kerberized logins.

On OpenBSD systems, modify the auth-defaults line in /etc/login.conf as shown:

# Default allowed authentication styles
auth-defaults:auth=krb5-or-pwd,skey:

For backend systems which do not need to allow logins from the LOCAL.TJHSST.EDU Domain, just remove the second pam_krb5 line. In addition, on remotely accessible systems, the option fail_pwchange should be added to the pam_krb5 lines to prevent users from resetting their passwords remotely.

WARNING: editing PAM/login files without fully understanding what is going on carries a significant risk of either locking yourself out of the system or leaving the system open to unauthorized logins. If you are unsure, ask someone before making changes. In addition, always leave a root terminal open and test logging in and gaining root before completely logging out of the system to avoid locking yourself out.

/root/.k5login

In order to allow Admins to gain root on a system without needing to know the root password to it, we create <username>/root principals and then add them to this file. They can then use ksu and the password to their /root principal to gain root on the system. The format of this file is a list of complete principal names, one per line:

ahamilto/root@CSL.TJHSST.EDU

On OpenBSD systems, this file is located at /root/.klogin and the command to gain root using an authorized principal is:

su -a krb5 - root

/etc/ssh/sshd_config

To enable SSH passwordless login between systems, uncomment or add the following lines to /etc/ssh/sshd_config and then restart sshd.

GSSAPIAuthentication yes
GSSAPICleanupCredentials yes

This will also allow users with ksu access to two systems to ksu on one and then ssh as root to the other system without requiring a password.

Note that on Gentoo systems, openssh must be built with the Kerberos USEFLAG in order to enable these options.

Server Configuration

To configure a system as a Kerberos KDC; first configure /etc/krb5.conf and /etc/krb5.keytab as described in the #Client Configuration Section. Then continue below.

/etc/krb5.conf

Add the following sections to configure logging for the various server daemons:

[kdc]
       logging = FILE:/var/log/heimdal-kdc.log
[logging]
       # The KDC logs by default, but it's nice to have a kadmind log as well.
       kadmind = FILE:/var/heimdal/kadmind.log

Note: On Solaris systems, this file is located at /etc/krb5/krb5.conf and on OpenBSD systems, this file is located at /etc/kerberosV/krb5.conf.

/etc/krb5.keytab

For a Slave KDC, you will need to add an additional principal of the form hprop/<FQDN>@<REALM> to the system keytab. This can be done with a command similar to the following:

ktutil -k /etc/krb5.keytab get -p <username>/admin hprop/<FQDN>

Note: On Solaris systems, this file is located at /etc/krb5/krb5.keytab and on OpenBSD systems, this file is located at /etc/kerberosV/krb5.keytab.

/etc/inetd.conf

For a Slave KDC, add the following lines to /etc/inetd.conf and then kill -HUP the inetd process to make the changes go live:


krb_prop        stream  tcp     nowait  root    /usr/libexec/hpropd
krb_prop        stream  tcp6    nowait  root    /usr/libexec/hpropd

/var/heimdal/

Create the directory /var/heimdal/ with permissions root:wheel and 0700.

mkdir /var/heimdal/
chown root:wheel /var/heimdal/
chmod 0700 /var/heimdal/

Then copy the following files from an existing KDC to /var/heimdal/ making sure to set the permissions as noted below.

/var/heimdal/heimdal.db

This file is the actual database of Kerberos Principals. Permissions should be root:wheel and 0600.

/var/heimdal/kadm5.keytab

This file is only needed if the server is planned to take over as the Primary KDC (which runs the kadmind and kpasswdd servers). It is a standard keytab file containing the principals kadmin/admin@CSL.TJHSST.EDU and kadmin/changepw@CSL.TJHSST.EDU. Permissions should be root:wheel and 0600.

/var/heimdal/kadmind.acl

This file is only needed if the server is planned to take over as the Primary KDC (which runs the kadmind and kpasswdd servers). It controls permissions to create/edit principals via kadmind. It contains one or more lines each granting specific rights to a given Kerberos Principal. See the kadmind man page for details on the format. Permissions should be root:wheel and 0644.

/var/heimdal/m-key

This file contains the key used to encrypt the Kerberos Database. It is a standard keytab file containing the principal K/M@CSL.TJHSST.EDU. Permissions should be root:wheel and 0600.

Service Configuration

Now configure your server to start the appropriate daemons on boot. For a slave KDC, start the kdc and inetd daemons. For the master KDC, start the kdc, kadmind, and kpasswdd daemons. On OpenBSD, this is easily accomplished by editting the appropriate lines in /etc/rc.conf.local as shown below:


kdc_flags=""            # for normal use: "" see 'info heimdal' for help
kadmind_flags=NO        # for normal use: ""
kpasswdd_flags=NO       # for normal use: ""

Currently, due to a bug in the OpenBSD stock rc.conf, it is also necessarily to delete or comment the following lines in both /etc/rc.conf and /etc/rc.conf.local


: ${kdc_flags=$([ X"${krb5_master_kdc-NO}" = XYES -o X"${krb5_slave_kdc-NO}" = XYES ] || echo NO)}
: ${kadmind_flags=$([ X"${krb5_master_kdc-NO}" = XYES ] || echo NO)}
: ${kpasswdd_flags=$([ X"${krb5_master_kdc-NO}" = XYES ] || echo NO)}

Finally, for a new master KDC, setup #Replication to the slave KDCs. For a new slave KDC, add #Replication from the Master KDC to the new slave.

Debugging

Issues with SSH passwordless login

Normally, the GSSAPI mechanism is used to authenticate someone to a machine who has already authenticated to another machine in the lab. This uses their existing Kerberos credentials to prove who they are, and it also forwards their Kerberos tickets to the new machine, so they can use them for accessing AFS. So far, this has been seen to work fine on workstations.

A problem with this, first seen when trying to implement on the TJforge system and the remote SSH access server, is when this system is attempted on a machine with multiple IPs to SSH to. For example, the TJforge system currently is run on the server robustus, which also contains service IPs for forge.tjhsst.edu and remote.tjhsst.edu. When a user attempts to use GSSAPI against the remote IP, robustus seems to attempt to obtain the host principal for remote (even though it is in robustus' /etc/krb5.keytab, it still contacts a KDC). This fails, because it is accessing the KDC from the IP of robustus, which reverse-maps in DNS back to robustus.tjhsst.edu, and so the KDC can see that it is trying to obtain the wrong host principal. This causes GSSAPI via SSH to fail with the message "Wrong principal in request" when verbosity is turned on.

Unable to login

If you are unable to login to a system that uses Heimdal Kerberos and AFS Home Directories; check your afs permissions. Heimdal will deny your login if it is unable to check that you do not have a .k5login file or if it sees one and is unable to read it. Therefore, you need to make sure that you have no .k5login file in your AFS Home Directory and that system:anyuser has list privileges to the root of your Home Directory. You can check both of these with the following commands:

cd ~
fs la . #should return an entry for system:anyuser l
ls .k5login #should return nothing indicating that no such file exists

If you don't see a l entry for system:anyuser or if you have a .k5login file, apply the appropriate fixes from below: run this:

cd ~
fs sa . system:anyuser l #add an appropriate AFS ACL
rm .k5login #remove the .k5login file if it exists

IPv6 on a 2003 R2 Domain Controller

Normally, Kerberos will attempt to resolve the KDC hostnames and then communicate using IPv6 (if available) or IPv4 (otherwise) to authenticate a client. However, Windows Server 2003 R2, while supporting IPv6, does not make Active Directory Services available on IPv6. Therefore, if you specify a 2003 R2 DC by hostname in /etc/krb5.conf, it will have to timeout on IPv6 before attempting to reach the DC via IPv4. For this reason, any Server 2003 DCs should be listed in krb5.conf by IPv4 address.

Migrating from Heimdal to MIT Kerberos

This is much harder than it looks.

  1. Compile Heimdal from [source](https://www.h5l.org/sources.html)
  2. Use your new Heimdal's kadmin to dump principals in decrypted MIT format: heimdal/install/bin/kadmin -l dump -d -f MIT /tmp/mit.dump
  3. Securely transfer this file to your new MIT KDC
  4. Set up the new KDC, but don't add any principals (i.e. don't go further than kdb5_util create -s)
  5. Import the database dump: kdb5_util load -update mit.dump -sf /path/to/your/stash/file
  6. You're done(ish)!

External links