Background

If you have a website or an independent blog, you need to care about the expiration of your website’s SSL certificate every year. Recently, the wnote.com certificate is about to expire;

Applying for an SSL certificate allows the website to support https access. There are free and paid ones on the market;

For free certificates, domestic mainstream cloud vendors such as Alibaba, Tencent, ucloud and other platforms have free SSL certificate channels, which are generally valid for 1 year and need to be applied manually. Of course, if your users are mainly overseas, you can consider cloudflare’s CDN security protection, which provides free SSL certificates by default.

Of course, those who like to tinker can also use Let’s Engypt’s free certificates, which can be moved to https://letsencrypt.org/. The official generally recommends Certbot client to apply, and it also supports ACME protocol. I won’t introduce it too much here;

Today we mainly use acme.sh to apply for free certificates. On the one hand, acme.sh fully supports ACME protocol, and another advantage is that it supports wildcard domain name certificates and can be automatically renewed.

By default, acme.sh applies for free certificates from https://zerossl.com, with no quantity limit. If you go directly to the zerossl official website to apply, you can apply for up to three free certificates.

acme.sh project address:

https://github.com/acmesh-official/acme.sh

Install ACME

After the normal installation, the installation directory is: ~/.acme.sh/, and all subsequent certificates will also be placed in this folder.

1
2
3
git clone https://github.com/acmesh-official/acme.sh.git
cd ./acme.sh
./acme.sh --install -m my@example.com #Change here to your own email

The installation program performs a total of 3 operations:

  • Create and copy acme.sh to your home directory ($HOME): ~/.acme.sh/.

  • Create an alias acme.sh=~/.acme.sh/acme.sh for:

  • If necessary, create a daily cron job to check and update certificates.

Apply for a certificate

Issue a certificate using http

For one certificate and one domain name:

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

Or:

1
acme.sh --issue -d example.com -w /home/username/public_html

Or:

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

For the same certificate containing multiple domain names.

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

The -d parameter is the domain name for which the certificate is issued to you. There must be at least one domain name, and it forms a binding relationship with the following -w parameter;

The -w parameters /home/wwwroot/example.com, /home/username/public_html, and /var/www/html are the web root folders where you host website files. You must have writable permissions. Acme.sh will create a .well-known directory under the website root directory, in which it will generate a verification file to verify that you are the website owner.

The certificate is placed in ~/.acme.sh/example.com/ by default, and the certificate will be automatically renewed every 60 days.

Automatic DNS API Certificate Issuance

If your DNS provider supports API access, you can use the API to automatically issue certificates without having to do anything manually!

For supported DNS providers, please refer to https://github.com/acmesh-official/acme.sh/wiki/dnsapi

My domain name wnote.com is in Alibaba Cloud, which happens to be on the support list, so I will use this method to apply for the certificate this time.

First, we need to apply for the key pair of the account at Alibaba Cloud. The specific link is: https://ram.console.aliyun.com/manage/ak. After the application is successful, we will get the AccessKey ID and AccessKey Secret. Record them for the convenience of applying for the certificate below. If the certificate is successfully applied for later, the key pair will be recorded in the ~/.acme.sh/account.conf file, which is convenient for cron to automatically renew the certificate later.

1
2
3
root@VM-0-3-ubuntu:~# export Ali_Key="LTII5t8tE4IgMFGDK6iTcs2A"
root@VM-0-3-ubuntu:~# export Ali_Secret="Ku7q3lPJMISlJqZ9OomLOfzO8LFVff"
root@VM-0-3-ubuntu:~# acme.sh --issue --dns dns_ali -d wnote.com -d *.wnote.com #I am applying for the primary domain certificate and wildcard domain name certificate here

The application waiting log is as follows, about 2 minutes:

