Index

FO104

Title

crypto-config - a framework to manage crypto-related configurations system-wide

Status

Approved

Authors

Adrien Nader

Type

Standard

Created

2022-11-17

Reviewer

Status

Andreas Hasenack

Approved Sep 19, 2024

Michael Hudson-Doyle

Approved Aug 16, 2024

Seth Arnold

Approved Oct 15, 2024

Tobias Heider

Approved Sep 10, 2024


Abstract

Cryptography configuration is unique among types of configuration: it may need to be updated multiple times over the lifetime of a system or a cluster while requiring consistency across all installed software.

We want to offer a way to choose a system-wide crypto configuration among several consistent and supported alternatives.

This specification defines a framework made of tools and policy. The policy affects package building and software behavior. Tools are used for system administration.

This specification puts a greater emphasis on policy rather than tools, as the policy will serve as the foundation for the design and implementation of tools in the future.

Aside: crypto-what?

In this document we use “crypto” to mean basically anything that gnutls or openssl provide. This includes but is not limited to: cryptography primitives, SSL and TLS implementations, and certificate handling.

In addition, we define ‘crypto providers’ which expose crypto APIs and implement protocols and algorithms, and ‘crypto users’ which consume these. A user can also be a provider.


Table of contents

Abstract

Aside: crypto-what?

Table of contents

Forewords

Current implementation

The issues at stake

Lack of consistent configuration: case study on Mantic Minotaur

Moving security forward

Crypto-config overview

Applicability to non-crypto domains

State of the art: Fedora’s crypto-policies

Rationale for a new policy and tools

User stories

Other constraints, motivations and design goals

Specification

Constants used in the specification

In a nutshell

Overview

Policy

Paths

Profiles design

Profile inheritance

Packages

User-facing tool

Configuration sealing

Statically-linked crypto providers

Affected packages

Crypto providers

Crypto users

Example: usefulness with krb5

Known Limitations and Future work

Known Limitations

Future work

Further Information

Annex: bits of security, comparable algorithm strengths, and boiling oceans

Annex: Possible work split

Annex: relationship with distribution upstreams (Debian) and downstreams (Ubuntu derivatives)

Annex: Example report following package install or removal

References

Spec History and Changelog

Forewords

This specification is long. It touches many topics and many pieces of software. Not everything can be explained linearly unfortunately and Google docs is not entirely helpful as it is very limited. That being said, I believe the specification is consistent and the puzzle will become a clear picture by the end of the document.

In order to ease reading, I am introducing notes at the beginning of sections. These are not the specification but rather some context around it. They are displayed as follows:

💡This is an informative text.

Color is copied from the venerable dokuwiki "note" plugin which most recent version is hosted at https://github.com/lpaulsen93/dokuwiki_note and is released under the GPLv2. The plugin uses round corners but the best I can do with google docs is a 1-cell table with ugly hard corners.

It should be noted that this document has been authored in Google Docs. Not all export formats can be used reliably unfortunately: markdown is fine when diagrams and non-docs resources are not used while PDF appears to work for everything but is less convenient to handle. As such, this specification will be exported and published first using the markdown export and a PDF export will also be provided for reference.

Current implementation

There is already a partial implementation of the specification available. It is hosted on github.com/canonical/crypto-config.

It contains the integration with dpkg using a post-inst trigger. It also handles profile inheritance, albeit with the parent being set using a bare text file rather than JSON because the current implementation is a shell script. This is planned to be solved when re-writing the implementation in Rust, which will also feature a more complete UI.

The issues at stake

NB: A lightning talk on this topic was given at the Ubuntu Engineering Sprint in Riga in November 2023.

There are several libraries in Ubuntu implementing cryptographic algorithms (ciphers, hashes, …) and protocols (TLS, SSH, …). Hundreds of packages offer crypto-related configurations and these usually take precedence over system-wide library configuration. At least Java, Golang and Rust have their own crypto libraries. This amounts to hundreds if not thousands of configurations to perform. Moreover, several aspects are tricky to get right and version changes can cause breakage.

Lack of consistent configuration: case study on Mantic Minotaur

Software

Nginx

Apache

Mariadb

Postgres

Mysql

Exim

Rabbitmq

Ciphers

Baseline

Baseline

CAMELLIA

ARIA

CCM

Baseline

CHACHA20

POLY1305

CCM

ARIA

CAMELLIA

AES-SHA>128

ARIA

CAMELLIA

ECDH

Key

Exchange

Baseline

Baseline

Baseline

P-256 only

P-256

x25519

x448

ffdhe*

TLS1.3: CCM

P-384

P-512

x25519

x448

TLS1.3: CCM

P-256

brainpool

sect*

secp*

Bonus

Actually:

TLS1.2: AES128

TLS 1.0

TLS 1.1

TLS 1.0

TLS 1.1

Erlang OTP

