ACME-CLIENT(1)

NAME
acme-client - secure ACME client

SYNOPSIS
acme-client [-beFmnNOrsv] [-a agreement] [-C challengedir] [-c certdir] [-f accountkey] [-k domainkey] [-t challenge] domain [altnames...]

DESCRIPTION
The acme-client utility submits an X509 certificate for domain and its alternate DNS names altnames to the “Let's Encrypt” ACME server for automated signing. It can also revoke previously-submitted signatures. It must be run as root. (Why? chroot(2).)

By default, it uses /var/www/acme for responding to challenges (-C), /etc/ssl/acme for the public certificate directory (-c), /etc/ssl/acme/private/privkey.pem for the domain private key (-k), and /etc/acme/privkey.pem for the account private key (-f). All of these must exist unless you use -n and/or -N, which will generate the account and domain private keys, respectively. Its arguments are as follows:

-b  Back up all Certificates in the certificate directory. This will only back up if something will be done to them (remove or replace). The backups are called cert-NNNNN.pem, chain-NNNNN.pem, and fullchain-NNNNN.pem, where NNNNN is the current UNIX epoch. Any given backup effort will use the same epoch time for all three certificates. If there are no certificates in place, this does nothing.

-e  Allow expanding the domains listed in the certificate. This is a no-op if no certificate exists yet. If a new domain is specified, the certificate will be renewed as if -F were also specified.

-F  Force updating the certificate signature even if it's too soon.

-m  Append domain to all default paths except the challenge path (i.e., those that are overriden by -c, -k, -f). Thus, foo.com as the initial domain would make the default domain private key into /etc/ssl/acme/private/foo.com/privkey.pem. This is useful in setups with multiple domain sets. If the foo.com directory is not found within non-overriden default paths, it will be created automatically.

-n  Create a new 4096-bit RSA account key if one does not already exist.

-N  Create a new 4096-bit RSA domain key if one does not already exist.

-O  Request OCSP stapling for the given domains.

-r  Revoke the X509 certificate found in Certificates.

-s  Use the “Let's Encrypt” staging server instead of the real thing.

-v  Verbose operation. Specify twice to also trace communication and data transfers.

-a agreement
    Use an alternative agreement URL. The default uses the current one, but it may be out of date.

-C challengedir
    Where to register challenges. See Challenges for details. Ignored when -t is specified.

-c certdir
    Where to put public certificates. See Certificates for details.

-f accountkey
    The account private key. This was either made with a previous ACME client or with -n.

-k domainkey
    The private key for the domain. This may also be created with -N.

-t challenge
    If not using the internally-handled “http-01” as a challenge type, specify a challenge for the caller to manage. See the Challenges section for details.

domain
    The domain name. The only difference between this and the altnames is that it's put into the certificate's CN field and that it uses the “main” domain when specifying -m.

altnames
    Alternative names (“SAN”) for the domain name. The number of SAN entries is limited by ACME servers, usually to 100 or so.

The process by which acme-client obtains signed certificates is roughly as follows. In this, the “CA” is the ACME server for Let's Encrypt.

1.  Access the CA (unauthenticated) and requests its list of resources.

2.  Optionally create and register a new RSA account key.

3.  Read and process the RSA account key. This is used to authenticate each subsequent communication to the CA.

4.  For each domain name,

    1.  submit a challenge for authentication to the CA,

    2.  create a challenge response file,

    3.  wait until the CA has verified the challenge.

5.  Read and extract the RSA or ECSDA domain key.

6.  Create an X509 request from the domain key for the domain and its alternative names.

7.  Submit a request for signature to the CA.

8.  Download the signed X509 certificate.

9.  Extract the CA issuer from the X509 certificate.

10. Download the certificate chain from the issuer.

The revocation sequence is similar:

1.  Request list of resources, manage RSA account key as in the case for signing.

2.  Read and extract the X509 certificate (if found).

3.  Create an X509 revocation request.

4.  Submit a request for revocation to the CA.

5.  Remove the certificate, the chain, and the full-chain.

  Challenges
ACME uses challenges to verify that the submitter has access to the registered domains. acme-client internally implements only the “http-01” challenge type, where a file is created within a directory accessible by a locally-run web server configured for the requested domain. For example, for the domain “foo.com” and alternate “www.foo.com” and the default challenge directory, an Apache configuration snippet might be as follows:

    <VirtualHost *:80>
      [...]
      ServerName foo.com
      ServerAlias www.foo.com
      Alias /.well-known/acme-challenge /var/www/acme
      <Directory /var/www/acme>
        Options None
        AllowOverride None
        Order allow,deny
        Allow from all
      </Directory>
    </VirtualHost>

This way, the files placed in /var/www/acme will be properly mapped by the web server when the ACME server responds to a challenge.

An alternate challenge type, however, may be specified with -t, in which case the caller must create the challenge environment. This may be used for implementing “dns-01” and other system-specific challenges.

When using -t, each domain (primary and altnames) is authorised over standard output and input between the caller and acme-client as follows:

1.  acme-client prints “challenge-type dns-domain token.thumbprint\n” (note the trailing newline) on its standard output.

2.  The caller performs any tasks to implement the challenge's response.

3.  The caller writes the same three-field string and the newline to the standard input of acme-client.

This cycle repeats for each requested domain, then acme-client exits.

  Certificates
Public certificates (domain certificate, chain, and the full-chain) are placed by default in /etc/ssl/acme as cert.pem, chain.pem, and fullchain.pem, respectively. These are all created as the root user with mode 444.

An nginx configuration using these might be as follows:

    server {
      listen 443;
      server_name foo.com www.foo.com;
      [...]
      ssl_certificate /etc/ssl/acme/fullchain.pem;
      ssl_certificate_key /etc/ssl/acme/private/privkey.pem;
    }

The cert.pem file, if found, is checked for its expiration: if more than 30 days from expiring, acme-client will not attempt to refresh the signature.

EXIT STATUS
acme-client returns 1 on failure, 2 if the certificates didn't change (up to date), or 0 if certificates were changed (revoked or updated).

EXAMPLES
To create and submit a new key for a single domain, assuming that the web server has already been configured to map the challenge directory as in the Challenges section:

    # mkdir /var/www/acme
    # mkdir /etc/ssl/acme
    # mkdir /etc/ssl/acme/private /etc/acme
    # chmod 0700 /etc/ssl/acme/private /etc/acme
    # acme-client -vNn foo.com www.foo.com smtp.foo.com

After generating the necessary directories, the above will create all keys and submit them to the server. You'll then probably want to restart your web server to pick up the new certificates.

You can then keep your certificates fresh with a daily cron(8) invocation running the following:

    #! /bin/sh
    acme-client foo.com www.foo.com smtp.foo.com
    if [ $? -eq 0 ]
    then
    	/etc/rc.d/httpd reload
    fi

You'll need to replace the httpd-reload statement with the correct script to have your web server reload its certificates.

SEE ALSO
openssl(1)

AUTHORS
The acme-client utility was written by Kristaps Dzonsons <kristaps@bsd.lv>. It was originally named letskencrypt, renamed at version 0.1.11.

BUGS
The challenge and certificate processes currently retain their (root) privileges.

For the time being, acme-client only supports RSA as an account key format.