Invariant Properties

  • rss
  • Home

Introduction to Kerberos (part 1)

Bear Giles | April 17, 2016

Old protocols never die.

Kerberos is a three party protocol that provides strong mutual authentication between clients and servers. It is designed for academic and enterprise organizations where there is a single source of truth regarding identify, authentication and authorization. Think universities with faculty, students, and staff, or businesses with employees with different responsibilities. Changes must be propagated immediately – it is not acceptable for there to be a lag such as we see with X.509 digital certificates using periodically updated CRL lists. (It is possible, but expensive, to use OCSP to verify a certificate on each use.)

Strong mutual authentication is when both parties to a transaction have high confidence in the identity of the other party. A good example is when you log onto your bank’s website. The bank authenticates the user with username, password, and second factor like the user accepting the “personal image”. The user authenticates the bank by checking the HTTPS icon in the corner and the recognized “personal image”. Many of us consider the latter somewhat broken since the system will accept a certificate from ANY certificate authority preloaded into the browser. I have nothing against the Moldovian postal service but I don’t want to have to trust it in order to check my bank balance. I have nothing against it but I have no reason to trust it either. With Kerberos there’s a personal relationship – it is our employer, our university, etc., so there’s a much higher level of trust.

Kerberos came out of the Athena project at MIT in the 1980s and was “embraced and extended” by the Borg, I mean by Microsoft, in Windows 2000 as the basis of Active Directory. The “client” was traditionally a person but it is increasingly software as well.

There are three open source Kerberos implementations widely available to Linux users: MIT, Heimdal, and Shishi. MIT Kerberos 5 is the reference implementation and somewhat more tuned to enterprise users, Heimdal is an implementation made outside of the US, and I know nothing about Shishi. The fact that Heimdal was developed outside of the US was important while the US banned export under ITAR regulations (since it includes strong encryption) and may become important again and we refight the crypto wars.

I will be discussing MIT Kerberos since I’m a little more familiar with it.

The Three-Headed Hellhound

Kerberos is named after the three-headed dog that guards the gate of Hell. This reflects the three parties in a Kerberos session:

The Client

The client may be a person (student, employee) or enterprise software. The client does not log into a remote system. Instead the client logs into a local agent and that agent performs all necessary negotiation with the KDC and servers. In the protocol this is the “ticket granting ticket (TGT)”.

As mentioned earlier the client may also be enterprise software.

The Server

The server can be any software requiring authentication. Traditional servers include telnet (ktelnet) allowing remote access to a shell and NFS (allowing remote access to a filesystem). In the enterprise environment we often see kerberized web services.

The Key Distribution Center (KDC)

The key distribution center (KDC) is the trusted third party. In early implementations the KDC was literally responsible for generating symmetric keys to be used by the client and server, hence the name. I don’t know if that’s still true. The client and server are free to renegotiate their session keys at any time.

All of this occurs within a Kerberos realm. This is an arbitrary string but by convention is the domain name in all caps, e.g., INVARIANTPROPERTIES.COM. This ensures that realms will be unique (modulo bad players). Users within a realm are identified by principals. An individual may have more than one principal but no principal should be used by more than one individual. Principals have the format username@REALM or username/role@REALM, e.g., bgiles/admin@INVARIANTPROPERTIES.COM. Servers have a similar format: servicename/fqdn@REALM.

KDC installation on Debian and Ubuntu

Today we will discuss the installation and configuration of an MIT Kerberos5 KDC on an AWS EC2 instance. MIT can use either an internal database or LDAP for its backing store. The latter will be a better choice if you already use an LDAP database for user management.

I will only discuss the former in this blog entry but might revisit the latter in the future.

Hardware Requirements

The primary hardware requirement for a KDC is security. A compromised KDC will put the entire enterprise at risk. It should be physically secured and run no other services. In production we want at least two servers (one primary and at least one secondary) and they should be in physically separate locations.

