Hi,
I was working on a KCM server for SSSD for some time already in parallel
with the files provider and had some discussions with Simo as well. Of
course my intent wasn't to implement a feature secretly without a design
review, but to have a prototype to base a proper design on :)
However it makes sense to have a peer-reviewed design page now, also
because of Fedora's move towards Kerberos and KDC proxy, which leads to
questions on the Fedora lists about ccache renewals and so on -- so I
think it makes sense to pitch the design to Fedora at least already..
Here is the design page:
https://fedorahosted.org/sssd/wiki/DesignDocs/KCM
and here is the code of the KCM responder so far:
https://github.com/jhrozek/sssd/tree/kcm
Time-wise, I would like to pivot to return to working on KCM now that the
files provider is more or less done and tested.
For your convenience, the design page text is included below as well.
= KCM server for SSSD =
Related ticket(s):
*
https://fedorahosted.org/sssd/ticket/2887
External links:
* [
http://k5wiki.kerberos.org/wiki/Projects/KCM_client MIT wiki KCM documentation]
=== Problem statement ===
This design page describes adding a new SSSD responder, called
`sssd_kcm`. This component would manage Kerberos credential caches and
store them in SSSD's secrets storage.
=== Use cases ===
* A sysadmin needs to deploy applications in containers without worrying about
applications clobbering each other's credential caches in a kernel keyring as keyrings
are not namespaced
* A user wants to keep having her Kerberos ticket automatically renewed regardless of the
ticket being acquired through a PAM conversation with SSSD or from the command line with
kinit
* A system admin wants to leverage a collection-aware credentials cache for most of
applications on their systems, yet enable a legacy application that can only work with a
FILE-based ccache to interoperate with them
=== Overview of the solution ===
Over time, both libkrb5 and SSSD used different credential cache types
to store Kerberos credentials - going from a simple file-based storage
(`FILE:`) to a directory (`DIR:`) and most recently a kernel-keyring based
cache (`KEYRING:`).
Each of these caches has its own set of advantages and disadvantages. The
`FILE` ccache is very widely supported, but does not support multiple
primary caches. The `DIR` cache does, but creating and managing the
directories including proper access control can be tricky. The `KEYRING` cache
is not well suited for cases where multiple semi-isolated environments
might share the same kernel. Managing credential caches' lifetime is not
well solved in neither of these cache types automatically, only with the
help of a daemon like SSSD.
An interesting credentials cache that might solve the issues mentioned above
is `KCM`. With KCM, the Kerberos caches are not stored in a "passive"
store, but managed by a daemon. In this setup, the Kerberos library
(typically used through an application, like for example, `kinit`) is a
"KCM client" and the daemon is being referred to as a "KCM server".
Having the Kerberos credential caches managed by a deamon has several
advantages:
* the daemon is stateful and can perform tasks like Kerberos credential cache renewals
or reaping old ccaches. Some tasks, like renewals are possible already with SSSD, but only
for tickets that SSSD itself acquired (typically via a login through `pam_sss.so`) and
tracks. Tickets acquired otherwise, most notably though kinit wouldn't be tracked and
renewed.
* since the process runs in userspace, it is subject to UID namespacing,
[
http://www.projectatomic.io/blog/2014/09/yet-another-reason-containers-do...
unlike the kernel keyring]
* unlike the kernel keyring-based cache, which is entirely dependant on UIDs of the
caller and in a containerized environment is shared between all containers, the KCM
server's entry point is a UNIX socket which can be bind-mounted to only some
containers
* the protocol between the client and the server can be extended for custom operations
such as dumping a cache in a different format to a specific location. This would be
beneficial for applications that only understand a certain Kerberos ccache type - for
example, some legacy applications only know how to deal with a FILE-based cache, thus
preventing the use of cache collections
Only the Heimdal Kerberos implementation currently implements a KCM server,
but both Heimdal and MIT implement the client-side operations (in libkrb5)
to manage KCM-based Kerberos ccaches. This design page describes adding a
KCM server to SSSD. While it's of course possible to create a completely
standalone deamon that would implement a KCM server, doing so in the
context of SSSD has several advantages, notably:
* An easy access to the authentication provider of SSSD that already has existing and
tested code to renew Kerberos credentials on user's behalf
* SSSD already has a D-Bus API that could publish information about Kerberos tickets
and for example emit signals that a graphical application can consume
* SSSD has a 'secrets provider' to store data at rest. It makes sense to
leverage this component to store Kerberos ccaches persistently
=== Implementation details ===
A new SSSD responder will be added. Since accessing the Kerberos credentials
is quite an infrequent operation, the responder will be socket-activated.
This responder would implement the same subset of the KCM protocol the MIT
client libraries implement. Contrary to Heimdal's KCM server that just
stores the credential caches in memory, the SSSD KCM server would store
the ccaches in the secrets database through the sssd-secret's responder
[
https://jhrozek.fedorapeople.org/sssd/1.14.2/man/sssd-secrets.5.html public REST API].
For user credentials the KCM Server would use a secrets responder URI
like `/kcm/users/1234/X` where 1234 is the user ID and X is the residual.
The client then gets assigned a KRB5CCNAME of KCM:1234:X. Internally in the
secrets responder we will store the credential caches under a new base DN
`cn=kcm`.
The secret responder's quota on secrets must be made modular to allow
different number of secrets per base DN (so, different number of secrets
and credentials pretty much). What to do in case the quota is reached is
debatable - we should probably first remove service (non-TGT) tickets first
for valid TGTs and if that's not possible, just fail. A failure in this
case would be no different than a failure if a disk is full when trying
to store a FILE-based ccache.
The KCM responder would renew the user credentials by starting a tevent
timer which would then contact the SSSD Data Provider for the given UID
and principal, asking for the credentials to be renewed. Another tevent
timer would reap and remove a ccache that reaches its lifetime.
In the future, SSSD-specific operations such as writing out a FILE-based
ccache might be added. The SSSD D-Bus interface would also be extended to
publish information about credentials activity (such as - a ticket being
acquired, a ticket was renewed etc)
=== Configuration changes ===
No KCM-specific configuration options will be added. The SSSD KCM responder
would use the same common options like other SSSD services such as idle
timeout.
We can add a configurable KCM socket location later, if needed, but for
the start it's fine to default to `/var/run/.heim_org.h5l.kcm-socket`
mostly because that's what MIT defaults to as well.
'''Q''': Should we add an option to explicitly enable ccache
renewals and
default to no renewals? I don't think this would any any security though,
the attacker can just run 'kinit -R' on behalf of the user anyway.
=== How To Test ===
In order for the admin to start using the KCM service, the sssd-kcm
responder's systemd service must be enabled. Then, libkrb5 must also be
configured to use KCM as its default ccache type in `/etc/krb5.conf`
{{{
[libdefaults]
default_ccache_name = KCM
}}}
After that, all common operations like kinit, kdestroy or login through
pam_sss should just work and store their credentials in the KCM server.
The KCM server must implement access control correctly, so even
trying to access other user's KCM credentials by setting KRB5CCNAME to
`KCM:1234:RESIDUAL` would not work (except for root).
Restarting the KCM server or rebooting the machine must persist the tickets.
As far as automatic unit and integration testing is required, we need to make
sure that MIT's testsuite passes with Kerberos ccache defaulting to KCM
and SSSD KCM deamon running. In the SSSD upstream, we should write
integration tests that run a MIT KDC under socket_wrapper to exercise the
KCM server.
=== How To Debug ===
The SSSD KCM server would use the same DEBUG facility as other SSSD
services. In order to debug the client side operations, setting the
`KRB5_TRACE` variable might come handy.
When debugging the setup, the admin might also inspect the SSSD secrets
database (if permissable by SELinux policy) to see what credential caches
have been stored by the SSSD.
=== Authors ===
* Jakub Hrozek <jhrozek(a)redhat.com>
* Simo Sorce <simo(a)redhat.com>