The basics of Kerberos

For my own reference/sanity while implementing/configuring delegation on linux in java. Likely full of errors, please help...

Authentication

Client needs to log in to the authentication service without sending their password over the network

  1. Client sends a message to the authentication server that they want to request a service
  2. The authentication server sends back 2 messages
  3. If the client can decrypt the session key then the client can save the TGT

Authorization

We can use this TGT to authorize our user to the service

  1. Client sends 2 messages to the ticket-granting server (TGS)
  2. The TGS decrypts and validates the ticket it issued earlier to get the session key, then uses the session key to decrypt the authenticator
  3. The TGS sends back 2 messages

Service Request

This new client-service ticket is used to send the service the new session key and proves the user's identity.

  1. Similarly to the client-TGS communication the client sends 2 messages to the service
  2. If the service can decrypt the ticket using its own key, extract the session key, then decrypt and validate the authenticator, the request is valid
  3. The service sends back the timestamp from the decrypted ticket encrypted with the session key so that the client knows that the service is valid

Java Integration

Ensure capitalization is correct!

Set system properties

System.setProperty("java.security.auth.login.config", "/tmp/login.conf");
System.setProperty("java.security.krb5.conf","/etc/krb5.conf");
System.setProperty("java.security.krb5.realm","EXAMPLE.COM");
System.setProperty("java.security.krb5.kdc","kerberos.example.com");
System.setProperty("javax.security.auth.useSubjectCredsOnly","false");

login.conf

KrbLogin {
  com.sun.security.auth.module.Krb5LoginModule required
  useKeyTab=true
  storeKey=true
  keyTab="file:///etc/krb5.keytab"
  useTicketCache=true
  principal="HTTP/localhost@EXAMPLE.COM"
  debug=true;
};

com.sun.security.jgss.initiate {
  com.sun.security.auth.module.Krb5LoginModule required
  useKeyTab=true
  storeKey=true
  keyTab="//etc/krb5.keytab"
  useTicketCache=true
  principal="HTTP/localhost@EXAMPLE.COM"
  debug=true;
};

krb5.conf

[libdefaults]
    default_realm = EXAMPLE.COM

[realms]
    EXAMPLE.COM = {
        admin_server = kerberos.example.com
        kdc = kerberos.example.com
    }

[domain_realm]
    example.com = EXAMPLE.COM
    .example.com = EXAMPLE.com

[logging]
    kdc          = SYSLOG:NOTICE
    admin_server = SYSLOG:NOTICE
    default      = SYSLOG:NOTICE

Credential Delegation (forwardable vs. proxiable tickets)

In Windows 2000 delegation works by "trusting" a machine for delegation and then allowing that machine to forward a user's TGT to a remote service. Two issues:

  1. The "trusted" machine can impersonate the user to any other service
  2. The user must be authenticated to the machine

So if you have a web server that's only exposed to the internet through a proxy the user accessing your web server can't request that the service on the web server delegates their credentials without the site administrator exposing the KDC to the internet. The solution was to create a series of Service-for-User (S4U) extensions.

Service-for-User-to-Proxy (S4U2Proxy)

Instead of forwarding the user's TGT, this extension presents the user's service ticket to the KDC to prove the user's identity. This works well for establishing trust but still requires that the user is authorized to the service through Kerberos exposing the KDC to the user's network.

Service-for-User-to-Self (S4U2Self)

This extension defines a "protocol transition" service that allows for interoperability of Kerberos and the authentication protocols between the user and the intermediate web service. The distinction between this and S4U2Proxy is that the web service is required to have a valid TGT. The configuration of the gateway service specifies the SPNs for which delegation is allowed as well as the port and/or protocol.

Notes