It is extremely important that the clocks are synchronized across the all systems within a realm. Historically tickets would be valid for 5 to 15 minutes but with NTP running on all systems this window can be reduced to seconds. Note: this is the window when a ticket can be used for authentication and has no bearing on how long the user can use the service.

A KDC has modest computational requirements. I believe we can start with a micro instance and only upgrade if the need arises. This means the financial cost is extremely modest even if we use multiple KDCs.

We need to open three ports in our firewall. Ports 88 and 750 are required by Kerberos, port 22 for SSH is only required for initial installation and can can be blocked at the AWS Security Group level unless explicitly needed. Subsequent access can eat its own dog food with ktelnet (kerberized telnet), krsh (kerberized rsh), or SSH with Kerberos extensions.

The KDC admin server must also open port 749. Access to this port should be limited.

Debian/Ubuntu Packages

We need to install two packages: krb5-kdc and krb5-admin-server. If you are using LDAP you will want to install krb5-ldap as well. Finally we want to install krb5-doc for documentation.

  1. $ sudo apt-get install krb5-kdc krb5-admin-server krb5-doc
$ sudo apt-get install krb5-kdc krb5-admin-server krb5-doc

During installation we will be asked three things:

  • Name of our realm – this is traditionally our domain name in all-caps.
  • KDC servers – this system
  • KDC admin servers – this system

If you wish you can leave the servers blank at this time and fix the /etc/krb5.conf file below.

Database Initialization

We initialize the internal database with a call to krb5_util. We need to provide our realm name.

  1. $ sudo /usr/sbin/kdb5_util create -r INVARIANTPROPERTIES.COM -s
$ sudo /usr/sbin/kdb5_util create -r INVARIANTPROPERTIES.COM -s

This will take a minute or so to complete.

Defining user rights

We define our users’ rights via an ACL file – /etc/krb5kdc/kadm5.acl. See the man pages for details. One thing to keep in mind is that the user will remain logged in for 7 days by default. Roles with more authority should require reauthentication more frequently.

/etc/krb5dkc/kadm5.acl

  1. */admin@INVARIANTPROPERTIES.COM x  * -maxlife 4h
  2. */root@INVARIANTPROPERTIES.COM  ci *1@INVARIANTPROPERTIE.COM
  3. */root@INVARIANTPROPERTIES.COM  l  *
*/admin@INVARIANTPROPERTIES.COM x  * -maxlife 4h
*/root@INVARIANTPROPERTIES.COM  ci *1@INVARIANTPROPERTIE.COM
*/root@INVARIANTPROPERTIES.COM  l  *

See the man page for kadm5.acl for a description of these entries. The gist is that any principal with ‘admin’ has full administrative rights but must reauthenticate every 4 hours. The superuser on any system can list and update user credentials.

Creating our first administrative user(s)

We must bootstrap our administrative users on the KDC itself. Subsequent user management can be handled remotely. Note that we do NOT need the master password for this – this is why it is critical that access to the KDC be limited.

This shows how to add a user with both regular and administrative rights.

  1. $ sudo kadmin.local
  2. kadmin.local: add_principal bgiles
  3. Enter password for principal "bgiles@INVARIANTPROPERTIES.COM": *******
  4. Re-enter password for principal "bgiles@INVARIANTPROPERTIES.COM": *******
  5. kadmin.local: add_principal bgiles/admin
  6. Enter password for principal "bgiles/admin@INVARIANTPROPERTIES.COM": *******
  7. Re-nter password for principal "bgiles/admin@INVARIANTPROPERTIES.COM": *******
  8. kadmin.local: quit.
$ sudo kadmin.local
kadmin.local: add_principal bgiles
Enter password for principal "bgiles@INVARIANTPROPERTIES.COM": *******
Re-enter password for principal "bgiles@INVARIANTPROPERTIES.COM": *******
kadmin.local: add_principal bgiles/admin
Enter password for principal "bgiles/admin@INVARIANTPROPERTIES.COM": *******
Re-nter password for principal "bgiles/admin@INVARIANTPROPERTIES.COM": *******
kadmin.local: quit.

