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:

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

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

  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/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#

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.

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#

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 for ecdsa, 2048 for rsa.

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

Time to retry 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.

acme_client_path#

Syntax

acme_client_path path;

Default

Context

http

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.