Let's Encrypt

LetsEncrypt changed the SSL certificate world when its offer of free, short-lived, SSL certificates allowed a vast amount of individuals and companies to secure their web applications at no cost. With this service, the necessary infrastructure would need to exist, and to that end, a plethora of applications sprung up that fit the SSL-issuing needs.

One of the most common utilities is that of CertBot, which can work well, but another open-source application that is available is acme.sh. This is an entirely shell-based ACME (the protocol used by LetsEncrypt for issuing SSL certificates) client. With a lot of advanced functionality built-in, this client allows for complex configurations.

Installing Acme.sh

The easiest way to install [acme.sh](<http://acme.sh>) is the following, which downloads and executes the script from here, https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh.

curl <https://get.acme.sh> | sh

The source for that site is located here, if you would like to verify what the actual script is doing

The installation will download and move the files to ~/.acme.sh, and install an alias into your ~/.bashrc file. Additionally, a cron job will be installed if available.

Installing Acme.shc

First Steps

A lot of how you use [acme.sh](<http://acme.sh>) depends on the method and application that you are requesting the certificate for. Acme.sh offers many different methods to actually request a certificate such as:

In this article, I’m going to demonstrate two different ways to request a certificate. I am including web server configurations for both NGINX and Apache, which uses the Webroot method. The DNS mode method uses a configuration file to create CNAME records that are used to verify the domain, instead of creating a file on the file system.

Web Server Configuration

NGINX LetsEncrypt Configuration

NGINX makes it easy to create a shared configuration to use when using the webroot method of requesting a certificate.


It is recommended to create a standalone configuration that can be included as needed in the vhost configurations, like so: include /etc/nginx/letsencrypt.conf

# 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";

# Direct access returns a 404
location = /.well-known/acme-challenge/ {
   return 404;


Much like NGINX, Apache can create a separate configuration file. An example of this configuration is shown below.


In this case, the Apache configuration is specific to the virtual host due to the need to include the disk location. The following is a common location, but it may be differ depending on your specific configuration.

Alias /.well-known/acme-challenge/ "/var/www/html/.well-known/acme-challenge/"
<Directory "/var/www/html/">
    AllowOverride None
    Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
    Require method GET POST OPTIONS

DNS Configuration

In this article, I am demonstrating the DNS mode using Cloudflare, as it offers extremely quick DNS changes and works exceptionally well with this method.

Acme.sh uses two environmental variables for the dns_cf method: CF_Key and CF_Email. To include this in your environment upon startup, you can include this config within your .bashrc file.

It may not be readily apparent, but there is a preceding space before each export command, which generally ensures that they won’t be read into history, just in case.

 export CF_Key="#########..."
 export CF_Email="cfaccount@email.com"

Issue Certificate via Webroot Method

When issuing the following command, two domains are defined in a single certificate. This is to make sure that when either hostname is requested (and often redirected to the canonical one), the request will still be protected by a secure connection.

acme.sh --issue -d example.com -d www.example.com -w /var/www/html

Issued certificates are in /.acme.sh/acme.sh/{domain_name}

Issue Certificate via DNS Method

When using the DNS-issuing method, a temporary txt record is created via the Cloudflare API, and LetsEncrypt verifies the domain using that temporary record. This is a cleaner method, as no webroot configuration is needed.

# Multiple Domains
acme.sh --issue --dns dns_cf -d example.com -d www.example.com

Issued certificates are in /.acme.sh/acme.sh/{domain_name}

Renewing Certificate

By default, Acme.sh, will create a cronjob like the following entry:

48 0 * * * "/home/user/.acme.sh/acme.sh" --cron --home "/home/user/.acme.sh" > /dev/null

To force a renewal, you can issue the following command, which will use the same issuing method as originally used:

acme.sh --renew -d example.com -d www.example.com

Removing Certificates

If you no longer want to renew a certificate, it’s very easy to remove. This does not remove the certificate from the disk, though. To do that, you will need to navigate to ~/.acme.sh/ and remove the directory containing the certificates.

acme.sh --remove -d example.com -d www.example.com

This does allow one to clean up the certificates that are set up for renewal, which you can check by listing the certificates like so:

acme.sh --list


LetsEncrypt offers an excellent and easy-to-use service for provisioning SSL certificates for use in websites. Creating a secure website is easier than ever, and using the acme.sh client means you have complete control over how this occurs on your web server.

With a number of different methods to obtain a certificate, even very secure methods, such as a delegated domain, allows one to properly retrieve the needed certificates.

Profile Photo for Adam Bertram Adam Bertram
Adam Bertram is a 20+ year veteran of IT and an experienced online business professional. He’s a consultant, Microsoft MVP, blogger, trainer, published author and content marketer for multiple technology companies.
Read Full Bio »