https证书自动续订(renew)问题

https证书自动续订(renew)问题

之前写过一篇文章:为你的网站配置免费的HTTPS支持,看本文之前,建议先看一下这篇文章。

前面文章讲的方法主要是无法自动续订通配符证书,其原因是通配符证书需要向域名服务商添加一个txt记录,其实用前面文章中的certbot renew也是可以的,只是要指定更新域名服务商txt记录的shell脚本,该脚本需要调用域名服务商提供的接口,如果你熟悉shell,完全可以自己写,如果你不想麻烦,已经有人帮写好了一个工具:acme.sh

配置步骤

再简单说一下配置步骤:

  • 1.获取https证书(即ssl证书,前面说了,http是用ssl或tls来加密数据包的,所以我们要选获取ssl证书)
  • 2.在http服务器(如nginx、apache等)中配置使用ssl证书
  • 3.过期前自动更新证书(证书是有时效的,比如letsencrypt的证书有效期是90天)

http证书的类型

https证书有指定域名的证书和通配符证书,指定域名如:xiebruce.comwww.xiebruce.com就是指定域名,而*.xiebruce.com即为通配符证书。通配符证书的好处,就在于,如果你后面又增加了几个网站子域名,比如aaa.xiebruce.combbb.xiebruce.com,你就可以直接用通配符证书,否则你每增加一个子域名,就要申请一次证书,特别麻烦。

既然通配符证书简单,是不是只申请通配符证书就行了呢?是的,但要注意通配符证书是不包括自解析的,比如本博客的域名为xiebruce.topwww.xiebruce.top,有www的,可以用*.xiebruce.top通配符证书,但没有www的是无法使用通配符证书的,因为即使*是空,那也只能匹配.xiebruce.top,最前面多了一个点,所以无法匹配。

所以我们需要给通配符证书同时设置两个域名(一个证书是可以设置多个域名的),一个当然就是通配域名*.xiebruce.top,另一个就是不包括在通配域名中的xiebruce.top

获取https证书的方法

获取数字证书一般都是用ACME(Automatic Certificate Management Environment )自动证书管理环境工具来获取,这样的工具有多种,比如:

  • certbot
  • certbot-auto
  • acme.sh
  • certbot-letencrypt-wildcardcertificates-alydns-au

鉴于大部分情况下都需要使用通配符证书,所以前面两个并不合适(无法自动更新通配符证书),如果是阿里云买的域名或国外买的域名,可以用第三个acme.sh,最后一个可用于阿里、腾讯云、GoDaddy的域名,因为我的是阿里云买的域名,我这里使用第三个,即acme.sh(后面两个工具都是国人写的)。

安装ssl证书获取工具(acme.sh)

acme.sh的github:https://github.com/Neilpang/acme.sh

安装acme.sh(使用root权限):

curl https://get.acme.sh | sh

安装.acme.sh会自动安装到~/.acme.sh目录中(注意它是一个目录,不是单个文件),也就是说,如果你是用root用户安装,那么会安装到/root/.acme.sh目录中,如果是用普通用户,比如你的用户名是zhangsan,那么它将会被安装到/home/zhangsan/.acme.sh目录中。

安装中出现的这三句红色的提示不用管它:

[2019年 02月 15日 星期五 01:04:08 CST] It is recommended to install socat first.
[2019年 02月 15日 星期五 01:04:08 CST] We use socat for standalone server if you use standalone mode.
[2019年 02月 15日 星期五 01:04:08 CST] If you don't use standalone mode, just ignore this warning.

安装完它会自动在.bashrc.zshrc的最后添加以下命令(这是添加环境变量,这样你就可以直接使用acme.sh命令了):

. "/home/xiebruce/.acme.sh/acme.sh.env"

你只要source一下就可以使用了,如果你用的是bash:

source ~/.bashrc

如果你使用的是zsh:

source ~/.zshrc

source之后,试一下(如果正常,则会出来帮助选项):

acme.sh -h

获取通配符证书

阿里云中获取证书:

先从阿里云中获取“AccessKey ID”和“Access Key Secret”:https://ak-console.aliyun.com/#/accesskey

在你的~/.bashrc.zshrc文件中添加阿里云的“AccessKey ID”和“Access Key Secret”(添加后source一下,跟前面一样,不再赘述):

export Ali_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
export Ali_Secret="jlsdflanljkljlfdsaklkjflsa"

然后获取*.xiebruce.top的通配符证书,注意要加上xiebruce.top,而且要它放第一个(否则生成的证书目录名会被命名成有*号的那个,目录名有*号不太好),因为它是无法匹配通配符证书的:

acme.sh --issue --dns dns_ali -d xiebruce.top -d '*.xiebruce.top'

另外,它会等待120秒,原因是要等阿里云的txt记录解析生效,其实不需要这么久,不过为了保证成功率,还是等久一点好。

从CloudFlare获取证书:
点击CloudFlare的右上角头像→点击下拉菜单中的My Profile,滚到差不多到底部,你就可以看到一个“Global API Key”和一个“Origin CA Key”,“Global API Key”就是我们要的Key:
Xnip2019-06-06_11-20-19.jpg