At the moment (Mantic Minotaur), there are countless differences between the default cryptographic configuration of packages in the archive, especially for TLS. The results below have been obtained by enabling TLS support and configuring a certificate in nginx, apache, mariadb, postgresql, mysql, exim and rabbitmq. No further step was carried on in order to find what is the closest to a default configuration. It is likely that users run with these configurations, as can be seen through censys.io (internet-wide host scan database) which shows a large number of ubuntu machines running exim with TLS 1.0 and 1.1 enabled.

Compared to nginx' configuration:

The topic here is not about which configuration is better but how users can be anything but lost with so many widely different configurations.

Moving security forward

💡Using the same cryptography configuration for all software on Ubuntu and for all Ubuntu users actually means sticking to legacy and lenient configurations.

We need configuration values that are consistent per-ecosystem rather than across the distribution in order to not tie ourselves to the slowest moving ecosystems (i.e. e-mail).

How to make our default configurations be on the forefront rather than trailing?

Standards or good practices typically mandate sets of algorithms but not all algorithms from these sets are the same. These sets typically include some algorithms meant for the future, some for current usage and some for compatibility with legacy systems in order to maintain compatibility over time and be able to gradually update systems.

Completely forbidding deprecated algorithms in crypto providers is possible (although this will sometimes involve writing code). Is it enough?

As explained above, at any given time, we are likely to enable some algorithms for compatibility with legacy. Should they be enabled system-wide by default though? And if they're disabled by default, should enabling them always be system-wide?

I argue that we should aim to disable legacy algorithms and protocols by default and enable them per-application based on every application's environment. TLS 1.3 is understood by 97% of the used web browsers while TLS 1.2 (our current minimum) is understood by 98% of them. The difference is old and non-updated browsers; should we be held behind because of them? On the other hand, mail servers probably still require TLS 1.2 in many cases. As such, we might want something like the following:

 Relative security ^

                   |

+-----------------+| +---+  +---+  +---+

| Modern {g}      || |   |  | N |  | p |

+-----------------+| |   |  | g |  | s |

                   | | E |  | i |  | q |

+-----------------+| | x |  | n |  | l |

| Current {g}     || | i |  | x |  |   |

+-----------------+| | m |  +---+  +---+

┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄+┄+┄┄┄+┄┄┄┄┄┄┄┄┄┄┄┄┄┄

+-----------------+| |   |

| Legacy {o}      || |   |

+-----------------+| +---+

┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄+┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄

+-----------------+| Systemwide  minimum

| Deprecated {r}  ||

+-----------------+|

# Legend:

g = {

    fill: #93c47d;

}

o = {

    fill: #f5b26b;

}

r = {

    fill: #e06666;

}

Crypto-config overview

💡Crypto-config works by introducing an indirection in the path of configuration files. This is as if '/etc' were actually a symlink that you could point to either '/etc-lenient' or '/etc-hardened', except that it only applies to some files that the package maintainer opts into the scheme. The base implementation is 'ln -sfn'!

There is some architectural work to make everything smooth for both Ubuntu developers and users but it is fairly well-bound and this document should cover everything.

The majority of the work is providing meaningful and wise configuration choices to users so that they don't have to face the complexity of configuring everything themselves. In other words, that's typical distribution work.

Applications have their own configuration but they also use libraries which can also have their own configuration. For instance, Nginx reads "default.conf" but it also uses openssl which can read "openssl.cnf". This typical setup is shown below for several applications. In these pictures, each cell in the left column corresponds to the cells on the same line on the right side.

.-----------------------.  |  .-----------------------.   .-----------------------.   .---------.     .-----------------------.   .---------.     .---------.

|   Cryptography User   |  |  |        Apache2        |   |         Nginx         |   |   ...   |     |         Exim4         |   |   ...   |     |   ...   |

'-----------------------'  |  '-----------+-----------'   '-----------+-----------'   '---------'     '-----------+-----------'   '---------'     '---------'

                           |              +-------------.             +-------------.                             +-------------.                           

                           |              |             |             |             |                             |             |                           

                           |              v             |             v             |                             v             |                           

.-----------------------.  |  .-----------------------. | .-----------------------. | .---------.     .-----------------------. | .---------.     .---------.

|     Configuration     |  |  |       ssl.conf        | | |      default.conf     | | |   ...   |     |"03_exim4...tlsoptions"| | |   ...   |     |   ...   |

'-----------------------'  |  '-----------------------' | '-----------------------' | '---------'     '-----------------------' | '---------'     '---------'

                           |                            |                           |                                           |                           

                           |                            |                           |                                           |                           

                           |                            |                           |                                           |                           

                           |                            |                           |                                           |                           

                           |                            |                           |                                           |                           

                           |                            |                           |                                           |                       

                           |                            |                           |                                           |                       

                           |                            |                           |                                           |                       

                           |                            v                           v                                           v                       

.-----------------------.  |  .-----------------------------------------------------------------.     .-------------------------------------.     .---------.

| Cryptography Provider |  |  |                            OpenSSL                              |     |               GnuTLS                |     |   ...   |

