Index | FO104 |
Title | crypto-config - a framework to manage crypto-related configurations system-wide |
Approved | |
Authors | |
Standard | |
Created | 2022-11-17 |
Reviewer | Status |
Approved Sep 19, 2024 | |
Approved Aug 16, 2024 | |
Approved Oct 15, 2024 | |
Approved Sep 10, 2024 |
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.
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.
Lack of consistent configuration: case study on Mantic Minotaur
Applicability to non-crypto domains
State of the art: Fedora’s crypto-policies
Rationale for a new policy and tools
Other constraints, motivations and design goals
Constants used in the specification
Statically-linked crypto providers
Known Limitations and Future work
Annex: bits of security, comparable algorithm strengths, and boiling oceans
Annex: relationship with distribution upstreams (Debian) and downstreams (Ubuntu derivatives)
Annex: Example report following package install or removal
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.
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.
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.
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.
💡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 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:
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.
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.
💡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.
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.
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.
In addition to user wishes and needs, there are additional constraints to take into account.
Care must be taken not to provide fewer guarantees than the usual configuration handling in Debian.
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.
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.
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.
NB: examples in this section use ‘nginx’ because its configuration format is simple; the same can be done with openssl.
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
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
💡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). |
💡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. |
💡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. |
💡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. |
.----------------------. .----------------------.
| | | |
| .deb package | | User |
| | | |
'-----------+----------' '-----------+----------'
| |
| |
|dpkg installs |Edits
| |
v |
.----------------------. |
| | |
| Application | |
| | |
'-----------+----------' |
| |
| |
|Reads |
| |
v |
.----------------------. |
| | |
| 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" |
'----------------------' '----------------------'
+--------------------+ +--------------------+ +--------------------+
| .----------------. | | .----------------. | | .----------------. |
| |GnuTLS dropins | | | |GnuTLS dropins | | | |GnuTLS dropins | |
| '----------------' | | '----------------' | | '----------------' |
| .----------------. | | .----------------. | | .----------------. |
| | Nginx dropins | | | | Nginx dropins | | | | Nginx dropins | |
| '----------------' | | '----------------' | | '----------------' |
| .----------------. | | .----------------. | | .----------------. |
| |OpenSSL dropins | | | |OpenSSL dropins | | | |OpenSSL dropins | |
| '----------------' | | '----------------' | | '----------------' |
| .----------------. | | .----------------. | | .----------------. |
| | ... | | | | ... | | | | ... | |
| '----------------' | | '----------------' | | '----------------' |
+--------------------+ +--------------------+ +--------------------+
"'Default' Profile" "'Legacy' Profile" "'Future' Profile"
💡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 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.
+------------+
| Default |
+--+-+--+-+--+
| | | |
.------------------' | | '------------------.
| .----' '----. |
| | | |
v v v v
+-----------+ +-----------+ +-----------+ +-----------+
| Legacy | | FIPS | | Future | | Customer- |
| | | | | | | specific1 |
+-----------+ +-----+-----+ +-----------+ +-----------+
|
v
+-----------+
| Customer- |
| specific2 |
+-----------+
+-----------------------------------------------------------+
| |
| +------------+ +-----------+ +------------+ |
| 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;
}
💡Here we go through how crypto-config will be shipped and installed, and its impact on existing packages. |
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
💡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. |
💡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.
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.
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.
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.
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.
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.
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.
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.
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 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.
Once there are alternative configuration sets, the tool becomes useful
Move the relevant configuration entries to separate files in the proper location and refer to them through ‘include’ directives
Design and provide our first alternatives and ensure everything of interest is covered
Restrict which configurations can be used by crypto users by acting only on crypto providers
This step involves detecting packages that do not use configuration files and patches to stop this behavior
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?
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.
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.
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
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