All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased] - ReleaseDate
### Changed
- The development has been move from GitHub to Codeberg.
## [0.25.0] - 2025-03-17
### Changed
@ -33,7 +40,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.23.0] - 2024-02-10
### Added
- The `challenge-tls-alpn-01` hook now exposes the `raw_proof` variable, which contains the SHA-256 digest of the key authorization, encoded using Base64 URL scheme without padding.
- The `challenge-tls-alpn-01` hook now exposes the `raw_proof` variable, which
contains the SHA-256 digest of the key authorization, encoded using Base64
URL scheme without padding.
### Changed
- The minimum supported Rust version (MSRV) is now 1.74.
@ -42,26 +51,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.22.2] - 2024-01-09
### Fixed
- The default hooks were not properly updated during the 0.22.0 release, which causes the certificate renewal to fail.
- The default hooks were not properly updated during the 0.22.0 release, which
causes the certificate renewal to fail.
## [0.22.1] - 2023-12-20
### Fixed
- The `Cargo.lock` file is now updated before a new version is released (GitHub bug #103).
- The `Cargo.lock` file is now updated before a new version is released (GitHub
bug #103).
## [0.22.0] - 2023-12-20
### Fixed
- ACMEd no longer crashes when the `random_early_renew` parameter is set to zero (GitHub bug #102).
- ACMEd no longer crashes when the `random_early_renew` parameter is set to
zero (GitHub bug #102).
### Changed
- The minimum supported Rust version (MSRV) is now 1.70.
- Manual (and badly designed) threads have been replaced by async.
- Randomized early delay, for spacing out renewals when dealing with a lot of certificates.
- Randomized early delay, for spacing out renewals when dealing with a lot of
certificates.
- Replaced the template engine TinyTemplate with MiniJinja.
- The default period of time between the certificate renewal and its expiration date (`renew_delay`) has been changed from 3 weeks to 30 days.
- The default period of time between the certificate renewal and its expiration
date (`renew_delay`) has been changed from 3 weeks to 30 days.
## [0.21.0] - 2022-12-19
@ -81,13 +95,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- An invalid reference in the command line arguments has been fixed.
- Some missing file path in log messages has been added.
- The calculation of the certificate's expiration delay does no longer break compilation on some systems.
- The calculation of the certificate's expiration delay does no longer break
compilation on some systems.
## [0.19.0] - 2022-04-17
### Added
- The `acmed@user.service` systemd unit configuration has been added as an alternative to the `acmed.service` unit.
- The `acmed@user.service` systemd unit configuration has been added as an
alternative to the `acmed.service` unit.
### Changed
- The minimal required Rust version is now 1.54.
@ -96,25 +112,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Add support for Ed25519 and Ed448 account keys and certificates.
- In addition to `restart`, the Polkit rule also allows the `reload`, `try-restart`, `reload-or-restart` and `try-reload-or-restart` verbs.
- In addition to `restart`, the Polkit rule also allows the `reload`,
`try-restart`, `reload-or-restart` and `try-reload-or-restart` verbs.
## [0.17.0] - 2021-05-04
### Added
- Allow the configuration of some default values at compile time using environment variables.
- Allow the configuration of some default values at compile time using
environment variables.
### Changed
- The template engine has been changed in favor of TinyTemplate, which has a different syntax than the previous one.
- The template engine has been changed in favor of TinyTemplate, which has a
different syntax than the previous one.
- The default account directory now is `/var/lib/acmed/accounts`.
- The default certificates and private keys directory now is `/var/lib/acmed/certs`.
- The default certificates and private keys directory now is
`/var/lib/acmed/certs`.
- The default for volatile runtime data now is `/run`.
## [0.16.0] - 2020-11-11
### Added
- The `pkcs9_email_address`, `postal_address` and `postal_code` subject attributes has been added.
- The `pkcs9_email_address`, `postal_address` and `postal_code` subject
attributes has been added.
### Changed
- The `friendly_name` and `pseudonym` subject attributes has been removed.
@ -124,19 +145,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.15.0] - 2020-11-03
### Added
- The names of both the certificate file and the associated private key can now be configured.
- The names of both the certificate file and the associated private key can now
be configured.
### Fixed
- Configuration files cannot be loaded more than one time, which prevents infinite recursion.
- Configuration files cannot be loaded more than one time, which prevents
infinite recursion.
### Changed
- Certificates are now allowed to share the same name if their respective key type is different.
- Certificates are now allowed to share the same name if their respective key
type is different.
## [0.14.0] - 2020-10-27
### Added
- Add proxy support through the `HTTP_PROXY`, `HTTPS_PROXY` and `NO_PROXY` environment variables.
- Add proxy support through the `HTTP_PROXY`, `HTTPS_PROXY` and `NO_PROXY`
environment variables.
- Allow to specify a unique name for each certificate.
### Changed
@ -146,9 +171,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.13.0] - 2020-10-10
### Added
- In the configuration, `root_certificates` has been added to the `global` and `endpoint` sections as an array of strings representing the path to root certificate files.
- At compilation, it is now possible to statically link OpenSSL using the `openssl_vendored` feature.
- In the Makefile, it is now possible to specify which target triple to build for.
- In the configuration, `root_certificates` has been added to the `global` and
`endpoint` sections as an array of strings representing the path to root
certificate files.
- At compilation, it is now possible to statically link OpenSSL using the
`openssl_vendored` feature.
- In the Makefile, it is now possible to specify which target triple to build
for.
## [0.12.0] - 2020-09-26
@ -168,7 +197,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- External account binding.
### Changed
- The `email` account configuration field has been removed. In replacement, use the `contacts` field.
- The `email` account configuration field has been removed. In replacement, use
the `contacts` field.
- Accounts now have their own hooks and environment.
- Accounts are now stored in a single binary file.
@ -180,22 +210,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.10.0] - 2020-08-27
### Added
- The account key type and signature algorithm can now be specified in the configuration using the `key_type` and `signature_algorithm` parameters.
- The delay to renew a certificate before its expiration date can be specified in the configuration using the `renew_delay` parameter at either the certificate, endpoint and global level.
- It is now possible to specify IP identifiers (RFC 8738) using the `ip` parameter instead of the `dns` one.
- The hook templates of type `challenge-*` have a new `identifier_tls_alpn` field which contains, if available, the identifier in a form that is suitable to the TLS ALPN challenge.
- The account key type and signature algorithm can now be specified in the
configuration using the `key_type` and `signature_algorithm` parameters.
- The delay to renew a certificate before its expiration date can be specified
in the configuration using the `renew_delay` parameter at either the
certificate, endpoint and global level.
- It is now possible to specify IP identifiers (RFC 8738) using the `ip`
parameter instead of the `dns` one.
- The hook templates of type `challenge-*` have a new `identifier_tls_alpn`
field which contains, if available, the identifier in a form that is suitable
to the TLS ALPN challenge.
- Globing is now supported for configuration files inclusion.
- The CSR's digest algorithm can now be specified using the `csr_digest` parameter.
- The CSR's digest algorithm can now be specified using the `csr_digest`
parameter.
### Changed
- In the certificate configuration, the `domains` field has been renamed `identifiers`.
- In the certificate configuration, the `domains` field has been renamed
`identifiers`.
- The `algorithm` certificate configuration field has been renamed `key_type`.
- The `algorithm` hook template variable has been renamed `key_type`.
- The `domain` hook template variable has been renamed `identifier`.
- The default hooks have been updated.
### Fixed
- The Makefile now works on FreeBSD. It should also work on other BSD although it has not been tested.
- The Makefile now works on FreeBSD. It should also work on other BSD although
it has not been tested.
## [0.9.0] - 2020-08-01
@ -207,7 +246,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- The HTTP(S) part is now handled by `attohttpc` instead of `reqwest`.
### Fixed
- In tacd, the `--acme-ext-file` parameter is now in conflict with `acme-ext` instead of itself.
- In tacd, the `--acme-ext-file` parameter is now in conflict with `acme-ext`
instead of itself.
## [0.8.0] - 2020-06-12
@ -222,20 +262,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.7.0] - 2020-03-12
### Added
- Wildcard certificates are now supported. In the file name, the `*` is replaced by `_`.
- Wildcard certificates are now supported. In the file name, the `*` is
replaced by `_`.
- Internationalized domain names are now supported.
### Changed
- The PID file is now always written whether or not ACMEd is running in the foreground. Previously, it was written only when running in the background.
- The PID file is now always written whether or not ACMEd is running in the
foreground. Previously, it was written only when running in the background.
### Fixed
- In the directory, the `externalAccountRequired` field is now a boolean instead of a string.
- In the directory, the `externalAccountRequired` field is now a boolean
instead of a string.
## [0.6.1] - 2019-09-13
### Fixed
- A race condition when requesting multiple certificates on the same non-existent account has been fixed.
- A race condition when requesting multiple certificates on the same
non-existent account has been fixed.
- The `foregroung` option has been renamed `foreground`.
@ -243,13 +287,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Hooks now have the optional `allow_failure` field.
- In hooks, the `stdin_str` has been added in replacement of the previous `stdin` behavior.
- In hooks, the `stdin_str` has been added in replacement of the previous
`stdin` behavior.
- HTTPS request rate limits.
### Changed
- Certificates are renewed in parallel.
- Hooks are now cleaned right after the current challenge has been validated instead of after the certificate's retrieval.
- In hooks, the `stdin` field now refers to the path of the file that should be written into the hook's standard input.
- Hooks are now cleaned right after the current challenge has been validated
instead of after the certificate's retrieval.
- In hooks, the `stdin` field now refers to the path of the file that should be
written into the hook's standard input.
- The logging format has been re-written.
### Fixed
@ -259,10 +306,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.5.0] - 2019-05-09
### Added
- ACMEd now displays a warning when the server indicates an error in an order or an authorization.
- ACMEd now displays a warning when the server indicates an error in an order
or an authorization.
- A configuration file can now include several other files.
- Hooks have access to environment variables.
- In the configuration, the global section, certificates and domains can define environment variables for the hooks.
- In the configuration, the global section, certificates and domains can define
environment variables for the hooks.
- tacd is now able to listen on a unix socket.
@ -271,9 +320,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Man pages.
- The project can now be built and installed using `make`.
- The post-operation hooks now have access to the `is_success` template variable.
- The post-operation hooks now have access to the `is_success` template
variable.
- Challenge hooks now have the `is_clean_hook` template variable.
- An existing certificate will be renewed if more domains have been added in the configuration.
- An existing certificate will be renewed if more domains have been added in
the configuration.
### Changed
- Unknown configuration fields are no longer tolerated.
@ -291,16 +342,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- tacd, the TLS-ALPN-01 validation daemon.
- An account object has been added in the configuration.
- In the configuration, hooks now have a mandatory `type` variable.
- It is now possible to declare hooks to clean after the challenge validation hooks.
- It is now possible to declare hooks to clean after the challenge validation
hooks.
- The CLI `--root-cert` option has been added.
- Failure recovery: HTTPS requests rejected by the server that are recoverable, like the badNonce error, are now retried several times before being considered a hard failure.
- The TLS-ALPN-01 challenge is now supported. The proof is a string representation of the acmeIdentifier extension. The self-signed certificate itself has to be built by a hook.
- Failure recovery: HTTPS requests rejected by the server that are recoverable,
like the badNonce error, are now retried several times before being
considered a hard failure.
- The TLS-ALPN-01 challenge is now supported. The proof is a string
representation of the acmeIdentifier extension. The self-signed certificate
itself has to be built by a hook.
### Changed
- In the configuration, the `email` certificate field has been replaced by the `account` field which matches an account object.
- The format of the `domain` configuration variable has changed and now includes the challenge type.
- In the configuration, the `email` certificate field has been replaced by the
`account` field which matches an account object.
- The format of the `domain` configuration variable has changed and now
includes the challenge type.
- The `token` challenge hook variable has been renamed `file_name`.
- The `challenge_hooks`, `post_operation_hooks`, `file_pre_create_hooks`, `file_post_create_hooks`, `file_pre_edit_hooks` and `file_post_edit_hooks` certificate variables has been replaced by `hooks`.
- The `challenge_hooks`, `post_operation_hooks`, `file_pre_create_hooks`,
`file_post_create_hooks`, `file_pre_edit_hooks` and `file_post_edit_hooks`
certificate variables has been replaced by `hooks`.
- The logs has been purged from many useless debug and trace entries.
### Removed
@ -311,18 +371,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.2.1] - 2019-03-30
### Changed
- The bug that prevented from requesting more than two certificates has been fixed.
- The bug that prevented from requesting more than two certificates has been
fixed.
## [0.2.0] - 2019-03-27
### Added
- The `kp_reuse` flag allow to reuse a key pair instead of creating a new one at each renewal.
- It is now possible to define hook groups that can reference either hooks or other hook groups.
- Hooks can be defined when before and after a file is created or edited (`file_pre_create_hooks`, `file_post_create_hooks`, `file_pre_edit_hooks` and `file_post_edit_hooks`).
- It is now possible to send logs either to syslog or stderr using the `--to-syslog` and `--to-stderr` arguments.
- The `kp_reuse` flag allow to reuse a key pair instead of creating a new one
at each renewal.
- It is now possible to define hook groups that can reference either hooks or
other hook groups.
- Hooks can be defined when before and after a file is created or edited
(`file_pre_create_hooks`, `file_post_create_hooks`, `file_pre_edit_hooks` and
`file_post_edit_hooks`).
- It is now possible to send logs either to syslog or stderr using the
`--to-syslog` and `--to-stderr` arguments.
### Changed
- `post_operation_hook` has been renamed `post_operation_hooks`.
- By default, logs are now sent to syslog instead of stderr.
- The process is now daemonized by default. It is possible to still run it in the foreground using the `--foregroung` flag.
- The process is now daemonized by default. It is possible to still run it in
The first way to help is to actually use the software and [report any bug you encounter](https://github.com/breard-r/acmed/issues). Do not hesitate to test the limits.
This project has been moved from [GitHub][acmed_github] to
[Codeberg][acmed_codeberg]. GitHub has been kept as a mirror where changes are
forced-push. Since this will erase every change made on GitHub, you should
therefore exclusively contribute on Codeberg.
An indirect way to help this project is therefore to [help
Since the author is not a native English speaker, some of the texts used in this project should be fixed. This is especially true on the man pages as well as the [wiki](https://github.com/breard-r/acmed-wiki).
## Testing and bug report
## Package it for your favorite system
The first way to help is to actually use the software and [report any bug you
encounter][bugtracker]. Do not hesitate to test the limits. When reporting a
bug, please follow the generic [bug reporting recommendations][bug_howto].
A great way to contribute to the project is to package it. You can check the packages status on [Repology](https://repology.org/project/acmed/versions).
Since the author is not a native English speaker, some of the texts used in
this project should be fixed. This is especially true on the man pages as well
as the [wiki][wiki].
### botan and botan-sys
[wiki]: https://codeberg.org/rbd/acmed/wiki
Although Botan isn't a dependency, it is considered as an alternative to OpenSSL. But before this can be done, the Botan crate need to support a few features:
- Access to a certificate's expiration time (via `botan_sys::botan_x509_cert_get_time_expires`).
- CSR (requires to add bindings to [create_cert_req](https://botan.randombit.net/handbook/api_ref/x509.html#creating-pkcs-10-requests)) with DER export.
- Implement `Clone` for `botan::Privkey`.
## Package it for your favorite system
A great way to contribute to the project is to package it. You can check the
As a one-man project, it has several goals already set but not explicitly written in an issue or any other follow-up file. It will not be the case before version 1.0 is released since everything may change at any moment. Therefore, it is recommended to request change instead of implementing them, this way we can discuss how things should be made. That said, there might be a few [good first issues](https://github.com/breard-r/acmed/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) you might want to look into.
As a one-man project, it has several goals already set but not explicitly
written in an issue or any other follow-up file. It will not be the case before
version 1.0 is released since everything may change at any moment. Therefore,
it is recommended to request change instead of implementing them, this way we
can discuss how things should be made. That said, there might be a few [good
first issues][good_first_issue] you might want to look into.
If you want to submit a pull request, please :
If you want to submit a pull request, please:
- document your changes in the man pages and the `CHANGELOG.md` file
- write as much tests as you can
- run `cargo test` and be sure every test pass
- format your code using [rustfmt](https://github.com/rust-lang/rustfmt)
- format your code using [rustfmt][rustfmt]
- be sure not to have any warning when compiling
- run [clippy](https://github.com/rust-lang/rust-clippy) and fix any issue
- run [clippy][clippy] and fix any issue
- refrain from including a new dependency
- beware of potential repercussions on the default hooks: those should remain usable
Notice: man pages are written using the mdoc syntax, documentation is available in [`man 7 mdoc`](https://man.freebsd.org/cgi/man.cgi?query=mdoc&sektion=7&apropos=0&manpath=FreeBSD+13.1-RELEASE).
## Author vs. contributor
Some people have troubles seeing the difference between an author and a contributor. Here is how it is seen withing this project.
- beware of potential repercussions on the default hooks: those should remain
usable
A contributor is a person who helps the project in various ways whenever she or he wants. As such, a contributor does not have any obligation other than being respectful and open-minded. People who wrote code that have been accepted are automatically listed in the [contributors page](https://github.com/breard-r/acmed/graphs/contributors). The creation of a file with the names of people contributing outside of the code base will be studied upon request from such people.
Notice: man pages are written using the mdoc syntax, documentation is available
in [`man 7 mdoc`][mdoc].
An author is a person who has some responsibilities on the project. Authors are expected to contribute on a regular basis, decide architectural choices, enforce copyright issues and so on. One does not grant himself the author status, it is given by the others authors after having discussed the request.

The Automatic Certificate Management Environment (ACME), is an internet standard ([RFC 8555](https://tools.ietf.org/html/rfc8555)) which allows to automate X.509 certificates signing by a Certification Authority (CA). ACMEd is one of the many clients for this protocol.
The Automatic Certificate Management Environment (ACME), is an internet
standard ([RFC 8555][rfc_8555]) which allows to automate X.509 certificates
signing by a Certification Authority (CA). ACMEd is one of the many clients for
this protocol.
[rfc_8555]: https://tools.ietf.org/html/rfc8555
## Key features
- http-01, dns-01 and [tls-alpn-01](https://tools.ietf.org/html/rfc8737) challenges
- IP identifier validation extension [RFC 8738](https://tools.ietf.org/html/rfc8738)
- RSA 2048, RSA 4096, ECDSA P-256, ECDSA P-384, ECDSA P-521, Ed25519 and Ed448 certificates and account keys
- http-01, dns-01 and [tls-alpn-01][tls-alpn-01] challenges
- IP identifier validation extension [RFC 8738][rfc_8738]
- STAR certificates [RFC 8739](https://tools.ietf.org/html/rfc8739)
- STAR certificates [RFC 8739][rfc_8739]
- Daemon and certificates management via the `acmectl` tool
- HTTP/2 support
[rfc_8739]: https://tools.ietf.org/html/rfc8739
## Project status
This project is usable, but is still a work in progress. Each release should works well and accordingly to its documentation.
Because the API has not been stabilized yet, breaking changes may occur. Therefore, before any upgrade, you are invited to read the [CHANGELOG](CHANGELOG.md) and check if any change can break your setup.
This project is usable, but is still a work in progress. Each release should
works well and accordingly to its documentation. Because the API has not been
stabilized yet, breaking changes may occur. Therefore, before any upgrade, you
are invited to read the [CHANGELOG](CHANGELOG.md) and check if any change can
break your setup.
Please keep in mind this software has neither been subject to a peer review nor to a security audit.
Please keep in mind this software has neither been subject to a peer review nor
to a security audit.
## Documentation
The [wiki](https://github.com/breard-r/acmed/wiki) will provides you with an overview as well as guides. You may contribute to it by creating a PR on the [acmed-wiki](https://github.com/breard-r/acmed-wiki) repository.
The [wiki][wiki] will provides you with an overview as well as guides.
For exhaustive references, the following man pages are available:
@ -58,173 +75,290 @@ For exhaustive references, the following man pages are available:
- acmed.toml (5)
- tacd (8)
An easy way to read those pages without installing ACMEd is to downloads and pipe them to the man utility:
An easy way to read those pages without installing ACMEd is to downloads and
pipe them to the man utility:
```
curl -sSf "https://raw.githubusercontent.com/breard-r/acmed/main/man/en/acmed.8" | man -l -
curl -sSf "https://raw.githubusercontent.com/breard-r/acmed/main/man/en/acmed.toml.5" | man -l -
curl -sSf "https://raw.githubusercontent.com/breard-r/acmed/main/man/en/tacd.8" | man -l -
curl -sSf "https://codeberg.org/rbd/acmed/raw/branch/main/man/en/acmed.8" | man -l -
curl -sSf "https://codeberg.org/rbd/acmed/raw/branch/main/man/en/acmed.toml.5" | man -l -
curl -sSf "https://codeberg.org/rbd/acmed/raw/branch/main/man/en/tacd.8" | man -l -
```
Alternatively, using zsh, you can use the following variants. Useful on system where man is unable to read from stdin (yes BSD, that's you).
Alternatively, using zsh, you can use the following variants. Useful on system
where man is unable to read from stdin (yes BSD, that's you).
```
man =(curl -sSf "https://raw.githubusercontent.com/breard-r/acmed/main/man/en/acmed.8")
man =(curl -sSf "https://raw.githubusercontent.com/breard-r/acmed/main/man/en/acmed.toml.5")
man =(curl -sSf "https://raw.githubusercontent.com/breard-r/acmed/main/man/en/tacd.8")
man =(curl -sSf "https://codeberg.org/rbd/acmed/raw/branch/main/man/en/acmed.8")
man =(curl -sSf "https://codeberg.org/rbd/acmed/raw/branch/main/man/en/acmed.toml.5")
man =(curl -sSf "https://codeberg.org/rbd/acmed/raw/branch/main/man/en/tacd.8")
```
[wiki]: https://codeberg.org/rbd/acmed/wiki
## Build from source
In order to compile ACMEd, you will need the [Rust](https://www.rust-lang.org/) compiler and its package manager, Cargo. The minimum supported Rust version(MSRV) is 1.74, although it is recommended to use the latest stable one.
In order to compile ACMEd, you will need the [Rust][rust] compiler and its
package manager, Cargo. The minimum supported Rust version (MSRV) is 1.74,
although it is recommended to use the latest stable one.
ACMEd depends OpenSSL 1.1.0 or higher.
On systems based on Debian/Ubuntu, you may need to install the `libssl-dev`, `build-essential` and `pkg-config` packages.
On systems based on Debian/Ubuntu, you may need to install the `libssl-dev`,
`build-essential` and `pkg-config` packages.
On Alpine Linux, you may need to install the `openssl-dev` and `alpine-sdk` packages.
On Alpine Linux, you may need to install the `openssl-dev` and `alpine-sdk`
packages.
```
$ make
$ make install
```
To build ACMEd and tacd inside a temporary Docker container, use the `contrib/docker/build-docker.sh` helper script. It currently supports Debian Buster / Stretch.
To build ACMEd and tacd inside a temporary Docker container, use the
`contrib/docker/build-docker.sh` helper script. It currently supports Debian
Buster / Stretch.
You can also build a container image for some k8s deployement, use the
`contrib/docker/build-docker-image.sh` script. It supports the same targets as
the build-docker.sh script.
You can also build a container image for some k8s deployement, use the `contrib/docker/build-docker-image.sh` script. It supports the same targets as the build-docker.sh script.
When build succeed, you can start the container with `docker run --rm -v
/path/to/conf/dir:/etc/acmed acmed:buster`.
When build succeed, you can start the container with `docker run --rm -v /path/to/conf/dir:/etc/acmed acmed:buster`.
[rust]: https://www.rust-lang.org/
### Advanced options
You can specify a space or comma separated list of features to activate in the `FEATURE` variable. The possible features are:
You can specify a space or comma separated list of features to activate in the
`FEATURE` variable. The possible features are:
- `openssl_dyn` (default): use OpenSSL as the cryptographic library, dynamically linked (mutually exclusive with `openssl_vendored`).
- `openssl_vendored`: use OpenSSL as the cryptographic library, statically linked (mutually exclusive with `openssl_dyn`).
- `openssl_dyn` (default): use OpenSSL as the cryptographic library,
dynamically linked (mutually exclusive with `openssl_vendored`).
- `openssl_vendored`: use OpenSSL as the cryptographic library, statically
linked (mutually exclusive with `openssl_dyn`).
You can also specify the [target triple](https://doc.rust-lang.org/nightly/rustc/platform-support.html) to build for in the `TARGET` variable. Please note that, if used, this variable must be specified for both `make` and `make install`.
You can also specify the [target triple][target_triple] to build for in the
`TARGET` variable. Please note that, if used, this variable must be specified
for both `make` and `make install`.
For example, you can build statically linked binaries using the `openssl_vendored` feature and the `x86_64-unknown-linux-musl` target.
For example, you can build statically linked binaries using the
`openssl_vendored` feature and the `x86_64-unknown-linux-musl` target.
```
make FEATURES="openssl_vendored" TARGET="x86_64-unknown-linux-musl"
```
The following environment variables can be used to change default values at compile and/or install time:
The following environment variables can be used to change default values at
compile and/or install time:
- `PREFIX` (install): system user prefix (default to `/usr`)
- `BINDIR` (install): system binary directory (default to `$PREFIX/bin`)
- `DATADIR` (install): system data directory (default to `$PREFIX/share`)
- `MAN5DIR` (install): system directory where pages 5 manuals are located (default to `$DATADIR/man/man5`)
- `MAN8DIR` (install): system directory where pages 8 manuals are located (default to `$DATADIR/man/man8`)
- `SYSCONFDIR` (compile and install): system configuration directory (default to `/etc`)
- `VARLIBDIR` (compile and install): directory for persistent data modified by ACMEd (default to `/var/lib`)
- `MAN5DIR` (install): system directory where pages 5 manuals are located
(default to `$DATADIR/man/man5`)
- `MAN8DIR` (install): system directory where pages 8 manuals are located
(default to `$DATADIR/man/man8`)
- `SYSCONFDIR` (compile and install): system configuration directory (default
to `/etc`)
- `VARLIBDIR` (compile and install): directory for persistent data modified by
ACMEd (default to `/var/lib`)
- `RUNSTATEDIR` (compile): system run-time variable data (default to `/run`)
- `ACMED_DEFAULT_ACCOUNTS_DIR` (compile): directory where account files are stored (default to `$VARLIBDIR/acmed/accounts`)
- `ACMED_DEFAULT_CERT_DIR` (compile): directory where certificates and private keys are stored (default to `$VARLIBDIR/acmed/certs`)
- `ACMED_DEFAULT_CERT_FORMAT` (compile): format for certificates and private keys files names (default to `{ name }_{ key_type }.{ file_type }.{ ext }`)
- `ACMED_DEFAULT_CONFIG_FILE` (compile): main configuration file (default to `$SYSCONFDIR/acmed/acmed.toml`)
- `ACMED_DEFAULT_PID_FILE` (compile): PID file for the main acmed process (default to `$RUNSTATEDIR/acmed.pid`)
- `TACD_DEFAULT_PID_FILE` (compile): PID file for the tacd process (default to `$RUNSTATEDIR/tacd.pid`)
For example, the following will compile a binary that will use the `/usr/share/etc/acmed/acmed.toml` configuration file and will be installed in the `/usr/local/bin` directory :
- `ACMED_DEFAULT_ACCOUNTS_DIR` (compile): directory where account files are
stored (default to `$VARLIBDIR/acmed/accounts`)
- `ACMED_DEFAULT_CERT_DIR` (compile): directory where certificates and private
keys are stored (default to `$VARLIBDIR/acmed/certs`)
- `ACMED_DEFAULT_CERT_FORMAT` (compile): format for certificates and private
keys files names (default to `{ name }_{ key_type }.{ file_type }.{ ext }`)
- `ACMED_DEFAULT_CONFIG_FILE` (compile): main configuration file (default to
`$SYSCONFDIR/acmed/acmed.toml`)
- `ACMED_DEFAULT_PID_FILE` (compile): PID file for the main acmed process
(default to `$RUNSTATEDIR/acmed.pid`)
- `TACD_DEFAULT_PID_FILE` (compile): PID file for the tacd process (default to
`$RUNSTATEDIR/tacd.pid`)
For example, the following will compile a binary that will use the
`/usr/share/etc/acmed/acmed.toml` configuration file and will be installed in
Most of the time, when packaging, you want to install the program in a dedicated directory. This is possible using the `DESTDIR` variable.
Most of the time, when packaging, you want to install the program in a
dedicated directory. This is possible using the `DESTDIR` variable.
```
make DESTDIR="/path/to/my/package/directory" install
```
Packager tip: If you package ACMEd in a way it does not run as root, you might want to create another package that provides the Polkit rule file located in the `contrib/polkit` directory. This package should depends on both acmed and Polkit.
Packager tip: If you package ACMEd in a way it does not run as root, you might
want to create another package that provides the Polkit rule file located in
the `contrib/polkit` directory. This package should depends on both acmed and
Polkit.
## Frequently Asked Questions
### Why this project?
After testing multiple ACME clients, I found out none of them supported all the features I expected (see the key features above). It may have been possible to contribute or fork an existing project, however I believe those project made architectural choices incompatible with what i wanted, and therefore it would be as much or less work to start a new project from scratch.
After testing multiple ACME clients, I found out none of them supported all the
features I expected (see the key features above). It may have been possible to
contribute or fork an existing project, however I believe those project made
architectural choices incompatible with what i wanted, and therefore it would
be as much or less work to start a new project from scratch.
### Is it free and open-source software?
Yes, ACMEd is dual-licensed under the MIT and Apache 2.0 terms. See [LICENSE-MIT.txt](LICENSE-MIT.txt) and [LICENSE-APACHE-2.0.txt](LICENSE-APACHE-2.0.txt) for details.
Yes, ACMEd is dual-licensed under the MIT and Apache 2.0 terms. See
[LICENSE-MIT.txt](LICENSE-MIT.txt) and
[LICENSE-APACHE-2.0.txt](LICENSE-APACHE-2.0.txt) for details.
The man pages, the default hooks configuration file, the `CHANGELOG.md` and the
`README.md` files are released under the [GNU All-Permissive
The man pages, the default hooks configuration file, the `CHANGELOG.md` and the `README.md` files are released under the [GNU All-Permissive License](https://www.gnu.org/prep/maintain/html_node/License-Notices-for-Other-Files.html).
### Where is this project hosted?
At first this project was hosted on [GitHub][acmed_github] but has then been
moved to [Codeberg][acmed_codeberg]. GitHub has been kept as a mirror where
changes are forced-push.
[acmed_github]: https://github.com/breard-r/acmed
[acmed_codeberg]: https://codeberg.org/rbd/acmed
### Can it automatically change my server configuration?
Short answer: No.
Long answer: At some points in a certificate's life, ACMEd triggers some hooks in order to let you customize how some actions are done, therefore you can use those hooks to modify any server configuration you wish. However, this may not be what you are looking for since it cannot proactively detect which certificates should be emitted since ACMEd only manages certificates that have already been declared in the configuration files.
Long answer: At some points in a certificate's life, ACMEd triggers some hooks
in order to let you customize how some actions are done, therefore you can use
those hooks to modify any server configuration you wish. However, this may not
be what you are looking for since it cannot proactively detect which
certificates should be emitted since ACMEd only manages certificates that have
already been declared in the configuration files.
### How should I configure my TLS server?
You decide. ACMEd only retrieve the certificate for you, it does not impose any specific configuration or limitation on how to use it. For the record, if you are looking for security recommendations on TLS deployment, you can follow the [ANSSI TLS guide](https://www.ssi.gouv.fr/en/guide/security-recommendations-for-tls/) (the english version might not be the latest version of this document, if possible use [the french one](https://www.ssi.gouv.fr/entreprise/guide/recommandations-de-securite-relatives-a-tls/)).
You decide. ACMEd only retrieve the certificate for you, it does not impose any
specific configuration or limitation on how to use it. For the record, if you
are looking for security recommendations on TLS deployment, you can follow the
[ANSSI TLS guide][anssi_tls_en] (the english version might not be the latest
version of this document, if possible use [the french one][anssi_tls_fr]).
It depends on your definition of a beginner. This software is intended to be used by system administrators with a certain knowledge of their environment. Furthermore, it is also expected to know the bases of the ACME protocol. Let's Encrypt wrote a nice article about [how it works](https://letsencrypt.org/how-it-works/).
It depends on your definition of a beginner. This software is intended to be
used by system administrators with a certain knowledge of their environment.
Furthermore, it is also expected to know the bases of the ACME protocol. Let's
Encrypt wrote a nice article about [how it works][letsencrypt_how].
ACMEd releases do work properly. Knowing that new users tend to shoot themselves in the foot with hooks, you might want to check those before considering moving away to a different software. Files path and permissions are very common traps, you definitely want to check those.
ACMEd releases do work properly. Knowing that new users tend to shoot
themselves in the foot with hooks, you might want to check those before
considering moving away to a different software. Files path and permissions are
very common traps, you definitely want to check those.
By the way, don't forget to change the log verbosity using `--log-level trace`.
### Should ACMEd run as root?
Running ACMEd as root is the simplest configuration since you do not have to worry about access rights, especially within hooks (Eg: restart a service).
Running ACMEd as root is the simplest configuration since you do not have to
worry about access rights, especially within hooks (Eg: restart a service).
However, if you are concerned with safety, you should create a dedicated user for ACMEd. Before doing so, please consider the following points:
However, if you are concerned with safety, you should create a dedicated user
for ACMEd. Before doing so, please consider the following points:
* Will my services be able to read both the private key and the certificate?
* Will the ACMEd user be able to execute the hooks?
The last one could be achieved using either sudo or Polkit (see the `contrib/polkit` directory).
The last one could be achieved using either sudo or Polkit (see the
`contrib/polkit` directory).
### Why is there no option to run ACMEd as a specific user or group?
The reason some services has such an option is because at startup they may have to load data only accessible by root, hence they have to change the user themselves after those data are loaded. For example, this is wildly used in web servers so they load a private key, which should only be accessible by root. Since ACMEd does not have such requirement, it should be run directly as the correct user.
The reason some services has such an option is because at startup they may have
to load data only accessible by root, hence they have to change the user
themselves after those data are loaded. For example, this is wildly used in web
servers so they load a private key, which should only be accessible by root.
Since ACMEd does not have such requirement, it should be run directly as the
correct user.
### How can I run ACMEd with systemd?
The `contrib/systemd` contains examples of a service file as well as a `sysusers.d` and a `tmpfiles.d` file. Those files might need adjustments in order to work on your system (e.g. paths, user, group,...), but it's probably a good starting point.
The `contrib/systemd` contains examples of a service file as well as a
`sysusers.d` and a `tmpfiles.d` file. Those files might need adjustments in
order to work on your system (e.g. paths, user, group,...), but it's probably a
good starting point.
### Does ACMEd uses any threading or parallelization?
Yes, ACMEd is [asynchronous](https://en.wikipedia.org/wiki/Asynchrony_(computer_programming)) and uses a multi-thread runtime. In order to check the number of threads, you may run the following command:
Yes, ACMEd is [asynchronous][wikipedia_async] and uses a multi-thread runtime.
In order to check the number of threads, you may run the following command:
### Can I use the same account on different endpoints?
Yes, that is possible. However, you should aware that some certificate authorities (e.g. Let's Encrypt) have policies restricting the use multiple accounts. Please check your CA's documentation.
Yes, that is possible. However, you should aware that some certificate
authorities (e.g. Let's Encrypt) have policies restricting the use multiple
accounts. Please check your CA's documentation.
### Why is RSA 2048 the default certificate key type?
Short answer: it is sufficiently secured, has good performances and is wildly supported.
Before choosing a different algorithm for your certificate's signature, you might want to consider all of those three points.
* For security, you may refer to the table 2 of the [NIST SP 800-57 Part 1](https://csrc.nist.gov/publications/detail/sp/800-57-part-1/rev-5/final).
* For performances, you can launch the following command on your machine: `openssl speed rsa2048 rsa3072 rsa4096 ecdsap256 ecdsap384 ecdsap521 ed25519 ed448`. Your server will be affected by the signature performances and the clients connecting to it will be affected by the verification performances.
* Nowadays, every client support ECDSA. Therefore, unless you have very specific requirements, you can safely use it. At time of writing, EdDSA certificates are not yet supported, but it might become a thing in the future.
Currently, security and client support aren't the main concerns since every possible type of certificates is good enough on those two points. The performances clearly favors ECDSA P-256, Ed25519 and RSA 2048. The later has been chosen as the default because it's the most wildly used as Certification Authorities root and intermediate certificates. This choice may change in favor of ECDSA since Let's Encrypt issued [a full ECDSA certificates chain](https://letsencrypt.org/2020/09/17/new-root-and-intermediates.html).
Short answer: it is sufficiently secured, has good performances and is wildly
supported.
Before choosing a different algorithm for your certificate's signature, you
might want to consider all of those three points.
* For security, you may refer to the table 2 of the [NIST SP 800-57 Part
1][nist_sp_800-57_p1].
* For performances, you can launch the following command on your machine:
### Why is ECDSA P-256 the default account key type?
RFC 8555 section 6.2 defines ECDSA P-256 as the only account key type that any ACME servers must implement. It is therefore the best choice for the default value.
RFC 8555 section 6.2 defines ECDSA P-256 as the only account key type that any
ACME servers must implement. It is therefore the best choice for the default
value.
### Why can I chose the CSR's digest type but not the certificate's?
Well, you sign the CSR, so obviously you can chose which digest to use. However, the certificate is signed by the certificate authority, so its digest choice is up to your CA. I agree that being able to chose the CSR's digest type is of low importance, sorry if it gave you false hopes about the certificate.
Well, you sign the CSR, so obviously you can chose which digest to use.
However, the certificate is signed by the certificate authority, so its digest
choice is up to your CA. I agree that being able to chose the CSR's digest type
is of low importance, sorry if it gave you false hopes about the certificate.