Use acme.sh to request free ssl certificates for your site! – esap~!
esap~!
esap~!

Use acme.sh to request free ssl certificates for your site!

Use acme.sh to request free ssl certificates for your site!

What is acme.sh? Why use acme.sh?

An ACME protocol client written purely in Shell (Unix shell) language. Full ACME protocol implementation.
-- From the acme.sh Github project description

In short, acme.sh helps you painlessly apply for and deploy free ssl certificates
Compared to the Certbotclient recommended by Let’s Encrypt  on her website, acme.sh supports more DNS vendors, such as DNSPod (the default DNS vendor when registering domain names using Tencent Cloud), which saves time and effort when using DNS authentication
And Because acme.sh is 100% using Shell Language, so you also do not need to do software adapter can use, also won't produce basic software conflict (I currently use experience)
And, no matter who you are, you don't need root permission to install acme.sh
(But if you apply for a certificate using Webroot mode, it is better to install it using root, as the application process requires the file to be written to the root directory of the website, of course, this is later)
And she has Docker deployment. (what Docker Fans)
(I believe you will love her.)

Currently, acme.sh supports the following ways to apply for a certificate:

  • Webroot mode (Requires the user to have the webroot directory write permission)
  • Standalone mode  (Need to install socat service)
  • Standalone tls-alpn mode  (Need to install socat service)
  • Apache mode (Alternative to Webroot mode verification)
  • Nginx mode (Alternative to Webroot mode verification)
  • DNS mode (Need to apply for DNS API or manually add DNS resolution)
  • DNS alias mode (Please refer to the official documents)
  • Stateless mode (Please refer to the official documents)

This article is written with reference to the official documents of acme.sh and the author's personal experience
If you have any questions about this article, please feel free to comment in the comments section below


Less talk and more action

You can click here to see the detailed operation document
If you need A tutorial on Docker deployment, select the  A little reference for Docker Fans section from the left menu
⚠️ Attention! This article only describes the basic usage, please go to acme.sh to see the detailed operation document

Install acme.sh

You only need one command to install acme.sh
But please note that you need to replace this [email protected] with your own email address

curl https://get.acme.sh | sh -s [email protected]

You can also clone a GIT repository to install it

git clone --depth 1 https://github.com/acmesh-official/acme.sh.git
cd acme.sh
./acme.sh --install -m [email protected]

If your server is in China and the cloning may fail due to network issues, you can use the following command instead

git clone --depth 1 https://gitee.com/neilpang/acme.sh.git
cd acme.sh
./acme.sh --install -m [email protected]

Due to automatically update the certificate need to use the crond service to run, so you need to install the crond service first
You can also add the  --nocron  parameter to install without the crond service, but the automatic certificate update will not work

curl https://get.acme.sh | sh -s [email protected] --nocron

Tips after installation

During the installation process, acme.sh automatically writes your .bashrc file, which allows you to invoke it as if it were a command
That is, you don't need to be in the acme.sh installation directory to use it

Since the default CA of acme.sh is ZeroSSL, in my actual use, I found that ZeroSSL does not seem to adapt to the Chinese network environment, while Let's Encrypt can fully withstand it well, so let's change the CA first

acme.sh --set-default-ca --server letsenctypt

The letsenctypt field can be replaced with a CA that acme.sh supports by default or a link that supports the acme protocol
Click to see which CA acme.sh supports by default

Since acme.sh is currently updated frequently, it is recommended to turn on its automatic updates and check for updates before using it

acme.sh --upgrade --auto-upgrade

Apply for a certificate!

But before you apply, I'd like you to check out these things:

  • In the following section, I'll use  example.com as the request domain, and you need to change this domain name to your own domain
  • If there are any errors during the application process, you can add the —-debug parameter to debug (duh)
    This article will not explore how to debug
  • You can apply for multiple types of certificates by adding the parameter —-keylength (2048|3072|4096|8192|ec-256|ec-384|ec-521)
  • You can apply for certificates for multiple domains at the same time. When you do this, generally speaking, the first domain name that appears in your application command is the main domain name of the certificate. If you are not sure which certificate's primary domain name is, you can use acme.sh --list to find out
  • When you apply for certificates for multiple domain names at the same time, if you specify only one authentication method, then all domains will be authenticated using this method. Of course, you can also specify different authentication methods for different domain names, which is similar to this format:
acme.sh  --issue \
-d aa.com  -w /home/wwwroot/aa.com \
-d bb.com  --dns dns_cf \
-d cc.com  --apache \
-d dd.com  -w /home/wwwroot/dd.com

So now, let's get to work


DNS mode

DNS authentication is divided into automatic DNS authentication (which requires the API provided by the DNS vendor) and manual DNS authentication. Manual DNS authentication does not support automatic renewal
Only DNS authentication supports the application for a universal domain name certificate
(Maybe DNS alias mode works as well? I'll try it then.)

Automatic DNS authentication

Before doing so, please open this page: How to use DNS API
Now, you need to find the DNS vendor that your domain is currently using. Here, choose the commonly used Cloudflare and DNSPod as examples
(Some vendors have special requirements for automatic verification, which is why it is always better to read documentation than to read someone else's article)

Cloudflare

Cloudflare has two API keys, User API Token and Global API Key
Click here to go to the API acquisition page
Using a Global API Key is easier, of course, but it also increases security risks
Global API keys require your Cloudflare Global API Key and Cloudflare Login Email, while User API Token require your User API Token and Zone ID

CloudFlare API页面示例

CloudFlare API Page

To view your Global API Key, click the View button in the Global API Key line of your API page to get your global key
To get the zone key, Please click Create Token -> Edit zone DNS -> Select your domain name under Zone Resources -> Continue to summary to get your User API Token, you can find your domain name Zone ID under your Website Overview

Using Global API Key

export CF_Key="Your Cloudflare Global API Key"
export CF_Email="Your Cloudflare Login Email"

Using User API Token

export CF_Zone_ID="Your Cloudflare Website Zone ID"
export CF_Token="Your Cloudflare User API Token"

Finally, let's apply for the certificate!

acme.sh --issue --dns dns_cf -d example.com -d '*.example.com'
DNSPod

Even the official DNSPod has a tutorial for  acme.sh on DNSPod

If all is well, your certificate will be downloaded automatically

Manual DNS authentication

acme.sh --issue --dns -d example.com \
--yes-I-know-dns-manual-mode-enough-go-ahead-please

You'll get a response like this:

[Sun Feb 11 18:52:50 CST 2024] Add the following TXT record:
[Sun Feb 11 18:52:50 CST 2024] Domain: "_acme-challenge.example.com"
[Sun Feb 11 18:52:50 CST 2024] TXT value: "xxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

Please add a DNS resolution:

  • The DNS resolution type is TXT
  • The name is the content of Domain in the output above, in this case is _acme-challenge.example.com
    Note that in general the dns vendor will automatically add the example.com field for you when you add TXT parsing
  • The DNS resolution content is in the output TXT value , in this case is XXXXXXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXXX

After adding DNS resolution, use this command to continue

acme.sh --issue --renew -d example.com \
--yes-I-know-dns-manual-mode-enough-go-ahead-please

If all is well, your certificate will be downloaded automatically


Webroot mode

As the simplest (and easiest) way to verify, you only need to specify the webroot directory to which your domain name is bound
This example used  /home/wwwroot/example.com  as the webroot directory

acme.sh --issue -d example.com -w /home/wwwroot/example.com

If all is well, your certificate will be downloaded automatically


Standalone mode

There are two kinds of independent verification, but they're pretty much the same
If your server is not running a website service, it is easier to use this method of authentication
This mode is applicable to the server that has no service listen to port 80 or port 443
Since this method depends on the socat service, we need to install the socat service first

#For RHEL Series
sudo dnf install -y socat

#For Debian Series
sudo apt install -y socat

This authentication method needs to listen on port 80/443, so you need to use root permission to authenticate
(What is shown here is only simple usage, if the server has a reverse proxy please check the official documentation of acme.sh)

Using port 80

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

Using port 443

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

If all is well, your certificate will be downloaded automatically


Website service verification

Web service authentication, as the name implies, requires either nginx or Apache httpd to be installed before you use it.
acme.sh will change your website service configuration, but rest assured that it will be changed back to you after the certificate is issued

In fact, according to my tests, Website service verification is just an automation of Stateless mode
It's actually another way of Webroot mode

Nginx mode

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

Apache mode

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

If all is well, your certificate will be downloaded automatically


Install the certificate!

Due to acme.sh does not automatically help us change the web service (such as nginx and Apache httpd) configuration file, so we need to manually tell acme.sh where to place the certificate issued, and what command to reload or restart the website service
Using nginx as an example:

  • The primary domain name of the certificate we installed is example.com
  • The public key is written to /etc/nginx/conf.d/ssl/server.crt
  • The private key is written to /etc/nginx/conf.d/ssl/server.key
  • CA certificate is written to /etc/nginx/conf.d/ssl/ca.crt
  • FullChain is written to /etc/nginx/conf.d/ssl/fullchain.pem
  • The command for the nginx server to reload the configuration file is  nginx -s reload

So, our command should look like this

acme.sh --install-cert -d example.com \
--cert-file      /etc/nginx/conf.d/ssl/server.crt \
--key-file       /etc/nginx/conf.d/ssl/server.key \
--ca-file        /etc/nginx/conf.d/ssl/ca.crt \
--fullchain-file /etc/nginx/conf.d/ssl/fullchain.pem \
--reloadcmd      "nginx -s reload"

After executing this command, if all is well, you will find the certificates in the specified location (they are very good and cute)
If you also specify  —-reloadcmd parameter, acme.sh will attempt to run the specified command and print the output of the command at run time
Don't worry if you get an error running the reload-cmd in acme.sh, just adjust your  —-reloadcmd and run the above installation certificate command once, and  —-reloadcmd  will be overwritten with the latest specified command
⚠️ Note: Applying for a certificate without modifying any configuration file will not work. You will need to modify the configuration file of the website service yourself to deploy the ssl certificate
Please click here to check out the ssl certificate deployment tutorial

That's all! Thank you for reading this article


A little reference for Docker Fans section

Okay, okay, now I know you're going to use Docker
You can refer to The official Docker documentation for acme.sh
I don't like his documentation very much because you have to mount the docker.sock file, which can have security implications
(Docker = Root)
And if you want to deploy to multiple containers at the same time (seems possible?) it can be a bit cumbersome
So here is my solution that supports executing the commands you want on the Docker host after install-cert
Following my lazy habits, I may write an automatic deployment script later, so expect it

Deploy acme-reloader

There are several files that you need to download and unzip

wget https://ftp.esaps.net/dockersh/acme.sh/acme-reloader.tar.gz
tar xzvf acme-reloader.tar.gz

After unzipped, the file directory looks like this

acme-reloader
  |- ssl/
  |   |-
  |- config/
  |   |-
  |- acme-reloader/
  |   |-
  |- acme-reloader-host.service
  |- acme-reloader-host.sh
  |- acme-reloader.sh
  |- docker-compose.yml

Normally, we just need to go into the acme-reloader directory and run docker compose up -d to start the acme.sh container

How to reload a Docker container without mounting docker.sock

Change files first

If you are using Webroot mode, you need to mount your webroot directory into the container

Please find our acme-reloader-host-sh file and find this fragment and modify the file according to the comments (English site users please check the annotation in the file)

function restart_command() {
        #请在这里放下你在证书申请完成之后需要在docker宿主机上执行的命令
        #请类似于这样的格式书写:restart_with "需要执行的命令",一行一条
        #这样才可以在本目录下acme-reloader.log查找到命令执行异常时的日志

        restart_with "YOUR_OWN_SH_COMMAND"

        #输入完成!请不要更改其他文段并享受你的自动化过程吧 :)
        echo "Complete" >> ./socket/acme-reloader.sock
}

Find our acme-reloader-host.service file and make the following changes

  • Replace /path/to/acme-reloader-host.sh_directory with the absolute path of the acme-reloader directory
  • Replace /path/acme-reloader-host.sh with the absolute path to acme-reloader-host.sh

Then, copy the file into the /usr/lib/systemd/system/ directory
(Note that if your Linux distribution is too early, you may be using init.d instead of systemd, and I'm sure you can write your own service script) (sure)
(Forget it. I'll write another one then.)

acme-reloader-host, start!

Run the command to let systemd manipulate our acme-reloader

systemctl daemon-reload                      #重载配置文件,必须执行一次,否则可能提示找不到acme-reloader-host.service
systemctl start acme-reloader-host.service   #启动acme-reloader-host
systemctl stop acme-reloader-host.service    #关闭acme-reloader-host
systemctl restart acme-reloader-host.service #重启acme-reloader-host
systemctl status acme-reloader-host.service  #查看acme-reloader-host运行状态

Before proceeding, you need to start the acme-reloader-host service, otherwise you may receive an error message when acme.sh executes the restart command

It takes a little more work

Copy the acme-reloader.sh file to the root directory of the acme.sh container (replace it with your own container name, but don't change it if you use my docker-compose.yml)

docker cp ./acme-reloader.sh acme.sh:/

Then, apply for a certificate as described in this article~

sudo docker exec -it acme.sh acme.sh

Since we're running in a Docker container, we're replacing the neat acme.sh command in this cumbersome way
If you are annoyed of it, you can execute this command to make it easier

alias acme.sh="docker exec -it acme.sh acme.sh"

You can also go directly into the acme.sh container to do this

docker exec -it acme.sh ash

Next I'll demonstrate directly using the acme.sh command

Since we are running a Docker container, we need to set up an account with the CA

acme.sh  --register-account  --server letsencrypt  -m  [email protected]

And change the default CA of acme.sh

acme.sh --set-default-ca --server letsencrypt

Then you can apply for the certificate as described in this article

Note: If you're using automated DNS authentication, it's better to go straight into the container and apply first, letting acme.sh hold your API key

Last little bit!

Yes, we need to install the certificate

acme.sh --install-cert -d example.com \
--cert-file      /etc/nginx/conf.d/ssl/server.crt \
--key-file       /etc/nginx/conf.d/ssl/server.key \
--ca-file        /etc/nginx/conf.d/ssl/ca.crt \
--fullchain-file /etc/nginx/conf.d/ssl/fullchain.pem \
--reloadcmd      "sh /acme-reloader.sh"

By default, I mounted the /ssl directory for you to the docker container, which is the same directory as docker-compose.yml
--reloadcmd must be changed to "sh /acme-reloader.sh" so that we can notify the host to execute the reload command
If you have not started the acme-reloader-host service on the host machine, you will be prompted
Host error: Unable to connect to host.
In this case, you need to start the acme-reloader-host service before re-installing the certificate
Also, the logs of the acme-reloader-host service are in the same directory as acme-reloader-hoaster.sh. If the reload fails, you can see which command is wrong. meow~

Finished~! Enjoy your certificate automation!
(BTW, you need to change the web server configuration file to deploy certificate yourself, see here)

赞赏
知识共享许可协议
This work is licensed under Creative Commons Attribution 4.0 International license.
Reprint please indicate the article links: https://esaps.net/en/use-acme-sh-to-apply-for-ssl-certificates/

AptS:1547

Article author

This is AptS:1547! Hope to bring you happiness!

Leave a Reply

textsms
account_circle
email

esap~!

Use acme.sh to request free ssl certificates for your site!
Get your own free SSL certificate! Fully automatic and automatically renewed after deployment!
Scan the QR code to continue reading
2024-02-24