有时候不得不说,大家都是一个草台班子,想破了都没理解,这么大的企业可以证书能过期没处理,过期就算了,关键这服务器过期会导致鼠标配置用不了也是醉了,而且能持续这么长时间:

当然,对于个人来说其实也是,相信很多人用的都是免费证书,在此之前大家应该都是 3 个月换一次,而前段时间,Let's Encrypt 也宣布了将全面缩短 TLS/SSL 证书的有效期, 从现有的 90 天调整为45 天 ,这对于个人 Free 用户来说,无疑是灾难的:

那我是怎么解决的?其实从 Let's Encrypt 将免费 SSL 证书有效期缩短到三个月之后,我就很烦 SSL 这个问题,所以我当时找了个脚本解决这个,整体其实还挺简单的:Let's Encrypt + acme.sh ,可以 20 分钟搞定两个不同场景的域名 SSL 自动更新,不得不赞叹劳动人民为了 Free 的智慧。
首先我有两个 ssl 证书:
- 一个是主域名的,域名的 ssl 证书和 dns 都在腾讯云,服务器也是腾讯云的,证书之前是手动部署在我服务器内的 nginx 配置下
- 一个是子域名的,img 子域名和其对应的 ssl ,是给七牛云配置的 https 域名支持
基于这个场景,我用 Let's Encrypt + acme.sh 做自动续签 ,因为对比 Certbot ,acme.sh 在完全手动控制 nginx 配置上更方便,而且轻量又不依赖 openssl,高可控且不需要修改我目前的 Nginx 配置。
也 Free 。
主域名
对于主域名,因为我现在的证书路径在我服务器的:
vbnet
/etc/nginx/default.d/1_XXXX.cn_bundle.crt
/etc/nginx/default.d/2_XXXX.cn.key
所以我需要确保:
- 每次续期后自动覆盖这两个文件
- 自动 reload nginx
- 不会破坏现有 nginx 配置
- Let's Encrypt 的 challenge 能正常走 HTTP( 80 端口是可访问的)
所以具体流程为:
1、安装 acme.sh
bash
# 安装 acme.sh
curl https://get.acme.sh | sh
# 重启 shell
source ~/.bashrc
2、适配配置
因为我现在的 80 端口配置是:
perl
location /{
rewrite ^(.*) https://$host$1 permanent;
}
对于 acme.sh 来说,会检测到 challenge 无法验证,所以我需要在 80 的 server 块【最前面】加一段例外配置,必须放在所有 rewrite 之前 ,把 acme 的验证排除在跳转之外,这里的 /usr/share/nginx/html 就是 nginx 默认的 server root :
bash
location ^~ /.well-known/acme-challenge/ {
root /usr/share/nginx/html;
allow all;
}
3、开始签发
因为我是有 XXXX.cn 和 www.XXXX.cn 两个需要解析的,所以命令是如下所示,这里的 /usr/share/nginx/html 就是前面的 server root :
css
acme.sh --issue -d XXXX.cn -d www.XXXX.cn -w /usr/share/nginx/html
在这里我遇到了两个问题:
acme.sh is using ZeroSSL as default CA now.,acme.sh 默认改用 ZeroSSL 导致必须注册账号并绑定邮箱的提示,你可以通过acme.sh --register-account -m 你的邮箱@example.com来解决,但是我不想弄,所以我用acme.sh --set-default-ca --server letsencrypt切回 Let's Encrypt
-
curl: (60) SSL certificate problem: unable to get local issuer certificate,acme.sh 访问 Let's Encrypt 的 API 时,系统信任链不完整,CA 根证书过期或缺失,这在老版本 CentOS(特别是 CentOS 7)上非常常见,因为系统自带的 CA bundle 太旧了,无法验证 Let's Encrypt 的新根证书 ISRG Root X1,解决方式就是更新 ca-certificates :sqlyum update ca-certificates -y update-ca-trust
申请颁发成功后, acme.sh 会告诉你证书路径一般在:
javascript
~/.acme.sh/XXXX.cn/

