使用acme.sh与阿里云DNS签发Let’s Encrypt的免费数字证书

0x01 前言

Let’s Encrypt项目开展一年多了,很早以前已经支持泛域名证书的签发,而我的博客从该项目正式运行的时候也切换到Let’s Encrypt的数字证书。

刚开始的时候签发证书比较繁琐,需要自己手敲命令,但后来有位大佬创建了acme.sh这个项目,以下是该项目的GitHub地址:

通过访问acme.sh一样可以打开该项目的GitHub页面噢。因为该项目是国人创建的,所以会有中文版本的说明文档。

而今天这篇文章只是记录下我日常使用的情况,主要结合阿里云的DNS服务申请和续签免费的Let’s Encrypt数字证书。因为我使用的功能比较单一,所以文章里没有其他高级功能的部分,如果有需要,请留意该项目的中文说明部分。如果以后有需求,我会撰写文章,额外说明。

0x02 准备

Let’s Encrypt只支持DV证书的签发,也就是通过验证域名所有权,然后签发该域名的证书。它支持两种验证方式,一种是通过HTTP的方式验证,另一种是通过DNS的方式验证,而今天要讲的就是第二种方式。

首先得准备一个可以使用阿里云DNS解析服务的阿里云账号。阿里云的DNS解析服务是免费的,但免费版本的TTL最小为10分钟,如果需要更小的TTL值,则需要购买升级服务。相关咨询可以参考以下文章:

但Let’s Encrypt验证DNS对TTL并没有要求,用免费版的阿里云DNS解析服务是可以的。

紧接着需要将你的域名解析权赋予阿里云,首先在阿里云的DNS解析服务中添加你的域名:

使用acme.sh与阿里云DNS签发Let’s Encrypt的免费数字证书

域名添加完成后会给出两个DNS服务器的域名,这时候需要在你购买域名的厂商中将域名的DNS服务器修改为给出的DNS服务器即可。

稍等片刻,当页面中出现绿色勾勾,则说明DNS服务器切换完成,你域名正由阿里云提供解析服务。

接下来要准备acme.sh源码,直接使用git clone即可将源码克隆到本地:

1

[[email protected] ~]# git clone https://github.com/Neilpang/acme.sh.git

在签发证书前还得准备阿里云账户的API key,打开以下地址并创建AccessKey即可:

使用acme.sh与阿里云DNS签发Let’s Encrypt的免费数字证书

注意!阿里云支持子账户功能,为了提高安全性,请参考阿里云的文档,创建子账户后再创建API key,但这不是必须操作的。

创建完成后将AccessKey ID与Access Key Secret记下来备用。

0x03 acme.sh

我们已经准备好一切,接下来先安装acme.sh到本地,进入源码文件夹并执行以下命令即可:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

# 进入文件夹

[[email protected] ~]# cd acme.sh/

 

# 安装

[[email protected] acme.sh]# ./acme.sh --install

[Sun Jan 27 19:23:03 HKT 2019] It is recommended to install socat first.

[Sun Jan 27 19:23:03 HKT 2019] We use socat for standalone server if you use standalone mode.

[Sun Jan 27 19:23:03 HKT 2019] If you don't use standalone mode, just ignore this warning.

[Sun Jan 27 19:23:03 HKT 2019] Installing to /root/.acme.sh

[Sun Jan 27 19:23:03 HKT 2019] Installed to /root/.acme.sh/acme.sh

[Sun Jan 27 19:23:03 HKT 2019] Installing alias to '/root/.bashrc'

[Sun Jan 27 19:23:03 HKT 2019] OK, Close and reopen your terminal to start using acme.sh

[Sun Jan 27 19:23:03 HKT 2019] Installing alias to '/root/.cshrc'

[Sun Jan 27 19:23:03 HKT 2019] Installing alias to '/root/.tcshrc'

[Sun Jan 27 19:23:03 HKT 2019] Installing cron job

no crontab for root

no crontab for root

[Sun Jan 27 19:23:03 HKT 2019] Good, bash is found, so change the shebang to use bash as preferred.

[Sun Jan 27 19:23:03 HKT 2019] OK

默认情况下,acme.sh以隐藏文件夹的形式安装在用户的home目录下,而我是用root用户,所以它在这里:

1

2

3

4

5

6

7

8

[[email protected] acme.sh]# ll /root/.acme.sh/

