acmed.toml(5)
| ACMED.TOML(5) | File Formats Manual | ACMED.TOML(5) |
NAME
acmed.toml — ACMEd
configuration file
DESCRIPTION
acmed.toml is the configuration file for
acmed(8). It is written in the
TOML
format. The allowed elements are described below.
account- Array of table representing an account on one or several endpoint.
contactsarray- Array of tables describing describing the account holder's contact
information. Each table must have one and only one key-value pair.
Possible keys and their associated values are:
mailtostring- A mailto URI as defined by RFC 6068. This URI cannot contains neither “hfields” nor more than one “addr-spec” in the “to” component.
envtable- Table of environment variables that will be accessible from hooks.
external_accounttable- Table containing the information required to bind the account to an
external one. Possible fields and values are:
identifierstring- ASCII string identifying the key.
keystring- Private key encoded in base64url without padding.
signature_algorithmstring- Name of the signature algorithm used to sign the external account
binding message sent to the endpoint as defined in
RFC 7518. Possible values are:
- HS256 ⟨default⟩
- HS384
- HS512
hooksarray- Names of hooks that will be called during operations on the account storage file. The hooks are guaranteed to be called sequentially in the declaration order.
key_typestring- Name of the asymmetric cryptography algorithm used to generate the key
pair. Possible values are:
- ed25519
- ed448
- ecdsa_p256 ⟨default⟩
- ecdsa_p384
- ecdsa_p521
- rsa2048
- rsa4096
namestring- The name the account is registered under. Must be unique.
signature_algorithmstring- Name of the signature algorithm used to sign the messages sent to the
endpoint as defined in RFC 7518. The default value
is derived from the key type. Possible values are:
- ES256
- ES384
- ES512
- RS256
certificate- Array of table representing a certificate that will be requested to a CA.
Note that, by default, certificates are identified by the first identifier in the list of identifiers. That means that if you reorder the identifiers so that a different identifier is at the first position, a new certificate with a new name will be issued.
accountstring- Name of the account to use.
csr_digeststring- Name of the certificate's signing request digest algorithm. Possible
values are:
- sha256 ⟨default⟩
- sha384
- sha512
directorystring- Path to the directory where certificates and their associated private keys are stored.
endpointstring- Name of the endpoint to use.
envtable- Table of environment variables that will be accessible from hooks.
file_name_formatstring- Template used to build the file's name. The template syntax is
MiniJinja. See the
STANDARDS section for a link to
the MiniJinja specifications. If not specified, the
value defined in the endpoint element, and then the
global element, is used. Default is “{{ name
}}_{{ key_type }}.{{ file_type }}.{{ ext }}”. Possible
variables are:
extstring- File extension. See cert_file_ext and pk_file_ext.
file_typestring- Contains “pk” for the private key file and “crt” for the certificate file.
key_typestring- The certificate's private key type.
namestring- The certificate's name.
hooksarray- Names of hooks that will be called when requesting a new certificate. The hooks are guaranteed to be called sequentially in the declaration order.
identifiersarray- Array of tables listing the identifiers that should be included in the
certificate along with the challenge to use for each one. The
dns and ip fields are mutually
exclusive.
challengestring- The name of the challenge to use to prove the identifier's
ownership. Possible values are:
- dns-01
- http-01
- tls-alpn-01
dnsstring- The domain name.
envtable- Table of environment variables that will be accessible from hooks.
ipstring- The IP address.
key_typestring- Name of the asymmetric cryptography algorithm used to generate the
certificate's key pair. Possible values are:
- ed25519
- ed448
- ecdsa_p256
- ecdsa_p384
- ecdsa_p521
- rsa2048 ⟨default⟩
- rsa4096
kp_reuseboolean- Set whether or not the private key should be reused when renewing the certificate. Default is false.
name- Name of the certificate. Must be unique unless the key type is different. Will be used in logs and in the associated file's name. The ‘*’, ‘:’ and ‘/’ characters will be replaced by an underscore. Default is the first identifier.
random_early_renewstring- Period of time before the usual certificate renewal, in which the certificate will renew at a random time. This is useful for when you want to even out your certificate orders when you're dealing with very large numbers of certificates. The format is described in the TIME PERIODS section. Default is the value defined in the associated endpoint.
renew_delaystring- Period of time between the certificate renewal and its expiration date. The format is described in the TIME PERIODS section. Default is the value defined in the associated endpoint.
subject_attributestable- Table where the certificate's subject attributes are specified.
Possible keys, with their RFC 4519 and X.500 equivalents, are:
ACMEd key RFC 4519 X.500 country_namec countryName generation_qualifiergenerationQualifier given_namegivenName initialsinitials locality_namel localityName namename organization_nameo organizationName organizational_unit_nameou organizationalUnitName pkcs9_email_addresspostal_addresspostalAddress postal_codepostalCode state_or_province_namest stateOrProvinceName streetstreet streetAddress surnamesn surname titletitle
endpoint- Array of table where each element defines a Certificate Authority (CA)
which may be used to request certificates.
file_name_formatstring- Template used to build the file's name. For detailed documentation, see the file_name_format directive located in the certificate element.
namestring- The name the endpoint is registered under. Must be unique.
rate_limitsarray- Array containing the names of the HTTPS rate limits to apply.
random_early_renewstring- Period of time before the usual certificate renewal, in which the certificate will renew at a random time. This is useful for when you want to even out your certificate orders when you're dealing with very large numbers of certificates. The format is described in the TIME PERIODS section. Default is the value defined in the global section.
renew_delaystring- Period of time between the certificate renewal and its expiration date. The format is described in the TIME PERIODS section. Default is the value defined in the global section.
root_certificatesarray- Array containing the path to root certificates that should be added to the trust store.
tos_agreedboolean- Set whether or not the user agrees to the Terms Of Service (TOS).
urlstring- The endpoint's directory URL.
global- Table containing the global configuration options.
accounts_directorystring- Specify the directory where the accounts private and public keys are stored.
cert_file_groupgroup_name|group_id string- Specify the group who will own newly-created certificates files. See chown(2) for more details.
cert_file_modeinteger- Specify the permissions to use for newly-created certificates files. See chmod(2) for more details.
cert_file_userusername|user_id string- Specify the user who will own newly-created certificates files. See chown(2) for more details.
cert_file_extstring- Specify the file extension of certificate files.
certificates_directorystring- Specify the directory where the certificates and their associated private keys are stored.
envtable- Table of environment variables that will be accessible from hooks.
file_name_formatstring- Template used to build the file's name. For detailed documentation, see the file_name_format directive located in the certificate element.
pk_file_groupgroup_name|group_id string- Specify the group who will own newly-created private-key files. See chown(2) for more details.
pk_file_modeinteger- Specify the permissions to use for newly-created private-key files. See chmod(2) for more details.
pk_file_userusername|user_id string- Specify the user who will own newly-created private-key files. See chown(2) for more details.
pk_file_extstring- Specify the file extension of private-key files.
random_early_renewstring- Period of time before the usual certificate renewal, in which the certificate will renew at a random time. This is useful for when you want to even out your certificate orders when you're dealing with very large numbers of certificates. The format is described in the TIME PERIODS section. By default, this is disabled, or rather, the time frame is set to 0.
renew_delaystring- Period of time between the certificate renewal and its expiration date. The format is described in the TIME PERIODS section. Default is 30d.
root_certificatesarray- Array containing the path to root certificates that should be added to the trust store.
group- Array of table allowing to group several hooks as one. A group is
considered as new hook.
hooksarray- Array containing the names of the hooks that are grouped. The hooks are guaranteed to be called sequentially in the declaration order.
namestring- The name the group is registered under. This name is considered as a hook name. Must be unique.
hook- Array of table where each element defines a command that will be launched
at a defined point. See section
WRITING A HOOK for more details.
allow_failureboolean- Defines if an error return value for this hook is allowed or not. If not allowed, a failure in this hook will fail the whole certificate request process. Default is false.
argsarray- Array of strings representing the command's arguments.
cmdstring- The name of the command that will be launched.
namestring- The name the hook is registered under. Must be unique.
stderrstring- Path to the file where the command's standard error output if written.
stdinstring- Path to the file that will be written into the command's standard intput. Mutually exclusive with stdin_str.
stdin_strstring- String that will be written into the command's standard input. Mutually exclusive with stdin.
stdoutstring- Path to the file where the command's standard output if written.
typearray- Array of strings. Possible types are:
- challenge-dns-01
- challenge-dns-01-clean
- challenge-http-01
- challenge-http-01-clean
- challenge-tls-alpn-01
- challenge-tls-alpn-01-clean
- file-post-create
- file-post-edit
- file-pre-create
- file-pre-edit
- post-operation
include- Array containing the path to configuration file to include. The path can
be either relative or absolute. If relative, it is relative to the
configuration file which included it.
In case or overlapping global option definition, the one of the last included file will be used. For example, if a file A includes files B and C and all three defines the same global option, the final value will be the one defined in file C.
Unix style globing is supported.
rate-limit- Array of table where each element defines a HTTPS rate limit.
namestring- The name the rate limit is registered under. Must be unique.
numberinteger- Number of requests authorized withing the time period.
periodstring- Period of time during which a maximal number of requests is authorized. The format is described in the TIME PERIODS section.
WRITING A HOOK
When requesting a certificate from a CA using ACME, there are three steps that are hard to automatize. The first one is solving challenges in order to prove the ownership of every identifier to be included: it requires to interact with the configuration of other services, hence depends on how the infrastructure works. The second one is restarting all the services that use a given certificate, for the same reason. The last one is archiving: although several default methods can be implemented, sometimes admins wants or are required to do it in a different way.
In order to allow full automation of the three above steps without imposing arbitrary restrictions or methods, acmed(8) uses hooks. Fundamentally, a hook is a command line template that will be called at a specific time of the process. Such an approach allows admins to use any executable script or program located on the machine to customize the process.
For a given certificate, hooks are guaranteed to be called sequentially in the declaration order. It is therefore possible to have a hook that depends on another one. Nevertheless, several certificates may be renewed at the same time. Hence, hooks shall not use globing or any other action that may disrupt hooks called by a different certificate.
A hook has a type that will influence both the moment it is called and the available template variables. It is possible to declare several types. In such a case, the hook will be invoked whenever one of its type request it. When called, the hook only have access to template variable for the current type. If a hook uses a template variable that does not exists for the current type it is invoked for, the variable is empty.
When writing a hook, the values of args, stdin, stdin_str, stdout and stderr are considered as template strings whereas cmd is not. The template syntax is MiniJinja. See the STANDARDS section for a link to the MiniJinja specifications.
The available types and the associated template variable are described below.
challenge-dns-01- Invoked when the ownership of an identifier must be proved using the
dns-01 challenge. The available template variables are:
challengestring- The name of the challenge type ⟨dns-01⟩. Mostly used in hooks with multiple types.
envarray- Array containing all the environment variables.
identifierstring- The identifier name whom ownership is currently being validated.
is_clean_hookbool- False
proofstring- The content of the proof that must be written to a
‘
TXT’ entry of the DNS zone for the ‘_acme-challenge’ subdomain.
challenge-dns-01-clean- Invoked once an identifier ownership has been proven using the dns-01 challenge. This hook is intended to remove the proof since it is no longer required. The template variables are strictly identical to those given in the corresponding challenge-dns-01 hook, excepted is_clean_hook which is set to true.
challenge-http-01- Invoked when the ownership of an identifier must be proved using the
http-01 challenge. The available template variables are:
challengestring- The name of the challenge type ⟨http-01⟩. Mostly used in hooks with multiple types.
envarray- Array containing all the environment variables.
file_namestring- Name of the file containing the proof. This is not a full path and
does not include the
‘
.well-known/acme-challenge/’ prefix. identifierstring- The identifier name whom ownership is currently being validated.
is_clean_hookbool- False
proofstring- The content of the proof that must be written to file_name.
challenge-http-01-clean- Invoked once an identifier ownership has been proven using the http-01 challenge. This hook is intended to remove the proof since it is no longer required. The template variables are strictly identical to those given in the corresponding challenge-http-01 hook, excepted is_clean_hook which is set to true.
challenge-tls-alpn-01- Invoked when the ownership of an identifier must be proved using the
tls-alpn-01 challenge. The available template variables
are:
challengestring- The name of the challenge type ⟨tls-alpn-01⟩. Mostly used in hooks with multiple types.
envarray- Array containing all the environment variables.
identifierstring- The identifier name whom ownership is currently being validated.
identifier_tls_alpnstring- The identifier name whom ownership is currently being validated, in a form suitable for the TLS ALPN challenge.
is_clean_hookbool- False
proofstring- Plain-text representation of the acmeIdentifier extension that should be used in the self-signed certificate presented when a TLS connection is initiated with the ALPN extension value. acmed(8) will not generate the certificate itself since it can be done using tacd(8).
raw_proofstring- The SHA-256 digest of the key authorization, encoded using Base64 URL scheme without padding. This is intended for the use of ACMEd with a TLS-ALPN responder other than tacd(8).
challenge-tls-alpn-01-clean- Invoked once an identifier ownership has been proven using the tls-alpn-01 challenge. This hook is intended to remove the proof since it is no longer required. The template variables are strictly identical to those given in the corresponding challenge-tls-alpn-01 hook, excepted is_clean_hook which is set to true.
file-post-create- Invoked after a non-existent file created. The available template variables are the same as those available for the file-pre-create type.
file-post-edit- Invoked after an existent file modified. The available template variables are the same as those available for the file-pre-create type.
file-pre-create- Invoked before a non-existent file
created. The available template variables are:
envarray- Array containing all the environment variables.
file_directorystring- Name of the directory where the impacted file is located.
file_namestring- Name of the impacted file.
file_pathstring- Full path to the impacted file.
file-pre-edit- Invoked before an existent file modified. The available template variables are the same as those available for the file-pre-create type.
post-operation- Invoked at the end of the certificate request process. The available
template variables are:
envarray- Array containing all the environment variables.
identifiersstring- Array containing the identifiers included in the requested certificate.
is_successboolean- True if the certificate request is successful.
key_typestring- Name of the asymmetric cryptography algorithm used to generate the certificate's key pair.
statusstring- Human-readable status. If the certificate request failed, it contains the error description.
certificate_pathstring- Path to the file containing the certificate.
private_key_pathstring- Path to the file containing the private key.
DEFAULT HOOKS
Because many people have the same needs, ACMEd comes with a set of hooks that should serve most situations. Hook names being unique, the following names and any other name starting by those is reserved and should not be used.
- git
- This hook uses git(1) to archive private
keys, public keys and certificates. It is possible to customize the commit
username and email by using respectively the
GIT_USERNAMEandGIT_EMAILenvironment variables. - http-01-echo
- This hook is designed to solve the http-01 challenge. For this purpose, it
will write the proof into {{ env.HTTP_ROOT }}/{{
identifier }}/.well-known/acme-challenge/{{ file_name }}.
The web server must be configured so the file http://{{ identifier }}/.well-known/acme-challenge/{{ file_name }} can be accessed from the CA.
If
HTTP_ROOTis not specified, it will be set to /var/www. - tls-alpn-01-tacd-tcp
- This hook is designed to solve the tls-alpn-01 challenge using
tacd(8). It requires
pkill(1) to support the
-F option.
tacd(8) will listen on the host defined by the
TACD_HOSTenvironment variable (default is the identifier to be validated) and on the port defined by theTACD_PORTenvironment variable (default is 5001).tacd(8) will store its pid into {{ TACD_PID_ROOT }}/tacd_{{ identifier }}.pid. If
TACD_PID_ROOTis not specified, it will be set to /run. - tls-alpn-01-tacd-unix
- This hook is designed to solve the tls-alpn-01 challenge using
tacd(8). It requires
pkill(1) to support the
-F option.
tacd(8) will listen on the unix socket {{ env.TACD_SOCK_ROOT }}/tacd_{{ identifier }}.sock. If
TACD_SOCK_ROOTis not specified, it will be set to /run.tacd(8) will store its pid into {{ TACD_PID_ROOT }}/tacd_{{ identifier }}.pid. If
TACD_PID_ROOTis not specified, it will be set to /run.
TIME PERIODS
ACMEd uses its own time period format, which is vaguely inspired by the ISO 8601 one. Periods are formatted as PM[PM...] where M is case sensitive character representing a length and P is an integer representing a multiplayer for the following length. The authorized length are:
- s: second
- m: minute
- h: hour
- d: day
- w: week
For example, “1d42s” and “40s20h4h2s” both represents a period of one day and forty-two seconds.
TEMPLATE FILTERS
In addition the the filters provided by default by MiniJinja, ACMEd provides the following filters:
- rev_labels
- Reverts the labels of a domain name (eg: “mx1.example.org” becomes “org.example.mx1” ).
FILES
- /var/lib/acmed/accounts
- Default accounts private and public keys directory.
- /etc/acmed/acmed.toml
- Default acmed(8) configuration file.
- /var/lib/acmed/certs
- Default certificates and associated private keys directory.
EXAMPLES
The following example defines a typical endpoint, account and certificate for a domain, several subdomains and an IP address.
[[endpoint]]
name = "example name"
url = "https://acme.example.org/directory"
tos_agreed = true
[[account]]
name = "my test account"
contacts = [
{ mailto = "certs@exemple.net" }
]
[[certificate]]
endpoint = "example name"
account = "my test account"
identifiers = [
{ dns = "exemple.net", challenge = "http-01"},
{ dns = "1.exemple.net", challenge = "dns-01"},
{ dns = "2.exemple.net", challenge = "tls-alpn-01", env.TACD_PORT="5010"},
{ dns = "3.exemple.net", challenge = "tls-alpn-01", env.TACD_PORT="5011"},
{ ip = "203.0.113.1", challenge = "http-01"},
]
hooks = ["git", "http-01-echo", "tls-alpn-01-tacd-tcp", "some-dns-01-hook"]
env.HTTP_ROOT = "/srv/http"
It is possible to use echo(1) to solve the http-01 challenge and rm(1) to clean it. mkdir(1) and chmod(1) are used to prevent issues related to file access.
[[hook]]
name = "http-01-echo-mkdir"
type = ["challenge-http-01"]
cmd = "mkdir"
args = [
"-m", "0755",
"-p", "{{ env.HTTP_ROOT | default('/var/www') }}/{{ identifier }}/.well-known/acme-challenge"
]
[[hook]]
name = "http-01-echo-echo"
type = ["challenge-http-01"]
cmd = "echo"
args = ["{{ proof }}"]
stdout = "{{ env.HTTP_ROOT | default('/var/www') }}/{{ identifier }}/.well-known/acme-challenge/{{ file_name }}"
[[hook]]
name = "http-01-echo-chmod"
type = ["challenge-http-01-clean"]
cmd = "chmod"
args = [
"a+r",
"{{ env.HTTP_ROOT | default('/var/www') }}/{{ identifier }}/.well-known/acme-challenge/{{ file_name }}"
]
[[hook]]
name = "http-01-echo-clean"
type = ["challenge-http-01-clean"]
cmd = "rm"
args = [
"-f",
"{{ env.HTTP_ROOT | default('/var/www') }}/{{ identifier }}/.well-known/acme-challenge/{{ file_name }}"
]
The hooks from the previous example can be grouped in order to reduce the number of hooks to define in the certificate.
[[group]]
name = "http-01-echo-var-www"
hooks = [
"http-01-echo-mkdir",
"http-01-echo-echo",
"http-01-echo-chmod",
"http-01-echo-clean"
]
[[certificate]]
# Some fields omitted
hooks = ["http-01-echo"]
env.HTTP_ROOT = "/srv/http"
It is also possible to use sendmail(8) in a hook in order to notify someone when the certificate request process is done.
[[hook]]
name = "email-report"
type = ["post-operation"]
cmd = "sendmail"
args = [
"-f", "noreply.certs@example.net",
"contact@example.net"
]
stdin_str = """Subject: Certificate renewal {{ 'succeeded' if is_success else 'failed' }} for {{ identifiers.0 }}
The following certificate has {{ '' if is_success else '*not* ' }}been renewed.
identifiers: {% for ident in identifiers %}{% if not loop.first %}, {% endif %}{{ ident }}{% endfor %}
key type: {{ key_type }}
status: {{ status }}"""
SEE ALSO
STANDARDS
- Tom Preston-Werner, TOML v0.5.0, https://toml.io/en/v0.5.0, July 2018.
- Armin Ronacher, MiniJinja, https://docs.rs/minijinja/latest/minijinja/syntax/index.html.
- M. Jones, JSON Web Algorithms (JWA), RFC 7518, May 2015.
AUTHORS
Rodolphe Bréard ⟨rodolphe@breard.tf⟩
| December 21, 2024 | Linux 6.12.85-6.12-alt1 |