'-----------------------'  |  '-------------------------------+---------------------------------'     '------------------+------------------'     '---------'

                           |                                  |                                                          |                               

                           |                                  |                                                          |                               

                           |                                  |                                                          |                               

                           |                                  v                                                          v                               

.-----------------------.  |  .-----------------------------------------------------------------.     .-------------------------------------.     .---------.

|     Configuration     |  |  |                          openssl.cnf                            |     |           "gnutls/config"           |     |   ...   |

'-----------------------'  |  '-----------------------------------------------------------------'     '-------------------------------------'     '---------'

                           |                                                                                                                                 

                           |                                                                                                                                 

                           |                                                                                                                                 

                           |                                                                                                                                 

                           |                                                                                                                                 

With crypto-config, the first idea is to have the following instead: every configuration file can refer to data through the crypto-config framework, therefore making it possible to have a single source of truth for the cryptography configuration.

.-----------------------.  |  .-----------------------.   .-----------------------.   .---------.     .-----------------------.   .---------.     .---------.

|   Cryptography User   |  |  |        Apache2        |   |         Nginx         |   |   ...   |     |         Exim4         |   |   ...   |     |   ...   |

'-----------------------'  |  '-----------+-----------'   '-----------+-----------'   '---------'     '-----------+-----------'   '---------'     '---------'

                           |              +-------------.             +-------------.                             +-------------.                           

                           |              |             |             |             |                             |             |                           

                           |              v             |             v             |                             v             |                           

.-----------------------.  |  .-----------------------. | .-----------------------. | .---------.     .-----------------------. | .---------.     .---------.

|                       |  |  |       ssl.conf        | | |     default.conf      | | |   ...   |     |"03_exim4...tlsoptions"| | |   ...   |     |   ...   |

|                       |  |  '-----------+-----------' | '-----------+-----------' | '---------'     '-----------+-----------' | '---------'     '---------'

|     Configuration     |  |              |             |             |             |                             |             |                           

|                       |  |              v             |             v             |                             v             |                           

|                       |  |  .-----------------------------------------------------------------------------------------------------------------------------.

|                       |  |  |                                                       "crypto-config"                                                       |

'-----------------------'  |  '-----------------------------------------------------------------------------------------------------------------------------'

                           |                            |                           |                                           |                       

                           |                            |                           |                                           |                       

                           |                            |                           |                                           |                       

                           |                            v                           v                                           v                       

.-----------------------.  |  .-----------------------------------------------------------------.     .-------------------------------------.     .---------.

| Cryptography Provider |  |  |                            OpenSSL                              |     |               GnuTLS                |     |   ...   |

'-----------------------'  |  '-------------------------------+---------------------------------'     '------------------+------------------'     '---------'

                           |                                  |                                                          |                               

                           |                                  |                                                          |                               

                           |                                  |                                                          |                               

                           |                                  v                                                          v                               

.-----------------------.  |  .-----------------------------------------------------------------.     .-------------------------------------.     .---------.

|                       |  |  |                          openssl.cnf                            |     |           "gnutls/config"           |     |   ...   |

|                       |  |  '-------------------------------+---------------------------------'     '------------------+------------------'     '---------'

|     Configuration     |  |                                  |                                                          |                                   

|                       |  |                                  v                                                          v                                   

|                       |  |  .-----------------------------------------------------------------------------------------------------------------------------.

|                       |  |  |                                                       "crypto-config"                                                       |

'-----------------------'  |  '-----------------------------------------------------------------------------------------------------------------------------'

While this is enough to cover the majority of applications, there is still an issue with hard-coded values in applications and applications initializing libraries in a way that doesn't parse the library configuration. We would also like to be able to apply changes system-wide by only touching the cryptography provider.

Due to limitations in cryptographic libraries, these will require patches. Such patches exist in Fedora/RHEL but while the ones for e.g. openssl achieve the desired outcome, they probably cannot be upstreamed without large changes.

Consider the source of configuration values in an application like nginx:

  1. defaults in the openssl binaries
  2. openssl configuration
  3. defaults in the nginx binaries
  4. nginx configuration

Today nginx configures the list of enabled ciphers using either a default value built into nginx, or a value which comes from its configuration. There is however no value which means "use what is defined system-wide". A system administrator would have to manually transcribe the system-wide configuration into nginx' configuration. While this is somewhat possible for a single application, it doesn't scale at all. Addressing this situation is the second category of changes for crypto-config.

Both approaches are complementary. Acting at the level of crypto providers ensures no application runs with a forbidden algorithm. Configuring applications directly makes it possible to move some of them forward faster than others: indeed, cryptography for the web has improved much faster than for e-mails which is hindered by backward-compatibility for its federative model.

It is important to keep in mind that in every case, sifting through the Ubuntu archive will be needed in order to ensure packages properly follow this specification. This isn't actually additional work since such an audit is already needed as shown previously.

Applicability to non-crypto domains

Little of what is described below is limited to cryptography. The only reasons to limit this to cryptography are not technical but practical.