total 188

-rw-r--r-- 1 root root     96 Jan 27 19:23 account.conf

-rwxr-xr-x 1 root root 169557 Jan 27 19:23 acme.sh

-rw-r--r-- 1 root root     78 Jan 27 19:23 acme.sh.csh

-rw-r--r-- 1 root root     78 Jan 27 19:23 acme.sh.env

drwxr-xr-x 2 root root   4096 Jan 27 19:23 deploy

drwxr-xr-x 2 root root   4096 Jan 27 19:23 dnsapi

另外,它还会创建一个定时任务,通过以下命令即可查看:

1

2

[[email protected] acme.sh]# crontab -e

3 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null

定时任务会在每天0点3分调用acme.sh程序,以检查证实是否过期,是否需要续签等。这个定时任务的时间是随机的,但不影响主要功能。

完成安装后先来准备脚本,这个脚本只需要执行一次。执行后,这些信息会记录在相关目录中,后续的执行将自动执行:

1

2

3

4

5

6

# 首先执行以下两行

export Ali_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"

export Ali_Secret="jlsdflanljkljlfdsaklkjflsa"

 

# 而后申请签发证书

acme.sh --issue --dns dns_ali -d m4d3bug.com -d *.m4d3bug.com

将之前步骤中准备好的阿里云API key填写到上面命令的中,并在终端中执行,执行后并不会有内容返还:

使用acme.sh与阿里云DNS签发Let’s Encrypt的免费数字证书

然后准备签发证书的命令,因为是签发,所以要使用“–issue”参数;指明使用“dns_ali”作为验证方式;后面跟着的“-d”为指定证书中的域名,这里有一点需要注意的:如果证书中只包含泛域名,那么签发出来的证书是没有根域的。所以需要额外添加一个根域,如上面的命令所示。

其他厂商的DNS API信息请参考以下链接:

完成后即可到acme.sh的安装目录中执行:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

# 进入文件夹

[[email protected] ~]# cd /root/.acme.sh/

 

# 执行命令

[[email protected] .acme.sh]# ./acme.sh --issue --dns dns_ali -d m4d3bug.com -d *.m4d3bug.com

[Sun Jan 27 19:39:36 HKT 2019] Registering account

[Sun Jan 27 19:39:37 HKT 2019] Registered

[Sun Jan 27 19:39:37 HKT 2019] ACCOUNT_THUMBPRINT='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'

[Sun Jan 27 19:39:37 HKT 2019] Creating domain key

[Sun Jan 27 19:39:37 HKT 2019] The domain key is here: /root/.acme.sh/m4d3bug.com/m4d3bug.com.key

[Sun Jan 27 19:39:37 HKT 2019] Multi domain='DNS:m4d3bug.com,DNS:*.m4d3bug.com'

[Sun Jan 27 19:39:37 HKT 2019] Getting domain auth token for each domain

[Sun Jan 27 19:39:40 HKT 2019] Getting webroot for domain='m4d3bug.com'

[Sun Jan 27 19:39:40 HKT 2019] Getting webroot for domain='*.m4d3bug.com'

[Sun Jan 27 19:39:40 HKT 2019] Found domain api file: /root/.acme.sh/dnsapi/dns_ali.sh

[Sun Jan 27 19:39:42 HKT 2019] Found domain api file: /root/.acme.sh/dnsapi/dns_ali.sh

[Sun Jan 27 19:39:45 HKT 2019] Sleep 120 seconds for the txt records to take effect

在执行命令后,程序会调用阿里云的API,在DNS中添加以下内容:

使用acme.sh与阿里云DNS签发Let’s Encrypt的免费数字证书

然后程序会等待120秒,以便让DNS生效,而后再调用Let’s Encrypt的API进行验证与证书的签发工作:

使用acme.sh与阿里云DNS签发Let’s Encrypt的免费数字证书

如果一切正常,验证通过之后,会完成证书签发的工作,最后会将DNS中用于验证域名所有权的TXT解析记录删除:

使用acme.sh与阿里云DNS签发Let’s Encrypt的免费数字证书

0x04 使用

完成签发后,再看看acme.sh安装目录中,会发现以相关域名命名的文件夹:

1

2

3

4

5

6

7

8

9

10

11

[[email protected] .acme.sh]# ll /root/.acme.sh/

