http_acme module#

Provides automatic certificate retrieval using the ACME protocol.

This module isn’t built by default; it should be enabled with the --with-http_acme_module configuration parameter.

Packages in our repositories have this module built.

Steps to enable certificate retrieval in the configuration:

  1. 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.

  2. Designate the domains to update 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.

  3. Make sure to accept ACME challenges: currently, Angie only supports domain name verification by HTTP, which requires responding to a special request at port 80 from the certificate autority (CA), called an ACME challenge.

  4. 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_client/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.

Example Configuration#

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 for ACME challenges over HTTP. However, as the previous example hints, the listen directive for that port may appear on a separate server block. If you have no such existing blocks, you can even limit it to ACME challenges only:

server {
    listen 80;
    return 444; # No response, connection is closed
}

Directives#

acme#

Syntax:

acme name;

Default:

Context:

server

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.

acme_client#

Syntax:

acme_client name uri [enabled=on|off] [key_type=type] [key_bits=number] [email=email] [renew_before_expiry=time] [retry_after_error=off|time];

Default:

Context:

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.

enabled

Enables or disables the client; this is useful, for example, to temporarily disable the client without removing it from the configuration.

Default: on.

key_type

The type of private key algorithm for the certificate. Valid values: rsa, ecdsa.

Default: ecdsa.

key_bits

Number of bits in the certificate key. Default: 256.

email

Optional email address for feedback; used when creating an account on the CA server.

renew_before_expiry

Time before the certificate expires when certificate renewal should start.

Default: 30d.

retry_after_error

Pause time before retrying when a certificate couldn’t be obtained. If set to off, the client won’t retry to obtain the certificate after a failure.

Default: 2h.

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.