ACME Certificate Lifecycle Operations

ACME Enrollment

The Horizon Client uses the LEGO ACME client under the hood to enroll certificates with Horizon. As per the ACME protocol, the client will need to prove its ownership of the domain name(s) it wants to enroll a certificate for. This is done either by HTTP, TLS-ALPN or DNS challenge. An email address is also needed to create an ACME account with Horizon in order to enroll certificates.

Table 1. ACME Validation parameters
Parameter Description

--account

Email of the account to use.

--dns-names

DNS names to enroll a certificate for.

--http-01-port

Port to use for http01 challenge. (Optional)

--tls-alpn-01-port

Port to use for tlsalpn01 challenge. (Optional)

--dns-01-provider

DNS provider name to use for dns01 challenge, from the LEGO supported list

ACME Account

The ACME account is used to store the ACME account key, which is used to sign the ACME requests. All of this is taken care of by the ACME modules of Horizon and Horizon Client.

Given the email from the --account CLI parameter, the client will create an ACME account with Horizon, and store it’s private key in the /var/db/acme/accounts/<email>.pem file relative to the Horizon Client data folder (/opt/horizon on unix and C:\ProgramData\Horizon on Windows). If such a file already exists, the client will use it instead of creating a new account.

ACME validation

The ACME protocol requires the client to prove its ownership of the domain name(s) it wants to enroll a certificate for. This is done either by HTTP, TLS-ALPN or DNS challenge.The order in which the client will try the validation methods is the following:

  1. TLS-ALPN challenge

  2. HTTP challenge

  3. DNS challenge

The allowed challenge validation modes for a profile need to be configured in Horizon. If the profile does not allow a challenge validation mode, the client will not be able to enroll a certificate for it.

DNS challenge

Note that the DNS challenge requires the client to be able to update the DNS records of the domain name(s) it wants to enroll a certificate for. This is done by providing the proper credentials for the DNS provider specified in the --dns-01-provider CLI parameter. Each provider will have different needs, but the credentials will need to be provided as environment variables in every case. Please refer to the LEGO documentation for more details.

ACME Renewal

The acme renew command is designed to work similarly to the acme enroll command, but with a few differences:

The following input parameters can be used to specify the certificate to renew:

Table 2. ACME Renewal input certificate parameters
Parameter Description

--in-cert

Path to the Certificate to renew (PEM file, PKCS#12 file, JKS file) or cert thumbprint for Windows certificate store entries

--in-pfx-pwd

Password for the PKCS#12 file to renew

--in-jks-pwd

Password for the JKS file to renew

--in-jks-alias

Alias for the certificate to renew in the JKS file

--in-jks-alias-pwd

Alias password for the JKS file to renew

ACME Revocation

You can revoke an ACME enrolled certificate using the account that enrolled it. The acme revoke command will revoke the certificate specified by the --cert parameter with the reason specified by the --reason parameter.

The revocation reason must be one of the following:

  • unspecified

  • keycompromise

  • affiliationchanged

  • superseded

  • cessationofoperation

  • cacompromise

Key and Certificate parameters

These parameters define how to store the retrieved certificate and its associated private key. The following alternatives are available:

  • Key and certificate stored separately in two files, in PEM format. This is typically used to be used by Apache or NGINX web servers;

  • Key and certificate stored together in a PKCS#12 file. This is typically used by Tomcat application server;

  • Key and certificate stored together in Windows certificate store. This is typically used by IIS web server.

Table 3. Platform-independent key and certificate parameters
Parameter Description

--key

Path to the private key to store

--cert

Path to the certificate to store

--pfx

Path to the PKCS#12 file storing the certificate and its key

--pfx-pwd

Password used to encrypt the PKCS#12 file specified in the --pfx parameter

--jks

Path to export the certificate and private key as JKS

--jks-pwd

Password used to encrypt the JKS file specified in the --jks parameter

--jks-alias

Alias of the private key entry within the JKS

--jks-key-pwd

Password of the private key entry within the JKS

Table 4. Windows-only key and certificate parameters
Parameter Description

--win-store-save

Triggers the ability to store the certificate and private key into the "MY" certificate store

--win-machine-store

Triggers the ability to store in the Machine store. If not specified, the User store is used. This parameter requires Horizon Client to be executed with appropriate elevated rights

--win-use-tpm

Triggers the ability to store the certificate in the Microsoft Platform Crypto Provider KSP. If not specified, the Microsoft Software Key Storage Provider KSP will be used

Discovery parameter

You can chain a certificate enrollment operation with the discovery operation by using the --discovery parameter. It will use the APIID and APIKey defined in the general configuration to authenticate to Horizon and feed it with the enrolled certificate and its discovery metadata.

The --discovery parameter takes a value, which is the name of the Discovery campaign to use to report the certificate to Horizon.

Script parameter

You can tell Horizon Client to launch a script upon successful certificate enrollment or renewal by using the --script parameter, which takes the path to the script as an argument.

The script will receive arguments passed by Horizon Client in the following order:

  1. Issued certificate serial number

  2. Issued certificate fingerprint (SHA-1 hash of the certificate in DER format - windows store thumbprint)

  3. Issued certificate Subject DN

  4. Issued certificate Issuer DN

Below is an example of a very simple bash script:

#!/bin/sh

echo $1
echo $2
echo $3
echo $4

Below is an example of a very simple PowerShell script:

param($serial, $fingerprint, $subject, $issuer)

Write-Output $serial
Write-Output $fingerprint
Write-Output $subject
Write-Output $issuer

Examples

You will find below a few examples detailing how to use the client for ACME enrollment in various context

Enrollment with HTTP-01 validation, output as key and certificate

horizon-cli acme enroll --profile=<profile> [email protected] --key=/path/to/key --cert=/path/to/cert --dnsnames=test.example.com,www.test.example.com --http-01-port=5002

Enrollment with Cloudflare DNS-01 validation, output as PKCS#12

[email protected] \
CLOUDFLARE_API_KEY=<apikey> \
horizon-cli acme enroll \
  [email protected] \
  --profile=<profile> \
  --cn=test.example.com \
  --dnsnames=test.example.com,www.test.example.com \
  --pfx=/path/to/pkcs12 \
  --pfx-pwd=<pkcs12_password> \
  --dns-01-provider=cloudflare

Enrollment with TLS-ALPN-01 validation, output in machine windows store

horizon-cli acme enroll --profile=<profile> [email protected] --dnsnames=test.example.com,www.test.example.com --win-store-save --win-machine-store --tls-alpn-01-port=5001

Renewal with HTTP-01 or TLS-ALPN-01 validation, output as key and certificate

horizon-cli acme renew --profile=<profile> --account [email protected] --in-cert /path/to/cert --out-key=/path/to/key --out-cert=/path/to/cert --tls-alpn-01-port=5001 --http-01-port=5002

The Client will use either HTTP-01 or TLS-ALPN-01 validation, depending on the authorized validation modes in the profile configuration. If both are authorized, the Client will try them in this order.

Revoking a certificate using the account that enrolled it

horizon-cli acme revoke --profile=<profile> --account [email protected] --in-cert /path/to/cert