前言
众所周知 HTTPS 是保证 HTTP 通讯安全的协议,网站启用 HTTPS 可以避免很多安全性的问题, 而且 Chrome 浏览器 从 68 版本开始直接将 HTTP 网站标记为不安全了。
所以把网站升级成 HTTPS 自然是大势所趋,不过启用 HTTPS 有个最重要的问题是 HTTPS 证书要花钱!如果每年额外花钱去购买 HTTPS 证书,那也是一笔很大的开销。那么有没有免费的HTTPS证书可以用呢,查了下资料有个叫Let’s Encrypt的项目就提供了免费签发 HTTPS 证书的服务,这里记录下如何使用Let’s Encrypt来签发证书。
certbot 介绍
certbot是用于从 Let’s Encrypt 获取证书的命令行工具,代码开源在github上。
使用certbot命令行工具可以轻松的实现HTTPS证书签发,在签发证书之前,需要证明签发的域名是属于你控制的,目前certbot有两种验证方式:
HTTP
HTTP 方式就是certbot会生成一个特定的文件名和文件内容,要求放在你对应域名下对应路径(/.well-known/acme-challenge/)下,然后certbot再通过 HTTP 请求访问到此文件,并且文件内容与生成时候的一致。例如:
certbot生成文件名check和内容!@#$%^,你需要申请的域名为baidu.com,则certbot访问http://baidu.com/.well-known/acme-challenge/check来校验是否与生成的内容一致。DNS
DNS 则是certbot生成一段特定的文本,要求在你对应域名中配置一条对应子域名(_acme-challenge)的TXT类型解析记录。例如:
certbot生成内容!@#$%^,你需要申请的域名为baidu.com,则需要添加一条_acme-challenge.baidu.com的TXT类型解析记录,值为之前生成的内容。
在域名验证通过之后,certbot就可以签发HTTPS证书了,注意在此验证步骤基础上,certbot提供了很多开箱即用的自动验证方案,但是都不符合我的需求,原因是我需要支持通配符域名的证书,但是这种证书只支持DNS验证方式,而官方提供的DNS插件中并没有支持我用的阿里云DNS,所以只能自己去实现 阿里云的 DNS 自动校验。
使用 certbot 签发 HTTPS 证书
通过官网教程可以选择对应操作系统,并获取安装步骤:

这里我选择的Debian 9,根据官网的提示进行安装:
1 | sudo apt-get install certbot -t stretch-backports |
注:如果install失败可以先执行下 apt-get update
开始签发证书
1 | certbot certonly --cert-name pdown.org -d *.pdown.org,*.proxyee-down.com --manual --register-unsafely-without-email --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory |
这里签发了一个支持*.pdown.org和*.proxyee-down.com通配符域名的证书,注意如果是通配符域名证书需要指定--server https://acme-v02.api.letsencrypt.org/directory
示例:
1 | Saving debug log to /var/log/letsencrypt/letsencrypt.log |
这里会生成一串随机字符并阻塞住,需要去设置一条对应的 TXT 类型的 DNS 解析记录再继续,在设置好之后可以用nslookup进行本地验证:
1 | nslookup -type=txt _acme-challenge.pdown.org |
本地验证通过之后按回车键继续,接着 Let’s Encrypt 就会校验这个 DNS 解析记录是否正确,校验通过后就会进行下一个域名的验证直到全部验证通过。
1 | Waiting for verification... |
当验证通过的时候会输出证书生成的目录,里面会包含证书和对应的私钥,这里目录是/etc/letsencrypt/live/pdown.org/。
证书截图:

这样证书就生成好了,之后只需要把证书和私钥配置到nginx中就可以用https访问了。
使用 certbot hook 自动续签
上面证书虽然是生成好了,但是证书的有效期只有三个月,意味着每过三个月就得重新签发一个新的证书,一不注意证书就过期了,而且每次手动签发都非常的繁琐需要去手动设置 DNS 解析,所以certbot提供了一种自动续签的方案:hook
在创建证书的时候certbot提供了两个hook参数:
- manual-auth-hook
指定用于验证域名的脚本文件 - manual-cleanup-hook
指定用于清理的脚本文件,即验证完成之后
通过自定义这两个脚本就可以做到自动续签了,文档参考pre-and-post-validation-hooks。
在此基础上,官方已经提供了很多云厂商的自动续签方案,但是我用的阿里云官方并没有提供,于是参照官网文档,写了一个基于阿里云的自动续签脚本,在验证域名的脚本中通过阿里提供的 DNS API 添加一条域名解析记录,在验证完成之后再把刚刚那条域名解析记录删除,命令行调用如下:
1 | certbot certonly --cert-name pdown.org -d *.pdown.org,*.proxyee-down.com --manual --register-unsafely-without-email --manual-auth-hook /path/to/dns/authenticator.sh --manual-cleanup-hook /path/to/dns/cleanup.sh --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory |
为了方便使用,提供了一个docker镜像,通过环境变量将阿里云 API 调用的 AK 传递就可以生成和续签证书了。
- 启动容器
1 | docker run \ |
- 首次创建证书
1 | docker exec -it cert ./create.sh *.pdown.org |
创建过程中会等待一段时间,来确保 dns 记录生效,完成之后在/etc/letsencrypt/live目录下可以找到对应的证书文件
- 续签证书
1 | docker exec cert ./renew.sh |
代码开源在github,欢迎 start。


