背景
我的服务器、域名和 SSL 证书都是在腾讯云上购买/申请的,由于腾讯云的通配符 SSL 证书和自动续期能力都要付费且较为昂贵,所以我一直都是使用的免费 SSL 证书。免费证书的缺点是只有 90 天期限,到期后需要手动续期。 随着我的网站越来越多,域名也越来越多,每次要手动给每个域名的 SSL 证书手动续期,十分麻烦。
最近发现了一个好的开源项目 ------ acme.sh,它是一个使用 shell 实现的协议,通过简单的脚本就可以支持域名证书自动续期,而且支持免费的通配符证书。
教程
其实 acme.sh github 的教程十分明了,唯一的是对于证书安装后 nginx 或者 Apache 的配置缺少一点说明,小白可能需要花一点时间理解,所以我就在这再详细写一遍。
1. 安装 acme.sh
安装支持 curl、wget 或者 github 等多种安装方式,任选一种即可(下面的 my@example.com
只是安装时需要填写一个邮箱参数,不需要进行什么校验,随便填一个即可):
-
curl 安装
shcurl https://get.acme.sh | sh -s email=my@example.com
-
wget 安装
shwget -O - https://get.acme.sh | sh -s email=my@example.com
-
github 安装
shgit clone https://github.com/acmesh-official/acme.sh.git cd ./acme.sh ./acme.sh --install -m my@example.com
-
如果你的服务器因为国内网络导致上述安装方式失败,那也可以通过 gitee 来安装:
shgit clone https://gitee.com/neilpang/acme.sh.git cd acme.sh ./acme.sh --install -m my@example.com
2. 申请证书
证书支持通过 HTTPS、DNS 等多种方式申请,我使用的是 DNS API 自动集成的方式,需要找到你服务器对应的厂商:How to use DNS API,以我的厂商腾讯云为例,步骤非常的清晰:

首先去腾讯云的 API 秘钥管理申请秘钥: 然后将其设置为服务器的环境变量:
shell
export Tencent_SecretId="<Your SecretId>"
export Tencent_SecretKey="<Your SecretKey>"
现在就可以通过 DNS API 的方式申请证书了,推荐使用通配符的方式,以我的域名 *.zlxiang.com
为例:
shell
acme.sh --issue --dns dns_tencent -d *.zlxiang.com
等待一会儿,证书就申请完成了:

3. 配置 nginx 或者 apache
以我刚刚申请的通配符域名 *.zlxiang.com
的一个子域名 poker.zlxiang.com
为例。首先你需要建几个 .pem
文件,用于存储 SSL 配置的内容,我创建了 /www/ssl/all.zlxiang.com
目录并在里面添加了 fullchain.pem
、key.pem
、cert.pem
3个文件,最后一个文件是 apache 需要的,nginx 可以不建。然后将 SSL 配置指向这几个文件。
如果使用的是 nginx:
conf
server
{
listen 80;
listen 443 ssl http2;
server_name poker.zlxiang.com;
index index.php index.html index.htm default.php default.htm default.html;
root /www/wwwroot/poker;
# 重点关注:SSL 配置指向的路径,这里根据你的需要填就可以,待会会将 SSL 证书安装过来
ssl_certificate /www/ssl/all.zlxiang.com/fullchain.pem;
ssl_certificate_key /www/ssl/all.zlxiang.com/key.pem;
# others...
}
如果使用的是 apache:
xml
<VirtualHost *:80>
ServerName poker.zlxiang.com
Redirect permanent / https://poker.zlxiang.com/
</VirtualHost>
<VirtualHost *:443>
ServerName poker.zlxiang.com
DocumentRoot "/www/wwwroot/poker"
<IfModule dir_module>
DirectoryIndex index.php index.html index.htm default.php default.htm default.html
</IfModule>
# 重点关注:SSL 配置指向的路径,这里根据你的需要填就可以,待会会将 SSL 证书安装过来
SSLCertificateFile /www/ssl/all.zlxiang.com/cert.pem;
SSLCertificateKeyFile /www/ssl/all.zlxiang.com/key.pem;
SSLCertificateChainFile /www/ssl/all.zlxiang.com/fullchain.pem;
</VirtualHost>
4. 写入证书到 nginx/apache 配置
根据你安装的 acme.sh 的版本不同,可能会自动启用 ecc
,可以根据申请证书时最终证书下载的路径,检查是否是 ecc
:

如果带有 ecc
,则下面的命令中需要加上 --ecc
,否则则不需要。
然后执行下列命令,这会将申请的 SSL 证书内容写入到 nginx SSL 配置指向的 .pem
文件中,并在证书更新时自动重写。
nginx 对应命令:
sh
acme.sh --install-cert --ecc -d *.zlxiang.com \
--key-file /www/ssl/all.zlxiang.com/key.pem \
--fullchain-file /www/ssl/all.zlxiang.com/fullchain.pem \
--reloadcmd "service nginx reload"
apache 对应命令:
sh
acme.sh --install-cert -d example.com \
--cert-file /www/ssl/all.zlxiang.com/cert.pem \
--key-file /www/ssl/all.zlxiang.com/key.pem \
--fullchain-file /www/ssl/all.zlxiang.com/fullchain.pem \
--reloadcmd "service apache2 force-reload"
检查成果
通过 https
访问你刚刚配置的域名检查是否成功,可以点击域名旁边的 icon > 【Connection is secure】 > 【Certificate is valid】 检查域名到期时间 可以看到我的域名到期时间是 3 个月之后了,证明申请成功了。
acme.sh 每天会定时检查证书的到期时间,并在到期前一个月自动续期,也就是说正常 60 天自动续期一次,解决了手动续期的麻烦。