在你的~/.bashrc.zshrc文件中添加CloudFlare的这两个变量:

export [email protected]
export CF_Key=85302dsiorw3oisjdkf899234sdf72dfdb46

然后命令是一样的,只不过--dns指定的api为dns_cf(查看~/.acme.sh/dnsapi/目录,里面有所有支持的api):

acme.sh --issue --dns dns_cf -d xiebruce.top -d '*.xiebruce.top'

至于为什么阿里云要的是Ali_KeyAli_Secret,而CloudFlare要的是CF_EmailCF_Key?查看~/.acme.sh/dnsapi/下的api文件,打开对应的文件,比如阿里的就是dns_ali.sh,CloudFlare的就是dns_cf.sh,打开文件自然能看到里面需要什么变量。

安装证书

上边的获取证书,是放到了~/.acme.sh目录中的(实际上是在该目录中生成了一个xiebruce.top文件夹,文件夹里就是获取到的证书):
Xnip2019-02-15_00-02-12.jpg

理论上我们在nginx中引用它即可,实际上也可以,但最好不要直接引用它,而是先把它拷贝到另一个目录中比如nginx要用就拷贝到nginx目录中,或者你喜欢放在/etc下或/usr/local/etc下也行,我是放到了nginx的目录中,但不需要自己手动拷贝,直接用以下命令:

acme.sh --install-cert -d 'xiebruce.top' \
--key-file       /usr/local/openresty/nginx/letsencrypt/private.pem  \
--fullchain-file /usr/local/openresty/nginx/letsencrypt/fullchain.pem \
--reloadcmd     "nginx -s reload"

解析:
--install-cert:表示安装证书,其实就是把证书文件拷贝到指定目录。
-d:指定拷贝哪个域名的证书,不过由于我们获取的时候,写了两个域名,一个是xiebruce.top,一个是通配*.xiebruce.top,写哪个好呢?就写xiebruce.top,因为生成的文件夹名字是xiebruce.top
--key-file:指定证书私钥(本例是xiebruce.top.key文件)的目标路径(即指定要拷到哪里,从哪里拷不用指定,因为肯定是在acme.sh的工作目录中,该工具会自动去找的)。
--fullchain-file:fullchain是所有证书文件,该选项指定拷贝fullchain.cer文件到哪里。
--reloadcmd:重载的命令,因为证书改变后,nginx如果不重新加载配置,新证书是不会生效的。
注意:要保证--key-file--fullchain-file指向的目录存在,如果不存在,则要先创建,否则拷贝失败,比如我是用的openresty所以我放在以下目录,你自己的可以看情况,你自己喜欢放哪就放哪:

mkdir /usr/local/openresty/nginx/letsencrypt

自动续订(renew)

把以下命令加入到定时任务中即可实现证书过期时自动续订证书(事实上安装的时候已已经自动帮你加了,所以你不用手动加了):

0 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" >> /var/log/acme.sh-auto-renew.log

解析:
0 0 * * *:表示每天的0点执行一次。
/root/.acme.sh/acme.sh --cron:其实就是acme.sh --cron,只不过在定时任务中要把acme.sh的绝对路径写出来,该命令会把你所有的证书都renew一遍,并且会自动install并reload nginx,也就是说,renew获取到新证书后,它会自动执行前面的安装命令最后会执行reloadcmd指定的重载nginx的命令。有人可能会有疑问,这样是不是nginx每天都会重载一次?不会的,你单独执行一下acme.sh --cron命令看看结果:

[2019年 02月 15日 星期五 00:40:43 CST] ===Starting cron===
[2019年 02月 15日 星期五 00:40:43 CST] Renew: 'xiebruce.top'
[2019年 02月 15日 星期五 00:40:43 CST] Skip, Next renewal time is: 2019年 04月 15日 星期一 15:45:22 UTC
[2019年 02月 15日 星期五 00:40:43 CST] Add '--force' to force to renew.
[2019年 02月 15日 星期五 00:40:43 CST] Skipped xiebruce.top
[2019年 02月 15日 星期五 00:40:43 CST] ===End cron===

看到其中的“Skip, Next renewal time is”了吗?没有到续订日期,它会跳过,而且还给出下次续订的日期,所以只有到了续订日期,才会真正续订并reload nginx,否则相当于没有执行。

--home "/root/.acme.sh":这个是指定acme.sh的工具目录,其实不指定应该也是可以的。
>> /var/log/acme.sh-auto-renew.log把前面命令执行输出的结果存到指定的日期文件中。

多台机同一个网站问题

一般情况下都会在负载均衡那台机做一个就够了,不需要每台机都做,如果要多台机做,那就用一台机来更新,然后同步到其他机器。

使用证书

本文主要讲如何使用acme.sh安装证书以及自动续订证书,至于获取到证书以后如何使用,请参考:为你的网站配置免费的HTTPS支持,主要就是在nginx中引用两个证书文件。

打赏

Leave a Reply

avatar

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  Subscribe  
Notify of

扫码在手机查看
iPhone请用自带相机扫
安卓用UC/QQ浏览器扫

https证书自动续订(renew)问题