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) 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.
You have a few options to install acme.sh.
Install from web via
curl https://get.acme.sh | sh source ~/.bashrc
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
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:
- Create and copy
acme.shto your home dir (
~/.acme.sh/. All certs will be placed in this folder too.
- Create alias for:
- Create daily cron job to check and renew the certs if needed.
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.
--homeis a customized directory to install
acme.shin. By default, it installs into
--config-homeis a writable folder, acme.sh will write all the files(including cert/keys, configs) there. By default, it’s in
--cert-homeis a customized dir to save the certs you issue. By default, it’s saved in
--accountemailis the email used to register account to Let’s Encrypt, you will receive renewal notice email here. Default is empty.
--accountkeyis the file saving your account private key. By default it’s saved in
--useragentis 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 # v2.8.1
The program has a lot of commands and parameters that can be used. To get help you can run:
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
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/apache2/ssl for example, depending on your web server software and your own preferences to store SSL related stuff.
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"
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:
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.