Indeed, the goal is to cover a whole domain with a single configuration value and there doesn’t seem to be another field for which this would make sense or be doable.

In the event such a field is found, the process below would result in a second configuration value that is independent from this one anyway. Indeed, the whole point of this approach is to have users not need to consider combinations of options.

State of the art: Fedora’s crypto-policies

💡Here we quickly come back to why adopting crypto-policies from Fedora/RHEL is not useful nor desirable.

We have analyzed Fedora’s crypto-policies as part of US021. It is too RH-specific to use as-is and not interesting enough to reuse and improve upon.

On the plus side, it seems that it properly lets admins of RH systems experience the upcoming change in defaults in RH by running a simple command. People seem satisfied with a small featureset.

However:

My criticism of crypto-policies can be summarized as attempting to solve an uncommon use case in a fully generic way and ending up being so complex that the genericity becomes a hindrance for both developers and users. Moreover, I’d wager that most of the development time is spent on fixing it, leaving no time to make it nice to use. Moreover, writing policies seems time-intensive.

Crypto-policies is however very interesting since it is the only software and process that exists in this space today. It therefore constitutes a comparison point. The project also includes a policy for packaging that we can get inspiration from.

Rationale for a new policy and tools

Fedora has been shipping a ‘crypto-policies’ tool for several years. While its goals appealed to us, we have deemed it not appropriate for Ubuntu. This leaves us with a few choices: a) not provide anything, b) find something else that already exists, c) write something ourselves.

Customers have not yet expressed a strong urge to have such a tool but this is a growing demand and some customers (IBM-cloud) are asking for this. There is also an internal demand for it.

There seem to be no existing tools we could use or at least evaluate. This is not very surprising since one of the reasons we rejected Fedora’s crypto-policies is its complex ties to Fedora as it depends on the rest of the configurations in the distribution, on the software versions and even distribution patches (for instance, there is a special case related to RSA key length for openssh).

While it has been packaged and uploaded to Debian, crypto-policies has never been linked to the reset of the system and it has finally been removed in July 2024. It should be noted that since diverging from Debian is costly, we would prefer something that Debian also adopts or that at least implies a minimal diff. Adoption of policies and tools by Debian does not imply that Ubuntu and Debian will use the same configuration.

This leaves us with writing a tool ourselves. I believe there is a simple path forward that will let us have clearer configuration files that can be easily tweaked by users. I also believe there is a lot of value in bringing this to customers. This is done in baby steps that are also very natural: the risk with each step is minimal and the project can be paused at any time with no need to rollback anything.

User stories

As a sysadmin, I would like to select a configuration policy that applies to all supported services system-wide both for defaults settings and minimum ones.

As a sysadmin, I would like to know which software lowers the crypto settings of its crypto providers.

As a sysadmin, I would like to disable a given algorithm system-wide at a given date (e.g. SHA1 at the end of 2030).

As a sysadmin, I would like to disable a given algorithm system-wide but re-enable it selectively (e.g. a specific machine cannot be upgraded and only supports legacy cryptography).

As a sysadmin or developer, I would like to test a Ubuntu system with some algorithms or protocols disabled in order to assess compatibility (e.g. with upcoming deprecations).

As a developer of software that will run on Ubuntu, I would like to provide users with typical configuration values for them to choose from, reducing documentation burden and support requests.

As an Ubuntu developer, I would like to more easily know which crypto algorithms and configurations are configured and in use.

As a developer of software, I’d like to know which of the myriad of crypto options are recommended and reliable. This ranges from security considerations like “is it secure” to compatibility ones “is it working across all supported Ubuntu releases”.

As an Ubuntu developer, I would like to simplify the task of providing compliant configuration settings by using an integrated system which allows specifying the relevant settings for the various compliance frameworks.

Other constraints, motivations and design goals

In addition to user wishes and needs, there are additional constraints to take into account.

Guarantee consistency and don't break systems

Centralizing configuration risks breaking every related package at once: upgrading the central crypto-config package can break packages which rely on it. The central package should therefore be simple and developed with care in order to minimize this risk.

Handle package upgrades, removals and purges

Care must be taken not to provide fewer guarantees than the usual configuration handling in Debian.

Limit dynamism in configuration

Dynamism can be useful but we want a safe and deterministic system. It should behave similarly as configuration handling in Debian packages and provide at least the same guarantees, especially those of safety.

Don't require lockstep upgrades / transitions

We don't want to lock everything together. Requiring a transition for every crypto provider and user would be terrible.

This implies some dynamism in profiles. Indeed, consider package A which knows profiles X and Y; when adding profile Z, if there is no mechanism to automatically populate A's configuration files for Z, package A must be updated. This would apply to every enrolled package, effectively starting a very large transition. In other words, packages built at a given moment should be forward-compatible with profiles introduced later on.

In order to achieve this kind of compatibility, there must be dynamism after package creation, i.e. when installing. This will involve dpkg triggers as explained in the specification.