total 192

-rw-r--r-- 1 root root    251 Jan 27 19:42 account.conf

-rwxr-xr-x 1 root root 169557 Jan 27 19:23 acme.sh

-rw-r--r-- 1 root root     78 Jan 27 19:23 acme.sh.csh

-rw-r--r-- 1 root root     78 Jan 27 19:23 acme.sh.env

drwxr-xr-x 3 root root     42 Jan 27 19:39 ca

drwxr-xr-x 2 root root   4096 Jan 27 19:23 deploy

drwxr-xr-x 2 root root   4096 Jan 27 19:23 dnsapi

-rw-r--r-- 1 root root    395 Jan 27 19:42 http.header

drwxr-xr-x 2 root root    162 Jan 27 19:42 m4d3bug.com

域名文件夹中有以下文件:

1

2

3

4

5

6

7

8

9

[[email protected] .acme.sh]# ll /root/.acme.sh/m4d3bug.com/

total 28

-rw-r--r-- 1 root root 1648 Jan 27 19:42 ca.cer

-rw-r--r-- 1 root root 3567 Jan 27 19:42 fullchain.cer

-rw-r--r-- 1 root root 1919 Jan 27 19:42 m4d3bug.com.cer

-rw-r--r-- 1 root root  536 Jan 27 19:42 m4d3bug.com.conf

-rw-r--r-- 1 root root  989 Jan 27 19:39 m4d3bug.com.csr

-rw-r--r-- 1 root root  224 Jan 27 19:39 m4d3bug.com.csr.conf

-rw-r--r-- 1 root root 1675 Jan 27 19:39 m4d3bug.com.key

相关文件的用途如下:

  • ca.cer:Let’s Encrypt的中级证书
  • fullchain.cer:包含中级证书的域名证书
  • m4d3bug.com.cer:无中级证书的域名证书
  • m4d3bug.com.conf:该域名的配置文件
  • m4d3bug.com.csr:该域名的CSR证书请求文件
  • m4d3bug.com.csr.conf:该域名的CSR请求文件的配置文件
  • m4d3bug.com.key:该域名证书的私钥

因为我主要将证书用在nginx,所以需要用到包含中级证书的域名证书与私钥,而其他文件请不要修改,同时请保护好acme.sh安装目录中的所有文件,一旦泄露请及时更换API key、吊销证书并且注销Let’s Encrypt账号。

接下来通过nginx进行测试,以下是配置文件:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

server {

  listen                     443 ssl http2;

  server_name                m4d3bug.com;

 

  ssl_certificate            /usr/local/nginx/ssl/m4d3bug.com.crt;

  ssl_certificate_key        /usr/local/nginx/ssl/m4d3bug.com.key;

  ssl_buffer_size            16k;

  ssl_protocols              TLSv1.1 TLSv1.2 TLSv1.3;

  ssl_ecdh_curve             X25519:P-256:P-384:P-224:P-521;

  ssl_ciphers                TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256;

  ssl_prefer_server_ciphers  on;

  ssl_session_timeout        3h;

  ssl_stapling               on;

  ssl_session_tickets        on;

 

  access_log                 /var/log/nginx/access.log main;

 

  add_header                 Strict-Transport-Security "max-age=31536000; preload; includeSubDomains" always;

  add_header                 X-Frame-Options SAMEORIGIN;

 

  index                      index.php index.html;

 

  location / {

    root                     /usr/local/nginx/html;

  }

}

通过浏览器打开,即可检查证书的信息:

使用acme.sh与阿里云DNS签发Let’s Encrypt的免费数字证书

0x05 结语

Let’s Encrypt签发的证书有效期为90天,也就是说一年至少要更换4次。这是完全不可接受的,要是忘记不就完蛋了?

还好acme.sh支持自动部署,和调用脚本。这时候可以自行撰写脚本,将证书分发到各个节点,这个有时间再写文章了。

 

注意点:
1.注意nginx版本的差异,比如nginx.conf配置文件的差异,建议还是安装最新的稳定版(当前是 nginx 1.16.0 版本);
2.记得开启端口,http是80端口,ssl是443端口;
3.记得启停nginx服务,例如 停: nginx -s quit; 启:./nginx
4.如果原来没有ssl模块,记得安装ssl模块,参考https://www.cnblogs.com/ghjbk/p/6744131.html