Kea: Kea GSS-TSIG Hooks Library

| Kea 3.2.0-git

Kea GSS-TSIG Hooks Library

Welcome to Kea GSS-TSIG Hooks Library.

This documentation is addressed at developers who are interested in internal operation of the library. This file provides information needed to understand and perhaps extend this library.

This documentation is stand-alone: you should have read and understood Kea Developer's Guide and in particular its section about hooks: Hooks Developer's Guide.

# Overview

The `gss_tsig` library provides support for GSS-TSIG.

# References

GSS-TSIG is at the end of different protocols:

- Kerberos 5: a security protocol developed for the MIT Athena project since 1983. The version 5 is the last one and was published in RFC 4120.
- GSS-API (Generic Security Services Application Program Interface) is a protocol independent API even it is mainly used with Kerberos 5. The last version of GSS-API with Kerberos 5 is specified in RFC 4121.
- The GSS-API itself is in RFC 2743 and its C bindings in RFC 2744 (C++ bindings are in the gss_tsig_api.h file).
- The protocol used to negotiate the security setup is SPNEGO (SPNEGO Simple and Protected GSSAPI Negotiation Mechanism) described in RFC 4178.
- The mechanism to protect DNS exchange is TSIG (RFC 2845 updated by RFC 4635 and RFC 8945).
- The TKEY Resource Record defined in RFC 2930 transports opaque crypto payloads between a client and a server.
- GSS-TSIG described in RFC 3645 is a reuse of TSIG using GSS-API to setup a security context used to perform crypto signature creation and verification.

To summary the GSS-API with Kerberos 5 using SPNEGO establishes a security context using TKEY to transport opaque tokens between a client and a server. When the security context is established it is used to protect DNS exchanges, typically DNS dynamic updates using GSS-TSIG.

For this hook:

- TSIG is implemented in the DNS++ library
- TKEY was added to the DNS++ library
- Kerberos 5 and SPNEGO are not directly used
- remains the GSS-API itself (using the C Kerberos 5 API)

# GSS-API

There are 3 important kinds of objects in GSS-API:

- names, here Kerberos 5 files
- credentials which are crypto data associated to a name, including for the client / initiator side a notion of default credential
- security context which allows crypto signature creation and verification.

So only important operation is to establish a security context. This operation is different in the initiator and the responser sides but is based on the same schema: a function (init for the initiator and accept for the responder) is called with input and output tokens until the returned status is "complete" vs "continue". The output token is sent to the other side which uses it as the input token. The first step is to provide an empty token to the init function.

# Commands

The `gss_tsig` hooks library supports some commands:

- gss-tsig-list returns the ID of all configured DNS servers and the name of all GSS-TSIG keys.
- gss-tsig-get-all returns all configured DNS servers with their GSS-TSIG keys.
- gss-tsig-get returns the configured DNS server with the given server-id.
- gss-tsig-key-get returns the GSS-TSIG key with the key-name FQDN.
- gss-tsig-key-expire changes the status of the GSS-TSIG key with the key-name FQDN to expired.
- gss-tsig-key-del deletes the GSS-TSIG key with the key-name FQDN.
- gss-tsig-purge-all removes expired and in error GSS-TSIG keys.
- gss-tsig-purge removes expired and in error GSS-TSIG keys for the DNS server with the given server-id.
- gss-tsig-rekey-all rekeys the GSS-TSIG keys for all configured DNS servers.
- gss-tsig-rekey rekeys the GSS-TSIG key for the DNS server with the given server-id.

# Library Internals

## Framework

The structure of the library is very simple and contains:

- the hook library callouts (see gss_tsig_callouts.cc).
- the single instance of the hook library implementation `GssTsigImpl` (see gss_tsig_impl.h).
- the configuration container `GssTsigCfg` which stores the mapping between the hook configured DNS servers (`DnsServer`) and the kea-dhcp-ddns (D2) configured DNS servers (`d2::DnsServerInfoPtr`) in addition to all hook library parameters (see gss_tsig_cfg.h). For a complete list of parameters see the GSS-TSIG ARM section.
- the implementation of the `ManagedKey` which is the GSS-TSIG TKey managed by the hook library (see managed_key.h) and extends the `GssTsigKey` (see gss_tsig_key.h) which in turn extends the `d2::D2TsigKey`.
- the implementation of the `TKeyExchange` which manages the GSS-TSIG TKey exchange with the DNS server (see tkey_exchange.h).
- the implementation of the `TSIGContext` used to sign and verify GSS-TSIG DNS messages, which extends the `dns::TSIGContext` (see gss_tsig_context.h).
- the implementation of the GSS-API C++ wrapper using the C Kerberos 5 API: `GssApiBuffer`, `GssApiName`, `GssApiCred`, `GssApiSecCtx`, `GssApiOid`, `GssApiOidSet` (see gss_tsig_api.h).

## Callouts

The select_key hook point is used by the D2 server to select the key for the DNS update for the current server. If GSS-TSIG is not enforced (fallback is set to true), then non GSS-TSIG key (TSIG Key or none) will be used, but if GSS-TSIG is explicitly required (default: fallback is set to false), then the current server is skipped (by setting the NEXT_STEP_SKIP flag). If the current DNS server is not skipped, the respective TKey context (none, simple TSIG or GSS-TSIG) will be used to sign and verify the DNS updates. The d2_srv_configured hook point is used to set up internal io service and validate the hooks library configuration. At this stage the mapping between the hook configured DNS servers and the kea-dhcp-ddns (D2) configured DNS servers is done. The multi_threading_compatible indicate that the hook library is multi-threaded compatible, even though the D2 server does not currently use multiple threads to process DNS updates. The following hook points are used for commands only: get, get_all, lists, key_get, key_expire, key_del, purge, purge_all, rekey, rekey_all.

## The automatic key expiration and rekey process

The hook library will automatically check for expired keys after each rekey-interval seconds. It will also check if any key has been created more than rekey-interval seconds ago so that a new key is created before the respective one expires. The rekey-interval is recommend between 50% and 80% of the tkey-lifetime value. If any error occurs, the process is scheduled again after retry-interval seconds. The retry-interval must be smaller than the rekey-interval value, and should be at most 1/3 of the difference between tkey-lifetime and rekey-interval. The key expiration is also checked whenever a key is searched for the current DNS server, so that no expired key is used.

# Choice of the C++11 chrono clock

This stands for all other uses of the system C++11 chrono clock in Kea but for GSS-TSIG this choice raised some questions so the choice of the system clock vs steady clock or high resolution clock is explained here:

- the high resolution clock has only a nice property: its high resolution which has no interest in the GSS-TSIG particular case where a second granularity is enough.
- the steady clock is monotonic: this should have made it the best choice for the code itself without a stronger argument.
- the system clock is real time i.e. it provides direct conversions to and from the C time_t type including textual representations. This is critical for user interface so for convenience it was chosen.

# Multi-Threading Compatibility

The `gss_tsig` hooks library is compatible with multi-threading but can be used only by the D2 server which is not yet multi-threaded.