侧边栏壁纸
博主头像
可乐没气的猫博主等级

四分之一的职业法师|二次元的分享家

  • 累计撰写 13 篇文章
  • 累计创建 6 个标签
  • 累计收到 19 条评论

目 录CONTENT

文章目录

20241202 博客证书替换acme.sh自动托管

可乐没气的猫
2024-12-02 / 0 评论 / 0 点赞 / 72 阅读 / 7,605 字

博客网站一直以来都是使用的腾讯云免费的一年SSL证书,但是目前由于规则更改,证书最长时间为一年,因此将本站证书替换为acme.sh自动托管,每隔三个月自动更换ZeroSSL提供的SSL证书。

安装 acme.sh

Github官方文档: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/.cer ,否则 SSL Labs 的测试会报证书链问题(Chain issues Incomplete)。

本站由于采用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申请泛域名(通配符)证书

0

评论区