ACME#
Provides automatic certificate retrieval using the ACME protocol.
When building from the source code,
this module isn't built by default;
it should be enabled with the
--with-http_acme_module
build option.
In packages and images from our repos, the module is included in the build.
Steps to enable certificate retrieval in the configuration:
Define an ACME client in the
http
block with the acme_client directive that sets a unique client name and other options; multiple ACME clients may be configured.Designate the domains to request the certificates for: A single certificate will be issued for the domain names listed in all server_name directives of all
server
blocks whose acme directives reference a single ACME client.Make sure to accept ACME challenges by leaving port 80 open; the module will handle the rest. Currently, Angie supports domain name verification by HTTP only, which requires responding to a special request from the certificate authority (CA), called an ACME challenge.
Configure SSL using the newly obtained certificate and key: The module exposes its certificates and keys as built-in variables that you can use in the configuration to populate ssl_certificate and ssl_certificate_key.
Implementation Details#
Client keys and certificates are stored
using the PEM encoding
under respective subdirectories
in the directory set by the --http-acme-client-path
parameter:
$ ls /var/lib/angie/acme/example/
account.key certificate.pem private.key
An ACME client needs an account with the CA server.
To create and manage the account, the client uses a private key
(account.key
);
if it doesn't already have one, the key is created at startup.
Then, the client uses it to register an account with the server.
Note
If you have an existing account key, place it in the client's subdirectory before startup to reuse the account.
An ACME client also maintains a dedicated key
(private.key
) for certificate signing requests (CSR);
if needed, this certificate key is also created automatically at startup.
At startup, the client requests a certificate if it hasn't got one yet,
signing and sending a CSR for all domains it manages to the CA server.
The server verifies domain ownership over HTTP and issues a certificate,
which the client stores locally (certificate.pem
).
When the certificate approaches its scheduled renewal or the list of domains changes, the client signs and sends another CSR to the CA server. Again, the server verifies ownership and issues a new certificate, which the client installs locally, replacing the previous one.
Configuration Example#
Here, an ACME client named example
manages the example.com
and www.example.com
domains.
The certificate and its key
are exposed via prefix variables
$acme_cert_<name> and $acme_cert_key_<name>.
They store the respective file contents
that are in turn used
with ssl_certificate and ssl_certificate_key:
http {
resolver 127.0.0.53; # needed for the 'acme_client' directive
acme_client example https://acme-v02.api.letsencrypt.org/directory;
server {
listen 80; # Can occur in another server block,
# with a different domain list
# or even without one
listen 443 ssl;
server_name example.com www.example.com;
acme example;
ssl_certificate $acme_cert_example;
ssl_certificate_key $acme_cert_key_example;
}
}
As noted earlier, port 80 must be open to accept ACME challenges over HTTP. However, as the previous example hints, the listen directive for that port may appear on a separate server block. If no such blocks already exist, you can even limit your new block to ACME challenges only:
server {
listen 80;
return 444; # No response, connection is closed
}
Why would this work?
The module intercepts requests to /.well-known/acme-challenge/<TOKEN>
after reading the headers but before a virtual server is selected,
or any rewrite and location directives are processed.
Such intercepted requests are processed if the TOKEN
matches
what's expected for a specific challenge.
No actual directory access occurs; the request is fully handled by the module.
Directives#
acme#
For all domains specified in the server_name directives
of all server blocks that refer to the acme_client called name,
a single certificate will be obtained;
if the server_name
configuration changes,
the certificate is renewed to account for the updates.
Note
Currently, wildcard domains and domains specified with regular expressions are not supported and will be ignored.
This directive can be specified multiple times to load certificates of different types, for example, RSA and ECDSA:
server {
listen 443 ssl;
server_name example.com www.example.com;
ssl_certificate $acme_cert_rsa;
ssl_certificate_key $acme_cert_key_rsa;
ssl_certificate $acme_cert_ecdsa;
ssl_certificate_key $acme_cert_key_ecdsa;
acme rsa;
acme ecdsa;
}
acme_client#
|
|
Default |
— |
http |
Defines an ACME client under a globally unique name. It must be valid for a file directory and will be treated as case insensitive.
The second mandatory parameter is the uri of the ACME directory. For example, the URI of Let's Encrypt ACME directory is listed as https://acme-v02.api.letsencrypt.org/directory.
For this directive to work, a resolver must be configured in the same context.
Note
For testing purposes, certificate authorities usually provide separate staging environments. For example, Let's Encrypt staging environment is currently https://acme-staging-v02.api.letsencrypt.org/directory.
|
Enables or disables the client; this is useful, for example, to temporarily disable the client without removing it from the configuration. Default: |
|
The type of private key algorithm for the certificate.
Valid values: Default: |
|
Number of bits in the certificate key.
Default: 256 for |
|
Optional email address for feedback; used when creating an account on the CA server. |
|
Time before the certificate expires when certificate renewal should start. Default: |
|
Time to retry
when a certificate couldn't be obtained.
If set to Default: |
acme_client_path#
Overrides the path to the directory for storing certificates and keys,
specified at build time with the --http-acme-client-path
build option.
Built-in Variables#
$acme_cert_<name>
#
Contents of the last certificate file (if any) obtained by the client with this name.
$acme_cert_key_<name>
#
Contents of the certificate key file used by the client with this name.
Important
The certificate file is available only if the ACME client has received at least one certificate, whereas the key file is available immediately after startup.