背景
我的服务器、域名和 SSL 证书都是在腾讯云上购买/申请的,由于腾讯云的通配符 SSL 证书和自动续期能力都要付费且较为昂贵,所以我一直都是使用的免费 SSL 证书。免费证书的缺点是只有 90 天期限,到期后需要手动续期。
随着我的网站越来越多,域名也越来越多,每次要手动给每个域名的 SSL 证书手动续期,十分麻烦。
最近发现了一个好的开源项目 —— acme.sh,它是一个使用 shell 实现的协议,通过简单的脚本就可以支持域名证书自动续期,而且支持免费的通配符证书。
教程
其实 acme.sh github 的教程十分明了,唯一的是对于证书安装后 nginx 或者 Apache 的配置缺少一点说明,小白可能需要花一点时间理解,所以我就在这再详细写一遍。
1. 安装 acme.sh
安装支持 curl、wget 或者 github 等多种安装方式,任选一种即可(下面的 my@example.com 只是安装时需要填写一个邮箱参数,不需要进行什么校验,随便填一个即可):
-
curl 安装
curl https://get.acme.sh | sh -s email=my@example.com -
wget 安装
wget -O - https://get.acme.sh | sh -s email=my@example.com -
github 安装
git clone https://github.com/acmesh-official/acme.sh.git cd ./acme.sh ./acme.sh --install -m my@example.com -
如果你的服务器因为国内网络导致上述安装方式失败,那也可以通过 gitee 来安装:
git 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 秘钥管理申请秘钥:
然后将其设置为服务器的环境变量:
export Tencent_SecretId="<Your SecretId>"
export Tencent_SecretKey="<Your SecretKey>"
现在就可以通过 DNS API 的方式申请证书了,推荐使用通配符的方式,以我的域名 *.zlxiang.com 为例:
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:
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:
<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 对应命令:
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 对应命令:
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 天自动续期一次,解决了手动续期的麻烦。