Registering our servers

If you did not specify the KDC server and KDC admin servers when we installed the packages you can fix this now. Edit the appropriate entry in the /etc/krb5.conf file:

  1. ,,,
  2. [realms]
  3.         INVARIANTPROPERTIES.COM = {
  4.                 kdc = kdc1.invariantproperties.com:88
  5.                 kdc = kdc2.invariantproperties.com:88
  6.                 admin_server = kdc1.invariantproperties.com
  7.                 default_domain = invariantproperties.com
  8.         }
  9. ...
  10. [domain_realm]
  11.         .invariantproperties.com = INVARIANTPROPERTIES.COM
  12.         invariantproperties.com = INVARIANTPROPERTIES.COM
  13. ...
,,,
[realms]
        INVARIANTPROPERTIES.COM = {
                kdc = kdc1.invariantproperties.com:88
                kdc = kdc2.invariantproperties.com:88
                admin_server = kdc1.invariantproperties.com
                default_domain = invariantproperties.com
        }
...
[domain_realm]
        .invariantproperties.com = INVARIANTPROPERTIES.COM
        invariantproperties.com = INVARIANTPROPERTIES.COM
...

This snippet demonstrates how to specify multiple KDC servers. I have not discussed how to perform database replication among multiple KDC servers. This is one task where an LDAP backing store would make much more convenient.

Preparing the Client

We are now ready to set up the client systems so the user can log into Kerberos (that is, get a ticket-granting-ticket (TGT)). I am not going to discuss setting up and accessing kerberized services at this time.

Debian/Ubuntu Packages

We need to install one package: krb5-user. We may also want to install krb5-doc for the rare user who reads the documentation before calling the help desk.

  1. $ sudo apt-get install krb5-user krb5-doc
$ sudo apt-get install krb5-user krb5-doc

You will be asked to specify the Kerberos realm, KDC and KDC admin servers.

Logging in and out

The user can now log into the system using kinit. This command has many options – see the man page for details.

  1. $ kinit
  2. Password for bgiles@INVARIANTPROPERTIES.COM: ******
  3. $ kinit bgiles/admin
  4. Password for bgiles/admin@INVARIANTPROPERTIES.COM ******
$ kinit
Password for bgiles@INVARIANTPROPERTIES.COM: ******
$ kinit bgiles/admin
Password for bgiles/admin@INVARIANTPROPERTIES.COM ******

We can determine our current credentials with klist

  1. $ klist
  2. Ticket cache: FILE:/tmp/krb5cc_1000
  3. Default principal: bgiles/admin@INVARIANTPROPERTIES.COM
  4.  
  5. Valid starting       Expires              Service principal
  6. 04/17/2016 09:40:51  04/17/2016 19:40:51  krbtgt/INVARIANTPROPERTIES.COM@INVARIANTPROPERTIES.COM
  7.     renew until 04/18/2016 09:40:46
$ klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: bgiles/admin@INVARIANTPROPERTIES.COM

Valid starting       Expires              Service principal
04/17/2016 09:40:51  04/17/2016 19:40:51  krbtgt/INVARIANTPROPERTIES.COM@INVARIANTPROPERTIES.COM
	renew until 04/18/2016 09:40:46

(note that the credentials expire at 10 hours, not 4 hours. I need to look into that…)

Finally we can log out with kdestroy

  1. $ kdestroy
  2. $ klist
  3. klist: Credentials cache file '/tmp/krb5cc_1000' not found
$ kdestroy
$ klist
klist: Credentials cache file '/tmp/krb5cc_1000' not found

You can change your password with kpasswd and change your active principal with kswitch.

Remote administration

Administrators can run kadmin remotely. It is no longer necessary for them to physically log into the KDC and run kadmin.local. They will be prompted to reenter their credentials since this is a sensitive operation.

