How to Use Acme.sh to Provision LetsEncrypt SSL Certificates

LetsEncrypt has changed the face of SSL certification issuance. Making it easy for website developers to freely and easily issue an SSL certificate, LetsEncrypt has opened the floodgate to properly securing every website. A service is often only as good as its tools and an open-source project that has gained traction is the Acme.sh shell utility.

There are three functional steps in retrieving an SSL certificate from LetsEncrypt, requesting the certificate, verifying that the requestor is authorized, and issuing the certificate. Acme.sh makes all three of these steps easy, offering flexibility in what type of certificates are requested and how they are verified.

Installing Acme.sh on Ubuntu

There are two main ways to install Acme.sh. In this example, we are installing the utility to a recent version of Ubuntu. Acme.sh is written in the common Unix sh language, therefore it can be run on virtually every flavor of Linux and Mac OS X, even Windows with the right Cygwin setup!

Installation via the Web

This is the easiest method of installation, you can quickly install and get started with configuring. Some folks may not be comfortable with this due to directly installing from the internet.

# Directly download using the curl utility and pipe to sh to run.
curl <https://get.acme.sh> | sh
# Alternatively, use wget to download the installation file and pipe to sh to run.
wget -O -  <https://get.acme.sh> | sh

Installation via Git

If installing the utility directly from the web is not preferred, you can use git to clone the repository and run the installation from there.

git clone <https://github.com/acmesh-official/acme.sh.git>
cd ./acme.sh
./acme.sh --install

Either method will perform the following three actions. Technically, all three can be done individually, if desired but the installation script makes this quick and easy.

  1. Create and copy acme.sh to your home dir ($HOME): ~/.acme.sh/. All certs will be placed in this folder too.
  2. Create alias for: acme.sh=~/.acme.sh/acme.sh.
  3. Create daily cron job to check and renew the certs if needed.

Read on to learn how to issue a certificate using both the traditional file-based method and the DNS based method.

Issuing, Renewing, and Removing an SSL Certificate

There are multiple methods and ways to issue an SSL certificate using Acme.sh, but we are going to look at two common and easy to use methods, file-based, and DNS based. First, let’s look at the most common method below. This will request a certificate with an additional wildcard subject-alternate name (SAN) entry of *.[mydomain.com](<http://mydomain.com>). Why would you want both versions? If your site responds to both mydomain.com and www.mydomain.com, then you will want a certificate that satisfies both requests. Otherwise, the second request will fail, leading to a poor user experience.

acme.sh --issue -d mydomain.com -d '*.mydomain.com' -w /var/www/html

An example NGINX configuration is below, using the file-based .well-known folder. This will allow NGINX to respond to SSL authorization requests. Acme.sh must have writeable access to this folder.

This can be a standalone *.conf file that is included in the server configuration block of a NGINX vhost file.

# Rule for legitimate ACME Challenge requests (like /.well-known/acme-challenge/xxxxxxxxx)
# We use ^~ here, so that we don't check other regexes (for speed-up). We actually MUST cancel
# other regex checks, because in our other config files have regex rule that denies access to files with dotted names.
location ^~ /.well-known/acme-challenge/ {
    # Set correct content type. According to this:
    # <https://community.letsencrypt.org/t/using-the-webroot-domain-verification-method/1445/29>
    # Current specification requires "text/plain" or no content header at all.
    # It seems that "text/plain" is a safe option.
    default_type "text/plain";
}

# Prevent direct access to the top level folder.
location = /.well-known/acme-challenge/ {
    return 404;
}

The second method is to use a DNS provider, such as Cloudflare which is demoed below, to verify ownership of the domain. You will need to define an ~\\.acme.sh\\account.conf file with the following values.

SAVED_CF_Key='examplekey'
SAVED_CF_Email='[email protected]'
# If you use Cloudflare tokens, you would use the alternative variables.
# SAVED_CF_Token='exampletoken'
# SAVED_CF_Account_ID='accountid'

Once the account.conf file has been created you can issue a near-identical command from above, but using the --dns dns_cf option. This will create a temporary txt DNS record that will be used by LetsEncrypt and Acme.sh to verify ownership of the domain.

acme.sh --issue --dns dns_cf -d mydomain.com -d '*.mydomain.com'

SSL Certificate Renewals

The cron job that Acme.sh creates upon installation will also take care of renewals. There is no need to do anything, but if you need to force a renewal you can do so like below.

acme.sh --renew -d mydomain.com -d '*.mydomain.com' --force

Removing an SSL Certificate from Acme.sh Renew List

An SSL certificate will cease to validate when the certificate is not removed, to prevent Acme.sh from doing so, you can issue the following command.

acme.sh --remove -d mydomain.com -d '*.mydomain.com'

This will not remove the certificate stored on disk, in the same directory as Acme.sh, so you will need to remove that yourself.

Conclusion

LetsEncrypt and Acme.sh make retrieving and managing SSL certificates quick and easy. Using the familiar command-line shell interface that many system administrators are used to, using Acme.sh could not be easier. Secure your websites today!