Concepts / Identity and access

Identity and access

Kerberos

Also called KDC, ticket-granting ticket, TGT, service ticket, kinit, keytab, principal, realm, GSSAPI, krb5, Active Directory

A ticket system that lets one password login open many services, each proven with a ticket, never the password again.

A trusted KDC (Key Distribution Center) knows every user's and server's key. kinit sends the KDC a timestamp encrypted with the user's key (pre-authentication) and gets a ticket-granting ticket (TGT), sealed with the KDC's own key. To reach a server, the client trades the TGT at the KDC's ticket-granting service for a service ticket, sealed with that server's key; the server opens it with its key from a keytab file and never contacts the KDC. Everything is named by principal (alice@REALM, host/server.lab@REALM), so names and DNS must agree, and every ticket carries a timestamp and lifetime, so clocks must be close (within the clockskew) and a stolen ticket dies at its expiry. Windows Active Directory logins are Kerberos.

How Kerberos works, step by step

In the Kerberos lab the realm is OFFICE.LAB. The KDC (10.0.1.10, MIT krb5) knows every key; shellServer (.11) holds its own in a keytab; alice works on the laptop (.12). Kerberos v5 is RFC 4120, on UDP and TCP port 88.

  1. AS_REQ without proof. kinit alice asks the Authentication Service for a ticket to krbtgt/OFFICE.LAB. Every principal here needs pre-authentication, so the KDC answers KDC_ERR_PREAUTH_REQUIRED (logged as NEEDED_PREAUTH).
  2. AS_REQ with PA-ENC-TIMESTAMP. The client sends the current time encrypted with a key derived from alice's password. The KDC decrypts it with its copy of her key, checks the time is within the clock skew (300 s here), and answers AS_REP: the TGT, sealed with the krbtgt key, plus a session key encrypted for alice. The password itself never crosses the network.
  3. TGS_REQ. To reach host/shellserver.lab, the client sends the TGT and an authenticator (a fresh timestamp sealed with the session key) to the Ticket-Granting Service.
  4. TGS_REP. The KDC returns a service ticket sealed with shellServer's key, and a new session key.
  5. AP_REQ. The client gives the service ticket and a new authenticator to the server (over GSSAPI, RFC 4121). The server opens the ticket with its keytab, checks the authenticator's time, and knows it is alice. It never contacts the KDC.
  6. AP_REP. With mutual authentication, the server proves it opened the ticket, so the client knows it reached the real server.

Tickets carry start and end times (10 hours here). Names are exact: a ticket is for a principal, never an address.

What it looks like on a Linux machine

Before kinit there is no cache, and a login has nothing to present:

$ klist
klist: No credentials cache found (filename: /tmp/krb5cc_0)
$ gss-client -port 4444 shellServer.lab host@shellserver.lab hello
GSS-API error initializing context: No Kerberos credentials available (default cache: FILE:/tmp/krb5cc_0)

After kinit and one login, the cache holds the TGT and a service ticket:

$ klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: alice@OFFICE.LAB

Valid starting     Expires            Service principal
10/10/26 18:18:39  10/11/26 04:18:39  krbtgt/OFFICE.LAB@OFFICE.LAB
10/10/26 18:18:39  10/11/26 04:18:39  host/shellserver.lab@OFFICE.LAB

The KDC logs each exchange (etype lists trimmed):

AS_REQ 10.0.1.12: ISSUE: alice@OFFICE.LAB for krbtgt/OFFICE.LAB@OFFICE.LAB
TGS_REQ 10.0.1.12: ISSUE: alice@OFFICE.LAB for host/shellserver.lab@OFFICE.LAB

The server's key, one line per encryption type, readable by root only:

$ klist -k /etc/krb5.keytab
Keytab name: FILE:/etc/krb5.keytab
KVNO Principal
---- --------------------------------------------------------------------------
   2 host/shellserver.lab@OFFICE.LAB
   2 host/shellserver.lab@OFFICE.LAB
$ kvno host/shellserver.lab
host/shellserver.lab@OFFICE.LAB: kvno = 2

What goes wrong, and how you see it

Asking by address. kvno host/10.0.1.11 fails with Server host/10.0.1.11@OFFICE.LAB not found in Kerberos database. Use the name the principal was made for, and keep DNS forward and reverse in step with it.

Ticket expired. After the lifetime ends a login fails with GSS-API error initializing context: Ticket expired. Run kinit again; long-running jobs use a keytab or renewable tickets.

Clocks apart. More than the clockskew (default 300 s) off, and kinit says Clock skew too great while getting initial credentials. Run NTP (chrony) on every machine.

The server lost its keytab. The KDC still issues tickets, but the server cannot open them. Fetch the key again with kadmin -q 'ktadd host/shellserver.lab'; that bumps the KVNO, so older tickets stop working.

A readable ticket cache. A cache file anyone can read is as good as the password until it expires (pass the ticket). Keep caches mode 600, and lifetimes short.

Questions people ask

What port does Kerberos use? 88, UDP and TCP; replies too big for UDP move to TCP. Password changes use 464, and MIT's kadmind 749.

Kerberos vs LDAP? Kerberos proves who you are with tickets; LDAP stores who people are and their groups. Active Directory runs both.

Is Kerberos single sign-on? Yes, inside one realm: one kinit gives tickets for every service. Single sign-on on the web does the same with SAML or OpenID Connect tokens.

See it on real machines

Learn it on real machines.

Every lab is a small network of real Linux machines in your browser. Start with a free account: Google or email, no card.

Open this lab