1
2
3
4
5
6
7
[Fri 11 Nov 2022 10:40:31 PM CST] Using CA: https://acme.zerossl.com/v2/DV90
[Fri 11 Nov 2022 10:40:31 PM CST] Multi domain='DNS:wnote.com,DNS:*.wnote.com'
[Fri 11 Nov 2022 10:40:31 PM CST] Getting domain auth token for each domain
[Fri 11 Nov 2022 10:40:34 PM CST] Could not get nonce, let's try again.
[Fri 11 Nov 2022 10:40:41 PM CST] Could not get nonce, let's try again.
[Fri 11 Nov 2022 10:40:47 PM CST] Could not get nonce, let's try again. [Fri 11 Nov 2022 10:41:38 PM CST] Getting webroot for domain='wnote.com' [Fri 11 Nov 2022 10:41:38 PM CST] Getting webroot for domain='*.wnote.com' [Fri 11 Nov 2022 10:41:38 PM CST] Adding txt value: 9 QXV-Ve3eEI-JCLjJ7RkMMvPGNaTzV3YmlaXWtwrJVM for domain: _acme-challenge.wnote.com [Fri 11 Nov 2022 10:41:40 PM CST] The txt record is added: Success. [Fri 11 Nov 2022 10:41:40 PM CST] Adding txt value: KXKFA3BChlz0c5NTHN4fmO8jo-e3DbMu0VybF-YohTw for domain: _acme-challenge.wnote.com [Fri 11 Nov 2022 10:41:42 PM CST] The txt record is added: Success. [Fri 11 Nov 2022 10:41:42 PM CST] Let's check each DNS record now. Sleep 20 seconds first. [Fri 11 Nov 2022 10:42:03 PM CST] You can use '--dnssleep' to disable public dns checks. [Fri 11 Nov 2022 10:42:03 PM CST] See: https://github.com/acmesh-official/acme.sh/wiki/dnscheck [Fri 11 Nov 2022 10:42:03 PM CST] Checking wnote.com for _acme-challenge.wnote.com [Fri 11 Nov 2022 10:42:06 PM CST] Domain wnote.com '_acme-challenge.wnote.com' success. [Fri 11 Nov 2022 10:42:06 PM CST] Checking wnote.com for _acme-challenge.wnote .com [Fri 11 Nov 2022 10:42:07 PM CST] Domain wnote.com '_acme-challenge.wnote.com' success. [Fri 11 Nov 2022 10:42:07 PM CST] All success, let's return [Fri 11 Nov 2022 10:42:07 PM CST] Verifying: wnote.com [Fri 11 Nov 2022 10:42:12 PM CST] Processing, The CA is processing your order, please just wait. (1/30) [Fri 11 Nov 2022 10:42:20 PM CST] Processing, The CA is processing your order, please just wait. (2/30) [Fri 11 Nov 2022 10:42:29 PM CST] Processing, The CA is processing your order, please just wait. . (3/30) [Fri 11 Nov 2022 10:42:38 PM CST] Processing, The CA is processing your order, please just wait. (4/30) [Fri 11 Nov 2022 10:42:46 PM CST] Processing, The CA is processing your order, please just wait. (5/30) [Fri 11 Nov 2022 10:42:55 PM CST] Processing, The CA is processing your order, please just wait. (6/30) [Fri 11 Nov 2022 10:43:02 PM CST] Success [Fri 11 Nov 2022 10:43:02 PM CST] Verifying: *.wnote.com [Fri 11 Nov 2022 10:43:06 PM CST] Processing, The CA is processing your order, please just wait. (1/30) [Fri 11 Nov 2022 10:43:13 PM CST] Processing, The CA is processing your order, please just wait. (2/30) [Fri 11 Nov 2022 10:43:28 PM CST] Processing, The CA is processing your order, please just wait. (3/30) [Fri 11 Nov 2022 10:43:41 PM CST] Processing, The CA is processing your order, please just wait. (4/30) [Fri 11 Nov 2022 10:43:48 PM CST] Processing, The CA is processing your order, please just wait. (5/30) [Fri 11 Nov 2022 10:43:52 PM CST] Processing, The CA is processing your order, please just wait. (6/30) [Fri 11 Nov 2022 10:43:58 PM CST] Processing, The CA is processing your order, please just wait. (7/30) [Fri 11 Nov 2022 10:44:10 PM CST] Processing, The CA is processing your order, please just wait. (8/30) [Fri 11 Nov 2022 10:44:29 PM CST] Processing, The CA is processing your order, please just wait. (9/30) [Fri 11 Nov 2022 10:44:59 PM CST] Success [Fri 11 Nov 2022 10:44:59 PM CST] Removing DNS records. [Fri 11 Nov 2022 10:44:59 PM CST] Removing txt: 9QXV-Ve3eEI-JCLmJ7RkLMv PGNaTzV3YmlaXWtwrJVM for domain: _acme-challenge.wnote.com [Fri 11 Nov 2022 10:45:02 PM CST] Removed: Success [Fri 11 Nov 2022 10:45:02 PM CST] Removing txt: KXKKA3BChlz0c5NOHN4fmk8jo-e3DMMu0VybF-YohTw for domain: _acme-challenge.wnote.com [Fri 11 Nov 2022 10:45:06 PM CST] Removed: Success [Fri 11 Nov 2022 10:45:06 PM CST] Verify finished, start to sign. [Fri 11 Nov 2022 10:45:06 PM CST] 10:45:06 PM CST] Lets finalize the order. [Fri 11 Nov 2022 10:45:06 PM CST] Le_OrderFinalize='https://acme.zerossl.com/v2/DV90/order/FYF3wr0jlkJarp3dFuRaKg/finalize' [Fri 11 Nov 2022 10:45:33 PM CST] Order status is processing, lets sleep and retry. [Fri 11 Nov 2022 10:45:33 PM CST] Retry after: 15 [Fri 11 Nov 2022 10:45:49 PM CST] Polling order status: https://acme.zerossl.com/v2/DV90/order/FYF3wr0jlkJarp3dFuRaKg [Fri 11 Nov 2022 10:45:55 PM CST] Downloading cert. [Fri 11 Nov 2022 10:45:55 PM CST] Le_LinkCert='https://acme.zerossl.com/v2/DV90/cert/RVtakD091ssrWC6HxgcWxQ' [Fri 11 Nov 2022 10:46:02 PM CST] Cert success.
-----BEGIN CERTIFICATE----- MIIGbjCCBFagAwIBAgIRAOee+mMTTeRu9hUkpcDXkQcwDQYJKoZIhvcNAQEMBQAw SzELMAkGA1UEBhMCQVQxEDAOBgNVBAoTB1plcm9TU0wxKjAoBgNVBAMTIVplcm9T U0wgUlNBIERvbWFpbiBTZWN1cmU gU2l0ZSBDQTAeFw0yMjE xMTEwMDAwMDBaFw0y ...... ...... Sojv2 JHNsJhGlwrhqORg91jodBBl4 -----END CERTIFICATE----- [Fri 11 Nov 2022 10:46:02 PM CST] Your cert is in: /root/.acme.sh/wnote.com/wnote.com.cer [Fri 11 Nov 2022 10:46: 02 PM CST] Your cert key is in: /root/.acme.sh/wnote.com/wnote.com.key [Fri 11 Nov 2022 10:46:02 PM CST] The intermediate CA cert is in: /root/ .acme.sh/wnote.com/ca.cer [Fri 11 Nov 2022 10:46:02 PM CST] And the full chain certs is there: /root/.acme.sh/wnote.com/fullchain.cer 

