Getting started with acme.sh Let's Encrypt SSL client

Acme.sh is a simple, powerful and easy to use ACME protocol client written purely in Shell (Unix shell) language, compatible with bash, dash, and sh shells. It helps manage installation, renewal, revocation of SSL certificates. It supports ACME version 1 and ACME version 2 protocols, as well as ACME v2 wildcard certificates. Being a zero dependencies ACME client makes it even better. You don't need to download and install the whole internet to make it running. The tool does not require root or sudo access, but it's recommended to use root.

Acme.sh supports the following validation methods that you can use to confirm domain ownership:

  • Webroot mode
  • Standalone mode
  • Standalone tls-alpn mode
  • Apache mode
  • Nginx mode
  • DNS mode
  • DNS alias mode
  • Stateless mode

What is Let's Encrypt

Let’s Encrypt (LE) is a certificate authority (CA) and project that offers free and automated SSL/TLS certificates, with the goal of encrypting the entire web. If you own a domain name and have shell access to your server you can utilize Let's Encrypt to obtain a trusted certificate at no cost. Let's Encrypt can issue SAN certs for up to 100 hostnames and wildcard certificates. All certs are valid for the period of 90 days.

Acme.sh usage and basic commands

In this section, I will show some of the most common acme.sh commands and options.

Acme.sh installation

You have a few options to install acme.sh.

Install from web via curl or wget:

curl https://get.acme.sh | sh
source ~/.bashrc

or

wget -O - https://get.acme.sh | sh
source ~/.bashrc

Install from GitHub:

curl https://raw.githubusercontent.com/Neilpang/acme.sh/master/acme.sh | INSTALLONLINE=1 sh

or

wget -O - https://raw.githubusercontent.com/Neilpang/acme.sh/master/acme.sh | INSTALLONLINE=1 sh

Git clone and install:

git clone https://github.com/Neilpang/acme.sh.git
cd ./acme.sh
./acme.sh --install
source ~/.bashrc

The installer will perform 3 actions:

  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.

Advanced installation:

git clone https://github.com/Neilpang/acme.sh.git
cd acme.sh
./acme.sh --install \
--home ~/myacme \
--config-home ~/myacme/data \
--cert-home ~/mycerts \
--accountemail "[email protected]" \
--accountkey ~/myaccount.key \
--accountconf ~/myaccount.conf \
--useragent "this is my client."

You don't need to set all options, just set those ones you care about.

Options explained:

  • --home is a customized directory to install acme.sh in. By default, it installs into ~/.acme.sh.
  • --config-home is a writable folder, acme.sh will write all the files(including cert/keys, configs) there. By default, it's in --home.
  • --cert-home is a customized dir to save the certs you issue. By default, it's saved in --config-home.
  • --accountemail is the email used to register account to Let's Encrypt, you will receive renewal notice email here. Default is empty.
  • --accountkey is the file saving your account private key. By default it's saved in --config-home.
  • --useragent is the user-agent header value used to send to Let's Encrypt.

After installation is complete, you can verify it by checking acme.sh version:

acme.sh --version
# v2.8.1

The program has a lot of commands and parameters that can be used. To get help you can run:

acme.sh --help

Issue an SSL cert

If you already have a web server running, you should use webroot mode. You will need write access to the web root folder. Here are some example commands that can be used to obtain cert via webroot mode:

Single domain + Webroot mode:

acme.sh --issue -d example.com --webroot /var/www/example.com

Multiple domains in the same cert + Webroot mode:

acme.sh --issue -d example.com -d www.example.com -d mail.example.com --webroot /var/www/example.com

Single domain ECC/ECDSA cert + Webroot mode:

acme.sh --issue -d example.com --webroot /var/www/example.com --keylength ec-256

Multiple domains in the same ECC/ECDSA cert + Webroot mode:

acme.sh --issue -d example.com -d www.example.com -d mail.example.com --webroot /var/www/example.com --keylength ec-256

Valid values for --keylength are: 2048 (default), 3072, 4096, 8192 or ec-256, ec-384.