Keytab files

Finally it can be inconvenient to re-enter your password every time you access a remote service. Keytab files allow you to store a Kerberos principal and encryption key for us in place of a password. You must regenerate the keytab files every time you change your Kerberos password.

Keytabs are maintained with the ktutil command.

For more information see What is a keytab, and how do I use one? from Indiana University.

Next Time

Next time I will discuss setting up kerberized services.

Finally A Cautionary Tale

I almost forgot something important – a server should never ask for a user’s Kerberos credentials. The user always performs local authentication and everything else is negotiated behind the scenes. I mention this because Apache had (and still has?) a Kerberos authentication module that worked by prompting the user for his Kerberos credentials and then logging into the system as that that user on the server in order to obatain resources from other systems. This is entirely contrary to the design goals of Kerberos and it is a huge red flag when it happens – it is possible to get “transferable” tickets that can be used by a server on your behalf.

Categories
CEU, linux, security
Comments rss
Comments rss
Trackback
Trackback

« Should Mocked Method Arguments Make Assumptions? Introduction to Kerberos – PostgreSQL (part 2) »

Leave a Reply

Click here to cancel reply.

You must be logged in to post a comment.

Archives

  • May 2020 (1)
  • March 2019 (1)
  • August 2018 (1)
  • May 2018 (1)
  • February 2018 (1)
  • November 2017 (4)
  • January 2017 (3)
  • June 2016 (1)
  • May 2016 (1)
  • April 2016 (2)
  • March 2016 (1)
  • February 2016 (3)
  • January 2016 (6)
  • December 2015 (2)
  • November 2015 (3)
  • October 2015 (2)
  • August 2015 (4)
  • July 2015 (2)
  • June 2015 (2)
  • January 2015 (1)
  • December 2014 (6)
  • October 2014 (1)
  • September 2014 (2)
  • August 2014 (1)
  • July 2014 (1)
  • June 2014 (2)
  • May 2014 (2)
  • April 2014 (1)
  • March 2014 (1)
  • February 2014 (3)
  • January 2014 (6)
  • December 2013 (13)
  • November 2013 (6)
  • October 2013 (3)
  • September 2013 (2)
  • August 2013 (5)
  • June 2013 (1)
  • May 2013 (2)
  • March 2013 (1)
  • November 2012 (1)
  • October 2012 (3)
  • September 2012 (2)
  • May 2012 (6)
  • January 2012 (2)
  • December 2011 (12)
  • July 2011 (1)
  • June 2011 (2)
  • May 2011 (5)
  • April 2011 (6)
  • March 2011 (4)
  • February 2011 (3)
  • October 2010 (6)
  • September 2010 (8)

Recent Posts

  • 8-bit Breadboard Computer: Good Encapsulation!
  • Where are all the posts?
  • Better Ad Blocking Through Pi-Hole and Local Caching
  • The difference between APIs and SPIs
  • Hadoop: User Impersonation with Kerberos Authentication

Meta

  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org

Pages

  • About Me
  • Notebook: Common XML Tasks
  • Notebook: Database/Webapp Security
  • Notebook: Development Tips

Syndication

Java Code Geeks

Know Your Rights

Support Bloggers' Rights
Demand Your dotRIGHTS

Security

  • Dark Reading
  • Krebs On Security Krebs On Security
  • Naked Security Naked Security
  • Schneier on Security Schneier on Security
  • TaoSecurity TaoSecurity

Politics

  • ACLU ACLU
  • EFF EFF

News

  • Ars technica Ars technica
  • Kevin Drum at Mother Jones Kevin Drum at Mother Jones
  • Raw Story Raw Story
  • Tech Dirt Tech Dirt
  • Vice Vice

Spam Blocked

53,793 spam blocked by Akismet
rss Comments rss valid xhtml 1.1 design by jide powered by Wordpress get firefox