4、安装证书
最后,只需要通过以下命令,就可以直接成功将颁发的证书自动部署并安装到指定位置,同时开启了定时任务,acme.sh 会自动创建 cron,每 60 天自动续期,也会自动 reload Nginx,之后不需要做任何其他事情。
scss
acme.sh --install-cert -d XXXX.cn \
--key-file /etc/nginx/default.d/2_XXXX.cn.key \
--fullchain-file /etc/nginx/default.d/1_XXXX.cn_bundle.crt \
--reloadcmd "nginx -s reload"

第三方平台
因为图床的 SSL 证书是在七牛云的,所以还需要处理七牛云的证书问题,这也可以通过 acme.sh → 自动续签 → 自动上传到七牛云 来实现全自动化证书管理。
acme.sh 已经内置了 Qiniu API 自动部署证书(deploy hook),基本知名的第三方平台都有。
因为我是在腾讯云的域名,使用的是腾讯云 DNS(DNSPod),所以我需要结合腾讯云的流程来完成。
1、获取 DNSPod API Token
登录 console.dnspod.cn/account/tok...,创建一个 Token:
- Token 名称:任意
- 权限:只需要 DNS 读取/写入
这样我们得到:
DP_Id(ID)DP_Key(Token)
2、获取七牛云 AK/SK(用于自动上传证书)
通过 portal.qiniu.com/user/key,获得:
QINIU_AKQINIU_SK
3、使用 dns_dp 自动为 img.cdn.XXX.cn 签发证书
通过下面命令,就可以自动签发对应证书了
ini
export DP_Id="你的DP_Id"
export DP_Key="你的DP_Key"
acme.sh --issue \
-d img.cdn.XXX.cn \
--dns dns_dp
4、执行部署
执行以下命令,执行成功后,七牛 CDN 的 img.cdn.XXX.cn 的 HTTPS 配置会自动替换成 acme.sh 的新证书
ini
export QINIU_AK="你的七牛AK"
export QINIU_SK="你的七牛SK"
acme.sh --deploy \
-d img.cdn.XXX.cn \
--deploy-hook qiniu
之后 acme.sh 会每 60 天自动续签 Let's Encrypt 证书,自动运行 qiniu deploy hook,自动上传证书到七牛 CDN,再也不需要再手动登录七牛云上传证书。
实际上如果是阿里云也类似:
ini
export Ali_Key="你的阿里云AccessKeyId"
export Ali_Secret="你的阿里云AccessKeySecret"
acme.sh --issue \
-d img.cdn.XXX.cn \
--dns dns_ali
基本各大平台都支持。
最后
可以看到,实际操作起来还是挺简单的,而且是在你自己的服务器,安全问题也比使用第三方平台或者面板更可控,之后,你也可以通过以下命令查看 acme.sh 管理的证书状态。
css
acme.sh --list

如果你想强制立即续签,也可以通过以下命令完成:
css
cme.sh --renew -d img.cdn.XXX.cn --force
另外 acme.sh 的自动续签完全不依赖 systemd 服务 ,它是通过 cron 定时任务 来实现的,也就是就算服务器重启,只要 cron 服务是系统自带并默认启动的,续签任务也会继续按计划运行,不需要手动恢复。
正常来说,cron 作为 Linux 默认核心服务,重启后一般都是会自动恢复。
如果还有什么差异性需求,通过 AI 也可以看快速解决,可以说 Let's Encrypt + acme.sh 花费了我 20 分钟的时间,就解决了我蛋疼了一年的问题,对于懒人来收还是十分不错的选择。
对于企业来说,可能有财务和安全考虑问题,对于个人,基本瞒住。
另外有个冷知识,其实安卓的 APK 证书也是也有有效期的,只是一般来说,可能企业倒闭了证书还没到。