Kerberos, after all, is the security/authentication mainstay of the traditional, pre-container IT world, with its stable addresses, persistent resources, and here-today-still-here-two-years-from-now continuity. Docker containers, on the other hand, are a swarm of fireflies, popping in and out of existence as needed. How can they coexist? How can they work together?
Let me explain in this post…
Kerberos has, since its development at MIT in the 1980s, become one of the most widely used systems for authentication in IT. Its internal workings (and in most cases, even its presence) are well-hidden not only from end users (who can simply enter their passwords without worrying about what happens behind the scenes), but in many respects, from software developers as well.
Basic Kerberos Architecture
Kerberos was originally designed to operate in a network environment (as part of the MIT/DEC/IBM Project Athena on-campus distributed computing system), and this more-or-less-conventional-network origin is still apparent, even in its current incarnation (Kerberos 5). It consists of an authentication system (made up of an authentication server, a key distribution server, and a ticket-granting service), a set of clients, and a set of service principals.
Clients send requests for services provided by the service principals; the authentication server manages the authentication of those requests. Clients typically represent the role of end-use, and service principals generally represent services available on the network, but the basic Kerberos architecture can be used for authentication in almost any situation where a network-based, client-service relationship exists.
The actual process of authentication is complex. The messages passed between the authentication system, the client, and the service principal during this process are of three types: cleartext requests, encrypted messages which only the authentication system can decrypt, and messages which the client and/or service principal can decrypt.
In an extremely simplified form, the basic process works as follows:
1. The client sends a cleartext request for a service (provided by a specific services principal) to the authentication server. The request does not contain any passwords or keys.
2. The authentication server sends the client a Ticket-Granting Ticket (which only the authentication server can decrypt) and a session key, which the client can decrypt, using a password-dependent hash.
3. The client and authentication server then go through one or two more back-and-forth stages of the same type to establish client authentication, and to generate a ticket and session key which the client can send to the service principal’s service server.
4. The client and the service server follow a similar series of steps to authenticate each other, after which the service principal provides the requested service.
This description necessarily leaves out a large number of important elements of the process. Some of these elements, such as the internal structures of the messages, remain fairly consistent regardless of the environment in which Kerberos operates.
Others, including GSS-API (Generic Security Service Application Program Interface) and SPNEGO (Simple and Protected GSSAPI Negotiation Mechanism), resolve authentication requests at the system level. They function as layers of abstraction between the authentications server and the clients/service principals.
Still others, such as keytabs (tables listing clients/service principals and their authentication keys), SPNs (Service Principal Names, the identifiers for service principals), and delegation (the process of using the client’s authentication to access a service beyond that originally requested) can be important factors in configuring Kerberos for a specific environment.
Kerberos and Docker
How does all of this work in a container-based environment? After all, you might expect Kerberos (or the equivalent) authentication to be handled at the frontend, host system, or cloud service provider level, rather than within the container system.
If you’re deploying container-based applications locally, however, in a non-cloud, bare-metal environment, provider-based methods of authentication are not going to apply, and you will need to deal with the questions raised by using Kerberos with containers.
Containers as Moving Targets
Many of the basic features of Kerberos assume that clients and service principals will have permanent addresses by which they can be identified, and that the entire authentication process will occur in a stable network environment, but containers are much more like moving targets. If services are container-based, for example, will individual containers need to be represented by SPNs?
It seems impossible to reconcile a container, created to perform a specific purpose at a specific time, then destroyed, with the need for a stable, address-based identifier. And is there any reasonable way to delegate authentication, another identifier-based process? In general, how can the address-based elements of Kerberos be reconciled with the changing landscape of a container-system deployment?
Kerberos does need stable identifiers, but it is not tied to low-level, basic-infrastructure identifiers such as IP addresses. It is, in fact, relatively agnostic regarding resource identification systems, and is generally quite compatible with LDAP (Lightweight Directory Access Protocol), with which it is widely used, as well as Active Directory.
Container systems such as Docker, for their part, can be flexible in the way that they represent containers to users, and to the host system. An individual container represents an individual instance of a service, but it is not the service itself. The service can be provided by any instance of that type of container; from the point of view of a client, the identity of an individual instance of that service simply doesn’t matter.
In fact, container-management systems routinely abstract such services, placing large numbers of containers representing a specific service behind a single identifier (such as a Kubernetes cluster).
This means that SPNs, for example, do not need to be tied to individual containers. They can instead be tied to the stable identifiers given to abstract groups of containers. Other Kerberos elements, including keytabs and authentication delegation, can also deal strictly with such abstract identifiers, rather than individual containers.
Kerberos and Docker? The answer is yes, they do work together, and they work together well. And as is so often the case when bringing together seemingly disparate parts of the software/IT world, the proper use of abstraction is the glue that binds them together.
Follow us on Twitter
Follow us on Twitter for real time updates on the cloud native ecosystem, Twistlock product, and cloud native security threats.
How My Company (Teckro) Uses ContainersRead the Blog
Mitigating CVE-2019-5736 Impacting RunC and DockerRead the Blog
From Agile to DevSecOps and DevOps SecurityRead the Blog
What’s Next for Cloud-Native Infrastructure Technology?Read the Blog
Cloud Native Security Beyond Your Cloud Vendor’s ToolsRead the Blog