Avoid incompatibilities with Debian

As a Debian downstream, deltas are costly and incompatibilities require constant work. Moreover we would like Debian to be able to use this work.

Provisions should be taken to ensure differences with Debian, whether it is not using this work or it is, do not cause undue burden on Ubuntu developers.

Specification

NB: examples in this section use ‘nginx’ because its configuration format is simple; the same can be done with openssl.

Constants used in the specification

DATA_DIR=/usr/share/crypto-config

SYSTEM_PROFILES_DIR=${DATA_DIR}/profiles

STATE_DIR=/var/lib/crypto-config

STATE_PROFILES_DIR=${STATE_DIR}/profiles

SYSCONF_DIR=/etc/crypto-config

SYSCONF_PROFILES_DIR=${SYSCONF_DIR}/profiles

In a nutshell

SYSTEM_PROFILES="${SYSTEM_PROFILES_DIR}"

CURRENT_PROFILE="${STATE_DIR}/current"

### new files:

regular file: ${SYSTEM_PROFILES}/post-quantum/nginx/ssl-ciphers.conf

regular file: ${SYSTEM_PROFILES}/default/nginx/ssl-ciphers.conf

symlink:      ${CURRENT_PROFILE}    to post-quantum/ or default/

### modified with “include ${CURRENT_PROFILE}/nginx/ssl-ciphers.conf":

/etc/nginx/nginx.conf

### Run

crypto-config switch post-quantum

Overview

💡Packages install variants of their cryptography configuration and a post-installation dpkg trigger merges them across applications into profiles.

Users can use a tool to change the system from one profile to another.

There will also be work to ensure all software actually follows the system configuration (proof that all software doesn't work together out of the box: we're still not out of job).

Policy

💡This is mostly the set of rules required for packages to _actually_ use system-wide configurations. For instance, if there is a default set of TLS ciphers configured in openssl, applications can change that to almost anything and they very often do. We will therefore work towards making applications use a system-wide value by default (users can still configure them differently). The number of rules is due to how different every software in Ubuntu is.

Exceptions

Reporting and introspection

💡Some APIs of crypto providers can have a large impact on the effective configuration of the system (e.g. by changing the path of the system configuration to /dev/null, or by changing global options). These APIs also have legitimate usages which makes it impossible to outright forbid them. Moreover, static analysis is limited and does not cover software outside of Ubuntu. It will therefore be useful to dynamically query applications to learn if they have used such APIs.

Paths

💡Packages install configuration snippets in /usr. Running software uses configuration data from under /var/lib. A dpkg trigger reads from /usr and populates /var/lib, handling profile inheritance.

Without crypto-config

.----------------------.                            .----------------------.

|                      |                            |                      |

|     .deb package     |                            |         User         |

|                      |                            |                      |

'-----------+----------'                            '-----------+----------'

            |                                                   |

            |                                                   |

            |dpkg installs                                      |Edits

            |                                                   |

            v                                                   |

.----------------------.                                        |

|                      |                                        |

|     Application      |                                        |

|                      |                                        |

'-----------+----------'                                        |

            |                                                   |

            |                                                   |

            |Reads                                              |

            |                                                   |

            v                                                   |

.----------------------.                                        |

|                      |                                        |

|        Config        |                                        |

|                      |                                        |

|                      |<---------------------------------------'

|                      |

'----------------------'

With crypto-config

.----------------------.                            .----------------------.

|                      |                            |                      |

|     .deb package     |                            |         User         |

|                      |                            |                      |

'-----------+----------'                            '-----------+----------'

            |                                                   |

            |dpkg installs                                      |

            +------------------------.                          |Creates

            |                        |                          |

            v                        v                          v

.----------------------.  .----------------------.  .----------------------.

|                      |  |        Files         |  |         Files        |

|     Application      |  |          in          |  |           in         |

|                      |  | "SYSTEM_PROFILES_DIR"|  |"SYSCONF_PROFILES_DIR"|