Manual DNS certificate issuance

If the DNS service provider is not in the ACME support list, you can apply manually:

Add a TXT record in the domain name resolution, the format is as follows:

1
2
3
4
5
Domain name: _acme-challenge.example.com
Txt record value: 9ihDbjYfTExAYeDs4DBUeuTo18KBzwvTEjUnSwd32-c

Domain name: _acme-challenge.www.example.com
Txt record value: 9ihDbjxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Apply for a certificate:

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

Changing CA

Currently, acme.sh supports four official environment CAs, namely Let’s Encrypt, Buypass, ZeroSSL and SSL.com. ZeroSSL is used by default.

If you need to change, you can use the following command:

1
2
3
4
5
6
7
8
9
acme.sh --set-default-ca --server letsencrypt

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

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

acme.sh --set-default-ca --server ssl.com

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

Note: It is not recommended to use Google CA for domestic websites, because many The domain name is inaccessible and the application verification fails. For the free address of Google Public CA, please refer to: https://cloud.google.com/certificate-manager/docs/public-ca-tutorial

Update Docker and nginx configuration

After applying for the certificate, we Need to update docker-compose and nginx configuration,

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
version: "3"
services:
nginx:
image: nginx:1.18.0
volumes:
- ./conf/nginx.conf:/etc/nginx/nginx.conf - /opt/wwwroot/wnote.com:/opt/wnote.com - /root/.acme.sh/wnote.com:/opt/ssl - ./logs:/var/log/nginx restart: always ports: - 443:443 - 80:80 networks: - my-nginx networks: my-nginx: driver: bridge ``` ```yaml server { listen 443 ssl http2; server_name wnote.com www.wnote.com; root /opt/wnote.com; ssl_certificate /opt/ssl/wnote.com.cer; ssl_certificate_key /opt/ssl/wnote.com.key; ssl_session_timeout 5m;
ssl_session_cache shared:SSL:1m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;

location / {
root /opt/wnote.com;
index index.html index.htm;
}
}
server {
listen 80;
server_name wnote.com;
rewrite ^ https://$host$1 permanent;
} ```

At this point, the application of free certificates and wildcard domain name certificates using acme.sh has come to an end.