If you don't have a web server, maybe you are on a SMTP or FTP server, the 80 port is free, then you can use standalone mode. If you want to use this mode, you'll need to install socat tools first.

Single domain + Standalone mode:

acme.sh --issue -d example.com --standalone

Multiple domains in the same cert + Standalone mode:

acme.sh --issue -d example.com -d www.example.com -d mail.example.com --standalone

If you don't have a web server, maybe you are on a SMTP or FTP server, the 443 port is free. You can use standalone TLS ALPN mode. Acme.sh has a builtin standalone TLS web server, it can listen at 443 port to issue the cert.

Single domain + Standalone TLS ALPN mode:

acme.sh --issue -d example.com --alpn

Multiple domains in the same cert + Standalone TLS ALPN mode:

acme.sh --issue -d example.com -d www.example.com --alpn

Automatic DNS API integration

If your DNS provider has an API, acme.sh can use the API to automatically add the DNS TXT record for you. Your cert will be automatically issued and renewed. No manually work is required. Before requesting the certs configure your API keys and Email. Currently acme.sh has automatic DNS integration with around 60 DNS providers natively and can utilize Lexicon tool for those that are not supported natively.

Single domain + CloudFlare DNS API mode:

export CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
export CF_Email="[email protected]"
acme.sh --issue -d example.com --dns dns_cf

Wildcard cert + CloudFlare DNS API mode:

export CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
export CF_Email="[email protected]"
acme.sh --issue -d example.com -d '*.example.com' --dns dns_cf

If your DNS provider doesn't support any API access, you can add the TXT record manually.

acme.sh --issue --dns -d example.com -d www.example.com -d cp.example.com

You should get an output like below:

Add the following txt record:
Domain:_acme-challenge.example.com
Txt value:9ihDbjYfTExAYeDs4DBUeuTo18KBzwvTEjUnSwd32-c

Add the following txt record:
Domain:_acme-challenge.www.example.com
Txt value:9ihDbjxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Please add those txt records to the domains. Waiting for the dns to take effect.

Then just rerun with renew argument:

acme.sh --renew -d example.com

Keep in mind that this is DNS manual mode and you can't auto renew your certs. You will have to add a new TXT record to your domain by your hand when it's time to renew certs. So use DNS API mode instead, because it can be automated.

Install Let's encrypt SSL cert

After cert(s) are generated, you probably want to install/copy issued certificate(s) to the correct location on the disk. You must use this command to copy the certs to the target files, don't use the certs files in ~/.acme.sh/ folder, they are for internal use only, the folder structure may change in the future. Before installation, create a sensible directory to store your certificates. That can be /etc/letsencrypt, /etc/nginx/ssl or /etc/apache2/ssl for example, depending on your web server software and your own preferences to store SSL related stuff.

Apache example:

acme.sh --install-cert \
--domain example.com \
--cert-file /path/to/cert/cert.pem \
--key-file /path/to/keyfile/key.pem \
--fullchain-file /path/to/fullchain/fullchain.pem \
--reloadcmd "sudo systemctl reload apache2.service"

Nginx example:

acme.sh --install-cert \
--domain example.com \
--cert-file /path/to/cert/cert.pem \
--key-file /path/to/keyfile/key.pem \
--fullchain-file /path/to/fullchain/fullchain.pem \
--reloadcmd "sudo systemctl reload nginx.service"

The parameters are stored in the .acme.sh configuration file, so you need to get it right for your system as this file is read when the cron job runs renewal. "reloadcmd" is dependent on your operating system and init system. 

Renew the Let's Encrypt SSL certs

You don't need to renew the certs manually. All the certs will be renewed automatically every 60 days.

However, you can also force to renew a cert:

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

or, for ECC cert:

acme.sh --renew -d example.com --force --ecc

How to upgrade acme.sh

You can update acme.sh to the latest code with:

acme.sh --upgrade

You can also enable auto upgrade:

acme.sh --upgrade --auto-upgrade

Then acme.sh will be kept up to date automatically.

That's it. If you get stuck on anything visit acme.sh wiki page at https://github.com/Neilpang/acme.sh/wiki

Share this page:

Suggested articles

0 Comment(s)

Add comment