博客网站一直以来都是使用的腾讯云免费的一年SSL证书,但是目前由于规则更改,证书最长时间为一年,因此将本站证书替换为acme.sh自动托管,每隔三个月自动更换ZeroSSL提供的SSL证书。
安装 acme.sh
curl https://get.acme.sh | sh -s email=2****6@qq.com
acme.sh会自动安装到你的home目录下(本站默认安装到~/.acme.sh),需要重新连接SSH使alias生效,或者直接执行以下命令
source ~/.bashrc
此外会自动为你创建 cronjob, 每天 0:00 点自动检测所有的证书
申请证书
acme.sh 实现了 acme 协议支持的所有验证协议。一般有两种方式验证: HTTP 和 DNS 验证。
通过HTTP验证文件申请证书
该方式需要能够通过域名+80端口的方式访问到服务器,由于本站默认占用80、443端口,此种方式跳过。
直接签发
只需要指定域名,并指定域名所在的网站根目录. acme.sh 会全自动的生成验证文件,并放到网站的根目录,验证完成后会聪明的删除验证文件,整个过程没有任何副作用(本站建站:Docker安装Halo、Nginx、Wiz,基于docker部署此种方式跳过)。
acme.sh --issue -d mydomain.com -d www.mydomain.com --webroot /home/wwwroot/mydomain.com/
使用 Nginx 模式
如果你用的 Nginx 服务器,或者反代,acme.sh 还可以智能的从 Nginx 的配置中自动完成验证,你不需要指定网站根目录:
acme.sh --issue --nginx -d example.com -d www.example.com -d cp.example.com
通过校验DNS解析记录申请证书
本站使用腾讯云专业版DNS进行解析,因此使用DNS解析进行证书申请,该方式不需要任何服务器,不需要任何公网IP,只需要添加一个TXT类型的DNS解析记录即可完成验证。
自动修改DNS记录(推荐)
该方法需要调用DNS服务商API接口,且需要开通对应的API权限
阿里云DNS API获取方法
export Ali_Key="Ali_Key"
export Ali_Secret="Ali_Secret"
acme.sh --issue --dns dns_ali -d *.example.com -d example2.com
Cloudflare DNS API获取方法
export CF_Key="你的Global API Key"
export CF_Email="注册Cloudflare邮箱"
acme.sh --issue --dns dns_cf -d *.example.com -d example2.com
DnsPod(腾讯云DNS API) 获取方法
export DP_Id="DnsPod ID"
export DP_Key="DnsPod Token"
acme.sh --issue --dns dns_dp -d *.example.com -d example2.com
直接export DNS API方法并不推荐,服务器重启失效,建议实例化存储
vim ~/.acme.sh/account.conf
#日志默认关闭
#LOG_FILE="/root/.acme.sh/acme.sh.log"
#LOG_LEVEL=1
# acme.sh自动升级,建议打开
AUTO_UPGRADE='1'
ACCOUNT_EMAIL='2****6@qq.com'
UPGRADE_HASH='5****b'
# DNSPOD API密钥信息
SAVED_DP_Id='5****1'
SAVED_DP_Key='b****1'
USER_PATH='/sbin:/bin:/usr/sbin:/usr/bin'
#企业微信机器人通知
SAVED_WEIXIN_WORK_WEBHOOK='https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=f****f'
SAVED_WEIXIN_WORK_KEYWORD='acme'
NOTIFY_HOOK='weixin_work'
这里指定的所有参数都会被自动记录下来, 并在将来证书自动更新以后, 被再次自动调用.
本站存在多个子域名,且目前acme.sh默认支持泛域名解析,因此本站生成泛域名证书进行覆盖使用。
./acme.sh --issue --dns dns_dp -d findmyfun.xyz -d *.findmyfun.xyz
# 证书目录
[Mon Dec 2 11:20:56 CST 2024] Your cert is in: /root/.acme.sh/findmyfun.xyz_ecc/findmyfun.xyz.cer
[Mon Dec 2 11:20:56 CST 2024] Your cert key is in: /root/.acme.sh/findmyfun.xyz_ecc/findmyfun.xyz.key
[Mon Dec 2 11:20:56 CST 2024] The intermediate CA cert is in: /root/.acme.sh/findmyfun.xyz_ecc/ca.cer
[Mon Dec 2 11:20:56 CST 2024] And the full-chain cert is in: /root/.acme.sh/findmyfun.xyz_ecc/fullchain.cer
手动修改DNS记录
使用这种方法 acme.sh 将无法自动更新证书,每次都需要手动再次重新解析验证域名所有权。
acme.sh --issue --dns -d *.example.com -d example2.com
安装证书
证书生成好以后,我们需要把证书复制给对应的 Apache、Nginx 或其他服务器去使用。
必须使用 --install-cert 命令来把证书复制到目标文件,请勿直接使用 ~/.acme.sh/ 目录下的证书文件,这里面的文件都是内部使用,而且目录结构将来可能会变化。
默认采用Nginx二进制部署程序
acme.sh --install-cert -d example.com \
--key-file /path/to/keyfile/in/nginx/key.pem \
--fullchain-file /path/to/fullchain/nginx/cert.pem \
--reloadcmd "service nginx reload"
Nginx 的配置项 ssl_certificate 需要使用 /etc/nginx/ssl/fullchain.cer ,而非 /etc/nginx/ssl/
本站由于采用docker部署nginx,因此本站证书reloadcmd需要进行修改,证书默认安装位置/root/nginx/certs
acme.sh --install-cert -d findmyfun.xyz \
--key-file /root/nginx/certs/findmyfun.xyz.pem \
--fullchain-file /root/nginx/certs/fullchain.pem \
--reloadcmd 'docker exec -it nginx bash -c "service nginx reload"'
若上面方案不生效,建议使用
acme.sh --install-cert -d findmyfun.xyz \
--key-file /root/nginx/certs/findmyfun.xyz.pem \
--fullchain-file /root/nginx/certs/fullchain.pem \
--reloadcmd "docker restart nginx"
注意:reloadcmd 非常重要。证书会自动申请续签,但是如果没有正确的 reloadcmd 命令,证书可能无法被重新应用到 Apache 或者 Nginx,因为配置没有被重载。
查看已安装证书信息
acme.sh --info -d findmyfun.xyz
会输出如下内容:
DOMAIN_CONF=/root/.acme.sh/findmyfun.xyz_ecc/findmyfun.xyz.conf
Le_Domain=findmyfun.xyz
Le_Alt=*.findmyfun.xyz
Le_Webroot=dns_dp
Le_PreHook=
Le_PostHook=
Le_RenewHook=
Le_API=https://acme.zerossl.com/v2/DV90
Le_Keylength=ec-256
Le_OrderFinalize=https://acme.zerossl.com/v2/DV90/order/hnYzen2I-Z8wWzoU5ca1fg/finalize
Le_LinkOrder=https://acme.zerossl.com/v2/DV90/order/hnYzen2I-Z8wWzoU5ca1fg
Le_LinkCert=https://acme.zerossl.com/v2/DV90/cert/KikcmfadAp1--QMGjx0GXA
Le_CertCreateTime=1733122065
Le_CertCreateTimeStr=2024-12-02T06:47:45Z
Le_NextRenewTimeStr=2025-01-30T06:47:45Z
Le_NextRenewTime=1738219665
Le_RealCertPath=
Le_RealCACertPath=
Le_RealKeyPath=/root/nginx/certs/findmyfun.xyz.pem
Le_ReloadCmd=docker exec -it nginx bash -c "service nginx reload"
Le_RealFullChainPath=/root/nginx/certs/fullchain.pem
更新证书
默认情况下,证书每 60 天更新一次(可自定义),你也可以手动执行命令更新。
# 自动更新证书
acme.sh --cron
# 强制续签证书
acme.sh --renew -d findmyfun.xyz --force
更新证书后,Apache 或者 Nginx 服务会通过 reloadcmd 传递的命令自动重载配置,如果申请证书时使用的方法是手动修改DNS记录,在需要更新证书时请执行
acme.sh --renew -d example.com
设置通知(非必要)
5.1 设置更新证书通知
钉钉 dingtalk
推送通知到钉钉群聊天机器人,先在群设置中添加一个 webhook 机器人,获得 webhook url,并设置一个 keyword。目前不支持签名模式。
export DINGTALK_WEBHOOK='复制的Webhook'
export DINGTALK_KEYWORD=acme
acme.sh --set-notify --notify-hook dingtalk
飞书 feishu.cn
推送通知到飞书群聊天机器人。先在群设置中添加一个群机器人,获得 webhook 地址,并设置一个关键字(目前暂不支持签名模式)。
export FEISHU_WEBHOOK='https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxxxxxxx'
export FEISHU_KEYWORD=acme
acme.sh --set-notify --notify-hook feishu
**企业微信 work.weixin.qq.com
本站采用企业微信机器人推送通知的方式。先在群设置中添加一个群机器人,获得 webhook 地址,并设置一个关键字(目前暂不支持签名模式)。
export WEIXIN_WORK_WEBHOOK='https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=693a91f6-7xxx-4bc4-97a0-0ec2sifa5aaa'
export WEIXIN_WORK_KEYWORD=acme
acme.sh --set-notify --notify-hook weixin_work
设置通知级别,默认为2
# --notify-level <0|1|2|3>
# 0: 关闭没有通知
# 1: 有错误时才通知
# 2: 证书更新成功或错误才通知
# 3: 跳过更新、更新证书、错误都有通知
acme.sh --set-notify --notify-level 2
设置通知模式,默认为0
# --notify-mode <0|1>
# 0: 批量模式,所有更新信息放在一条通知里
# 1: 证书模式,每个域名更新都发一条通知
acme.sh --set-notify --notify-mode 0
nginx配置代理修改
证书默认安装位置/root/nginx/certs,因此需要修改下nginx默认配置文件
server {
listen 80;
server_name findmyfun.xyz;
#return 301 https://$host$request_uri;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name findmyfun.xyz;
access_log /var/log/nginx/findmyfun_xyz_access.log main;
error_log /var/log/nginx/findmyfun_xyz_error.log error;
#证书目录需要进行修改
ssl_certificate /etc/nginx/certs/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/findmyfun.xyz.pem;
...
client_max_body_size 1024m;
location ^~ /upload/ {
proxy_pass http://webps:3333;
proxy_set_header X-Real-IP $remote_addr;
proxy_hide_header X-Powered-By;
proxy_set_header HOST $http_host;
expires 7d;
}
location / {
gzip_static on; # 静态压缩
add_header Cache-Control public,max-age=60,s-maxage=60; # 配置缓存
proxy_pass http://halo:8090;
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
# 子域名也替换为泛域名证书
server {
listen 80;
server_name ****.findmyfun.xyz;
#return 301 https://$host$request_uri;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name ****..findmyfun.xyz;
access_log /var/log/nginx/ward_findmyfun_xyz_access.log main;
error_log /var/log/nginx/ward_findmyfun_xyz_error.log error;
ssl_certificate /etc/nginx/certs/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/findmyfun.xyz.pem;
ssl_session_timeout 5m;
...
client_max_body_size 1024m;
location / {
proxy_pass http://****:3002;
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
证书修改完之后,重启nginx
docker restart nginx
```shell
或者直接在线reload nginx
```shell
docker exec -it nginx nginx -s reload
如果nginx无法启动,可以通过以下命令查看异常日志
docker logs -f nginx
其他常用命令
# 查询所有命令
acme.sh -h
# 查看acme.sh版本
acme.sh -v
# acme.sh列出所有已注册证书
acme.sh --list
# acme.sh脚本升级
acme.sh --upgrade
# 设置acme.sh自动升级
acme.sh --upgrade --auto-upgrade 1
# 关闭acme.sh自动升级
acme.sh --upgrade --auto-upgrade 0
# 卸载acme.sh, 并删除所有acme.sh添加的crontab任务.
acme.sh --uninstall
# acme.sh更改申请证书机构
目前版本默认是ZeroSSL,一般不需要修改,可用机构见Wiki
acme.sh --set-default-ca --server zerossl
参考博客
1、docker 部署nginx+acme.sh 申请阿里云域名证书并且自动更新
2、acme.sh笔记
3、acme.sh申请泛域名(通配符)证书
评论区