'-----------+----------'  '-----------+----------'  '-----------+----------'

            |                         |                         |

            |                         |     "crypto-config"     |

            |Reads                    |        generates        |

            |                         `-----------.  .----------'

            v                                     |  |

.----------------------.                          |  |

|                      |                          v  v

|        Config        |                .----------------------.

|  .----------------.  |      Uses      |       Profiles       |

|  |"crypto-config" +--+--------------->|          in          |

|  '----------------'  |                | "STATE_PROFILES_DIR" |

'----------------------'                '----------------------'

Profiles and dropins collections

+--------------------+ +--------------------+ +--------------------+

| .----------------. | | .----------------. | | .----------------. |

| |GnuTLS  dropins | | | |GnuTLS  dropins | | | |GnuTLS  dropins | |

| '----------------' | | '----------------' | | '----------------' |

| .----------------. | | .----------------. | | .----------------. |

| | Nginx dropins  | | | | Nginx dropins  | | | | Nginx dropins  | |

| '----------------' | | '----------------' | | '----------------' |

| .----------------. | | .----------------. | | .----------------. |

| |OpenSSL dropins | | | |OpenSSL dropins | | | |OpenSSL dropins | |

| '----------------' | | '----------------' | | '----------------' |

| .----------------. | | .----------------. | | .----------------. |

| |      ...       | | | |      ...       | | | |      ...       | |

| '----------------' | | '----------------' | | '----------------' |

+--------------------+ +--------------------+ +--------------------+

 "'Default' Profile"    "'Legacy' Profile"     "'Future' Profile"

Profiles design

💡Designing profiles is a task that requires dedicated work: the data needs to be stored in a way that can be made sense of afterwards. This is initially constraining but mostly one-time work to enable profile inheritance (which is described in a subsequent section), and proper UI/UX for users.

Profile inheritance

💡Profile inheritance creates a profile that uses the same configuration data as another one except for some software. The inheritance is coarse: it occurs at the application-level, not at the level of configuration snippets which would be a much more complicated task, maybe even an undecidable one since that would require parsing every configuration format and making sense of it. If a maintainer (or user) wants to reuse some snippets, it should be done in a traditional way, possibly with symlinks to well-known files.

The inheritance is implemented through a program called every time configuration snippets are touched through a dpkg trigger. The process is deterministic and idempotent and can be used for user-customization (this will work but is not officially supported at this time).

The inheritance process paves the way for user-customized profiles but there are additional aspects to take into account, mostly around conffile handling before officially supporting user-customization.

Example profile inheritance tree

                      +------------+

                      |  Default   |

                      +--+-+--+-+--+

                         | |  | |

      .------------------' |  | '------------------.

      |               .----'  '----.               |

      |               |            |               |

      v               v            v               v

+-----------+  +-----------+  +-----------+  +-----------+

|  Legacy   |  |   FIPS    |  |  Future   |  | Customer- |

|           |  |           |  |           |  | specific1 |

+-----------+  +-----+-----+  +-----------+  +-----------+

                     |

                     v

               +-----------+

               | Customer- |

               | specific2 |

               +-----------+

Example dropins collection re-uses across profiles

    +-----------------------------------------------------------+

    |                                                           |

    |             +------------+  +-----------+  +------------+ |

    | Default     | GnuTLS {g} |  | Nginx {g} |  | OpenSSL {g}| |

 ,->|             +------------+  +-----------+  +------------+ |

 |  |                   ^               ^              ^        |

 |  +-------------------|---------------|--------------|--------+

 |Inherits from         | Reuses        |              | Reuses

 |  +-------------------|---------------|--------------|--------+

 |  |                   |               |              |        |

 `--|             +------------+  +-----------+  +------------+ |

    | Legacy      | GnuTLS {b} |  | Nginx {g} |  | OpenSSL {b}| |

 ,->|             +------------+  +-----------+  +------------+ |

 |  |                   ^               ^              ^        |

 |  +-------------------|---------------|--------------|--------+

 |Inherits from         | Reuses        | Reuses       |

 |  +-------------------|---------------|--------------|--------+

 |  |                   |               |              |        |

 `--|             +------------+  +-----------+  +------------+ |

    | "Customer2" | GnuTLS {b} |  | Nginx {b} |  | OpenSSL {g}| |

    | "-specific" +------------+  +-----------+  +------------+ |

    |                                                           |

    +-----------------------------------------------------------+

Legend:

+------------+

| <pkg>  {b} | Dropins are symlinks to dropins in another profile

+------------+

+------------+

| <pkg>  {g} | Dropins are regular files in the current profile

+------------+

# Legend:

g = {

    fill: #93c47d;

}

o = {

    fill: #f5b26b;

}

r = {

    fill: #e06666;

}

b = {

    fill: #cfe2f3;

}

Packages

💡Here we go through how crypto-config will be shipped and installed, and its impact on existing packages.

crypto-config

Directly enrolled packages

Other packages

User-facing tool

help, -h, --help                                display command-line help

status                                          show the currently-used profile

switch PROFILE                                  switch to PROFILE

query profile-condition       PROFILE           value of `condition` in PROFILE's metadata

query profile-current                           profile currently in use

query profile-description     PROFILE           value of `description` in PROFILE's metadata

query profile-list-all                          list all profiles, including disabled ones

query profile-list                              list profiles

query profile-maintainer      PROFILE           value of `maintainer` in PROFILE's metadata

query profile-parent          PROFILE           value of `parent` in PROFILE's metadata

query profile-path            PROFILE           value of `path` in PROFILE's metadata

query profile-summary         PROFILE           value of `summary` in PROFILE's metadata

query application-path        PROFILE PACKAGE   location of the profile for PACKAGE in

                                                PROFILE with symlinks not resolved

query application-realpath    PROFILE PACKAGE   location of the profile for PACKAGE in

                                                PROFILE with symlinks resolved

query application-realprofile PROFILE PACKAGE   profile that holds the application-realpath

                                                for PROFILE and PACKAGE

Configuration sealing

💡Writing consistent data in configuration files is wonderful but mostly useless if end-applications don't actually use it! Applications too often don't follow whatever configuration exists for their crypto provider and have their own instead.

Statically-linked crypto providers

💡This section is spurred by Go and Rust which use static-linking and have their own implementations of crypto providers. The issue is more general however: every statically-linked crypto provider raises the same issue.

Static linking is used to de-correlate an application from the system's shared libraries. In Ubuntu, configuration is linked to the system's shared libraries. It follows that static linking de-correlates applications from the system's configuration.

Indeed, an application could ship any version of any crypto provider from the past or from the future relative to a Ubuntu version, and the configuration format, values and consequences could be vastly different.

The issue would be somewhat better if configuration files were versioned but this is rarely the case.

Affected packages

Crypto providers

Crypto providers include at least the following:

There are also providers that are probably not directly affected by this:

We should also keep in mind packages that expose some hardware's acceleration features.

Crypto users

There is no fixed list of crypto users to enroll into this scheme, only guidelines.

The following can be taken into account in order to decide if a package (be it in main or in universe) should be effectively enrolled and with which priority.

There is no guaranteed criteria indeed: if 'md5sum' were relying on gnutls or openssl, it would be a crypto user but enrolling it wouldn't bring any value to users since its behavior would have to remain forever identical, including across profiles.

The most effective criteria is the Depends and Recommends of a package as with the following command-line filter:

grep-dctrl -e 'libssl3|libnss3|libgnutls30|libssh-4|libkrb' -FDepends -FRecommends \

| grep-dctrl -v -e 'universe' -FSection -sPackage

and with this command:

(for i in nss gnutls28 openssl; do reverse-depends -b src:$i -c main -l ; done) | sort | uniq

These two approaches yield respectively 256 packages in main and 1305 with universe, and 162 packages in main and 1027 with universe. These two approaches are not directly comparable and both should be used.

It is important to acknowledge that there will be gaps simply due to the number of packages involved and this is why it is important to take the value for users into account.

Example: usefulness with krb5

Until version krb5 1.20-1, the kdc.conf file shipped with Ubuntu included the following:

master_key_type = des3-hmac-sha1

As far as I understand, this was fixed because the krb5_newrealm outputs a deprecation warning. We would have appreciated that this was found earlier on.

Had this configuration been split into a dedicated file and organized into profiles, it would have been trivial to find it in an automated fashion. Indeed, it would be very easy to automatically extract all files that make up profiles across the archive and analyze them either automatically, or by hand.

Obviously the work leading to splitting this from configuration files would also have been able to surface this issue but this depends on when the splitting is done and what is considered secure at that time.

Known Limitations and Future work

Known Limitations

Missing configuration snippets for a software package when using a user-defined profile

One can imagine situations where the default profile starts using a new configuration snippet, other profiles are not updated to use it.

This is only a small issue for profiles provided by the distribution. It is not actually a new problem: it merely adds new files and paths to manage when updating packages.

This is more an issue for user-designed profiles since they are not updated at the same time. At the moment, user-designed profiles are not supported so we have time to identify issues like this one and address them.

In the future, we can imagine tooling that will identify such issues ahead of time by comparing the set of files in each snippet in order to warn of missing files.

Future work

Creating dh_crypto_config and lintian checks

At the moment, the installation of profiles in packages is manual. They will typically be added under debian/conf/ and listed in debian/foo.install. One could imagine a dh_crypto_config that would install profiles detected under debian/crypto-config . Similarly, lintian could be used to ensure the profiles in a package are consistent.

It is probably too early to add a lot of automation and it is probably better to first get more real-world experience.

Also, debhelper and lintian are written in perl.

Autopkgtest

Profiles change the behavior not only of the package but also of the system. It will be useful to run autopkgtests under various profiles. Maybe the only requirement will be to run tests in a loop, changing profile and restarting services each time. In any case, actual experience developing packages and profiles will probably be useful first.

Autopkgtests will also be most useful as a way to track upstream changes. Conversely, they will also be most needed when there are more than a few packages effectively enrolled.

Further Information

Annex: bits of security, comparable algorithm strengths, and boiling oceans

The choice of cryptographic algorithms and sizes has long been difficult and there is often no obvious answer when it comes to comparing them. They are also very abstract. Indeed, what does it mean to use AES128? It's the standard symmetric cipher nowadays and no-one is going to be fired for choosing it but why not use AES256 then, and could something else be appropriate too for some given usage scenario and threat model?

A notion that has taken hold is the bits of security: some algorithm is said to provide N bits of security at a given time with the current scientific knowledge (breakthroughs are rare but can change everything). Bits of security is still an abstract notion but can be applied to most algorithms, if not all. This leads to results such as SHA1 provides X bits of security, SHA256 provides Y bits of security and BLAKE2b-512 provides Z bits of security. This doesn't apply across different kinds of cryptographic algorithms but this is not an issue in practice since different usage scenarios require different kinds of such algorithms anyway.

NIST - Recommendation for Key Management : 5.6 Guidance for Cryptographic Algorithm and Key-Size Selection

It is worth mentioning Universal security from bits and mips to pools, lakes – and beyond by Lenstra et al in 2013. The authors build humorous comparisons between cracking cryptographic algorithms at various bit-lengths and the volume of water that would be boiled with the same amount of energy.

Annex: Possible work split

Below is a rough outline for one of the possible development plans. There are two or three major batches. Tasks will sometimes be done in parallel.

Tests

Tests include tools such as sslscan, ssh-audit or cryptolizer which scan a server in order to retrieve the cryptography algorithms and protocols it supports or offers. Results can be used to build a database of effective configurations that will serve for testsuite and documentation purposes.

Tests are immediately useful as they help prevent regressions and help us know the current behaviors better.

System administration tool

Once there are alternative configuration sets, the tool becomes useful

Crypto configuration split to separate files

Move the relevant configuration entries to separate files in the proper location and refer to them through ‘include’ directives

  1. Crypto providers that aren’t crypto users: openssl, gnutls, …
  2. HTTPS servers (nginx, apache, lighttpd) not in Rust, Go or Java
  3. HTTPS servers but also including some in Rust, Go or Java
  4. Virtualization (encryption of guest management via libvirt, encryption of migration, encryption of things on disk with luks, ...) to be of interest to e.g. disable a particular set of algorithms.
  5. VPN everything (tend to be quite complex)
  6. Everything else

Alternative profiles

Design and provide our first alternatives and ensure everything of interest is covered

Restrictions through crypto providers

Restrict which configurations can be used by crypto users by acting only on crypto providers

Configuration sealing

This step involves detecting packages that do not use configuration files and patches to stop this behavior

Annex: relationship with distribution upstreams (Debian) and downstreams (Ubuntu derivatives)

Every modification of a crypto provider or user has a maintenance cost. Most modifications will be small and that cost will correspondingly be low.

However, a number of the affected packages are certainly without Ubuntu modification currently and are therefore synced. Introducing changes will require merging the packages from Debian, costing time and attention. The large number of changes is a strong incentive to upstream them.

Will Debian generally accept these changes, and what differences will forever remain between the two distributions?

Forever differences

Ubuntu and Debian each have their specificities. It is very unlikely they will have the same configurations for cryptography, partly due to the differences with regard to how decisions are made in both distributions.

Keep in mind that having different profiles does not mean they cannot be stored in the same place however. There is support in crypto-config for hiding profiles based on criteria, which makes it possible to include both Debian and Ubuntu profiles in Debian but only show the relevant ones at runtime, thus easing inclusion in Debian.

Upstreaming changes

The per-package changes rely on dropins which are uncontroversial. The paths they use only make sense when crypto-config is installed. As a consequence, at least the plumbing and minimal UI of crypto-config must be uploaded and maintained in Debian. Since crypto-config doesn't require special treatment or specific changes by itself, this does not cause specific concerns.

Even when users do not install crypto-config, Debian maintainers can benefit from several of the user stories outlined in this document, in particular to express their intent regarding their package's configuration, especially to expose upcoming changes.

We must keep in mind that some maintainers will refuse to include such changes, possibly on non-technical grounds. Hopefully, crypto-config's lightness, optionality and non-disruptiveness will alleviate concerns. It should be noted that it will be scrutinized too for its inclusion in Ubuntu main ultimately: crypto-config will first be in universe but be used to configure packages from main and this will work without component-mismatches, proving this will not lead to any kind of covert takeover.

Annex: Example report following package install or removal

I made up the file hierarchy: /distro is where the distribution installs its files while /user is where the user can modify files. The profile modification is not supported but this shows it's not a limitation of the script or of the approach but about reconciling them with dpkg.

**************************

*   APPLICATION STATUS   *

**************************

installed  =>  nginx

removed    =>  lighttpd

**************************

*    PROFILES STATUS     *

**************************

distro/crypto-config:default:nginx  =>  distro/crypto-config/default/nginx

distro/crypto-config:test1:nginx    =>  distro/crypto-config/default/nginx

distro/crypto-config:test2:nginx    =>  distro/crypto-config/default/nginx

user/crypto-config:test:nginx       =>  distro/crypto-config/default/nginx

**************************

*     PROFILE TREES      *

**************************

distro/crypto-config/test1/nginx     ->  ../default/nginx

distro/crypto-config/test2/nginx     ->  ../test1/nginx

user/crypto-config/test/nginx        ->  /distro/crypto-config/test2/nginx

References

Fedora Packaging Policy for Crypto

NIST - Recommendation for Key Management and especially section 5.6 Guidance for Cryptographic Algorithm and Key-Size Selection

Universal security from bits and mips to pools, lakes – and beyond by Lenstra et al

TLS versions and ciphers used for inbound SMTP connections at Toronto University