
适用环境:Windows 腾讯云主机 + 域名解析在阿里云 + Nginx 证书类型:Let's Encrypt 免费 DV 证书(有效期 90 天,自动续签) 验证方式:DNS-01(阿里云 DNS API 自动添加 TXT 记录,不占用 80 端口)
目录
-
[二、安装 Git(提供 Bash 环境)](#二、安装 Git(提供 Bash 环境))
-
[四、获取阿里云 RAM 子账号密钥](#四、获取阿里云 RAM 子账号密钥)
-
[六、部署证书到 Nginx](#六、部署证书到 Nginx)
-
[九、常见问题 FAQ](#九、常见问题 FAQ)
一、整体思路(先搞懂在做什么)
自动续签这件事,本质是 4 个环节串起来,缺一个都不算"自动":
| 环节 | 谁负责 | 作用 |
|---|---|---|
| ① 终端环境 | Git Bash | 提供类 Linux 的 Bash 环境,让 acme.sh 脚本能跑起来 |
| ② 签发工具 | acme.sh | 向 Let's Encrypt 申请/续签证书,通过 DNS API 自动验证域名归属 |
| ③ 域名验证 | 阿里云 DNS (dns_ali 插件) |
自动添加/删除 _acme-challenge 的 TXT 记录,证明"这域名是你的" |
| ④ 定时触发 | Windows 计划任务 acme.sh.cron |
每天跑一次 --cron,到期才续,不到期就跳过 |
关键认知:
-
主机在腾讯云 ≠ 用腾讯云 DNS 。DNS 验证看的是"域名解析记录在哪一家"------解析在阿里云,就必须用
dns_ali插件。 -
计划任务只决定"多久检查一次",真正决定"多久续一次"的是 acme.sh 内部判断(证书剩余 < 30 天才续)。
-
证书文件替换不是计划任务直接复制,而是 acme.sh 续签成功后,按
--install-cert时记录的路径自动覆盖 + 执行 reload。
二、安装 Git(提供 Bash 环境)
acme.sh 是一个 Shell 脚本,必须在 Bash 环境下运行,Windows 本身没有,所以需要装 Git for Windows。
2.1 安装过程中的关键选项
| 安装界面 | 正确选择 | 说明 |
|---|---|---|
| 默认编辑器 | Use Visual Studio Code / Notepad | 不要选 Vim(新手容易卡在里面出不来) |
| PATH 环境 | Git from the command line and also from 3rd-party software | 让 CMD/PowerShell/VS Code 都能识别 git |
| SSH 客户端 | Use bundled OpenSSH | 自带、独立、不冲突 |
| HTTPS 后端 | Use the OpenSSL library | 个人环境最稳,不受系统证书更新干扰 |
| 换行符转换 | Checkout Windows-style, commit Unix-style | Windows 官方推荐默认项 |
| 终端模拟器 | Use MinTTY | 复制粘贴方便、中文不乱码 |
| git pull 行为 | Merge(默认) | 最安全直观 |
| 额外选项 | 勾选 Enable file system caching |
提升运行速度;符号链接不用勾 |
2.2 验证安装
安装完成后,右键菜单选 Git Bash Here,执行:
git --version
输出类似 git version 2.56.0.windows.2 即成功。
三、安装 acme.sh
国内云主机直连 GitHub 经常超时或被重置,改用国内 Gitee 镜像 用 git clone 安装。
3.1 安装命令
# 1. 清理可能失败的残留
rm -rf acme.sh
# 2. 用国内 Gitee 镜像拉取(官方镜像较旧,用此同步镜像)
git clone https://gitee.com/wenber/acme.sh.git
# 3. 进入目录
cd acme.sh
# 4. 执行安装(把邮箱换成你自己的)
./acme.sh --install -m your@email.com
3.2 关于"输入 Windows 密码"
安装过程中如果出现:
Please input your Windows password for: Administrator
这是正常的! 表示 acme.sh 正在尝试创建 Windows 计划任务(用于自动续签),需要管理员权限验证身份。
-
正确做法:输入 Administrator 账号的登录密码,回车。
-
不要 按
Ctrl + C终止,否则计划任务建不起来,自动续签就废了。
安装过程中出现的
socat缺失警告可以直接忽略,用 DNS 验证方式不需要它。
3.3 让配置生效并验证
安装完成后关闭 Git Bash,重新打开,执行:
~/.acme.sh/acme.sh --version
能显示版本号即安装成功。
重要 :以后所有 acme.sh 命令都用
~/.acme.sh/acme.sh绝对路径调用,最稳,不受 alias 是否生效影响。
四、获取阿里云 RAM 子账号密钥
因为域名解析在阿里云,要用 dns_ali 插件,需要阿里云的 API 密钥来自动操作 DNS 记录。
4.1 创建 RAM 子账号(不要用主账号!)
-
登录阿里云控制台 → 访问控制 RAM
-
创建用户 → 勾选「OpenAPI 调用」
-
授权策略:
-
省事:
AliyunDNSFullAccess -
更严谨:只授予「云解析 DNS」的写记录权限
-
-
创建后拿到一对:AccessKey ID 和 AccessKey Secret
4.2 ⚠️ 安全铁律
-
永远不要在聊天记录、截图、日志、GitHub 里贴出你的 AccessKey Secret。
-
一旦泄露,立即去 RAM 控制台禁用并删除该 AccessKey,重新建一对。
-
建议用子账号密钥,权限最小化,即使泄露影响范围也有限。
五、签发证书
5.1 注入密钥(注意变量名!)
dns_ali 插件只读 Ali_Key 和 Ali_Secret ,用错变量名会报 You don't specify aliyun api key and secret yet。
export Ali_Key="你的AccessKeyId"
export Ali_Secret="你的AccessKeySecret"
常见错误:把变量名写成
Tencent_SecretId/Tencent_SecretKey。那是腾讯云插件的变量名,用dns_ali时不认。
5.2 设置默认 CA
~/.acme.sh/acme.sh --set-default-ca --server letsencrypt
5.3 签发
~/.acme.sh/acme.sh --issue -d ai.dql5251.top --dns dns_ali
-
要带
www:追加-d www.dql5251.top -
要通配符:
-d '*.dql5251.top'
5.4 成功标志
看到以下输出即成功:
Success
Cert success.
-----BEGIN CERTIFICATE-----
证书文件位于:~/.acme.sh/ai.dql5251.top_ecc/ 目录下。
5.5 关于过程中的红色错误行
签发日志里可能出现红色字体的 curl error code: 35、28 等,例如:
Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: 35
Please refer to ... for error code: 28
Sleeping for 20 seconds first
这不是报错,不用管。 这是 acme.sh 用 curl 检查 DNS 解析是否生效时遇到的网络抖动:
-
Error 28:连接超时
-
Error 35:SSL/TLS 握手失败
acme.sh 有自动重试机制 ,会休眠 20 秒后换公共 DNS 再查。只要后面出现 All checks succeeded 和 Success,就说明重试后已顺利拿到证书。
六、部署证书到 Nginx
签发成功后,需要把证书"部署"到 Nginx 使用的路径,并让 acme.sh 记住覆盖路径 和重载命令,这样以后每次续签才能自动生效。
6.1 部署命令
假设你的 Nginx 证书目录是 C:/nginx/certs/,证书文件名为 ai.DQL5251.top-key.pem 和 ai.DQL5251.top-chain.pem:
~/.acme.sh/acme.sh --install-cert -d ai.dql5251.top \
--key-file /c/nginx/certs/ai.DQL5251.top-key.pem \
--fullchain-file /c/nginx/certs/ai.DQL5251.top-chain.pem \
--reloadcmd "cd /c/nginx && ./nginx.exe -s reload"
路径写法注意 :在 Git Bash 里,
C:/xxx要写成/c/xxx。
这条命令干了三件事:
-
把新证书复制到 Nginx 的 certs 目录(覆盖)
-
把这两条路径和 reload 命令记录进域名配置文件
-
以后每次续签成功,自动执行"覆盖 + reload"
6.2 验证 Nginx 是否生效
浏览器访问 https://ai.dql5251.top,点地址栏小锁图标,确认证书有效期已更新。
七、自动续签原理(计划任务)
7.1 acme.sh 自动创建了计划任务
acme.sh 安装时(就是让你输密码那一步)会自动在 Windows 任务计划程序里创建一个名为 acme.sh.cron 的任务:
-
路径:任务计划程序库 → 根目录(不在子文件夹里)
-
触发器:每天 0:12 执行
-
操作 :调用
bash.exe -c "~/.acme.sh/acme.sh --cron --home ~/.acme.sh"
打开 taskschd.msc 就能看到它,状态为"准备就绪",说明自动续签已经就绪。
7.2 续签链路全貌
Windows 计划任务(每天 0:12)
│
▼
acme.sh --cron
│
├─ 证书剩余 > 30 天 → 输出 "Skip, cert not due" → 退出(不消耗配额)
│
└─ 证书剩余 < 30 天 → 用 dns_ali 自动加 TXT → 续签成功
│
▼
按 --install-cert 记录的路径覆盖证书文件
│
▼
执行 --reloadcmd(nginx -s reload)
7.3 关于"频率"的两个误区
| 误解 | 真相 |
|---|---|
| 计划任务每天跑 = 每天续签一次 | ❌ 计划任务每天检查一次,到期才续 |
| 需要手动写 bat 复制证书 | ❌ acme.sh 内部钩子自动覆盖,计划任务不碰证书文件 |
八、日常检查与排错
8.1 查看证书列表和续签日期
~/.acme.sh/acme.sh --list
输出示例:
Main_Domain KeyLength SAN_Domains CA Created Renew
ai.dql5251.top "ec-256" no LetsEncrypt.org 2026-10-20T09:25:12Z 2026-12-18T09:25:12Z
Renew 列就是预计续签日期。
8.2 查看证书详细信息
~/.acme.sh/acme.sh --info -d ai.dql5251.top
8.3 确认部署配置已记录
grep -E "Le_KeyFile|Le_FullChainFile|Le_ReloadCmd" \
~/.acme.sh/ai.dql5251.top_ecc/ai.dql5251.top.conf
有输出 = 续签后会自动覆盖 + reload。
8.4 查看证书实际到期时间
openssl x509 -in /c/nginx/certs/ai.DQL5251.top-chain.pem -noout -dates
8.5 手动触发一次续签检查(不强制)
~/.acme.sh/acme.sh --cron
-
输出
Skip/Cert not due→ 正常,没到续签期 -
输出
Renew+reload→ 这次真续了
8.6 ⚠️ 别手贱反复重签
Let's Encrypt 生产环境限速:
| 限制项 | 阈值 |
|---|---|
| 同注册域名 | 50 张 / 7 天 |
| 同域名集合 | 5 张 / 7 天 |
触发后只能等,官方不手工解封。
# ❌ 禁止反复跑,会吃配额
acme.sh --renew --force
# ✅ 想测试就用这个,没到 30 天直接 Skip,不消耗配额
acme.sh --cron
8.7 排错加 --debug
~/.acme.sh/acme.sh --issue -d ai.dql5251.top --dns dns_ali --debug 2
在输出里搜 Ali_Key 看密钥有没有被正确读取。
8.8 密钥写错怎么改
如果密钥有换行、空格或拼错,检查并修正:
# 编辑配置文件
vi ~/.acme.sh/account.conf
确保 Ali_Key 和 Ali_Secret 的值没有多余字符。
九、常见问题 FAQ
Q1:为什么 acme.sh: command not found?
A :安装时按了 Ctrl+C 或密码没输对,导致安装没跑完。用绝对路径 ~/.acme.sh/acme.sh 重试;还是不行就按第三章重装一次(别加 --no-cron)。
Q2:为什么报 You don't specify aliyun api key and secret yet?
A :变量名写错了。dns_ali 插件只读 Ali_Key / Ali_Secret,不认 Tencent_* 或其他名字。
Q3:schtasks /query 报 无效参数/选项 - 'C:/Program Files/Git/query'?
A :schtasks 是 Windows 原生命令,不能在 Git Bash 里跑 (Bash 会把 /tn 转成路径)。要么在图形界面看,要么用管理员 PowerShell / CMD 执行。
Q4:计划任务名字为什么叫 acme.sh.cron 而不是我设的名字?
A :这是 acme.sh 官方安装时自动创建的名字,直接用就好。截图里那个 win-acme renew 是另一款工具建的,跟你无关。
Q5:签发日志里的红色 curl 错误要管吗?
A :不用。那是 DNS 检查的网络抖动,acme.sh 会自动重试。只要最后出现 Success 和 -----BEGIN CERTIFICATE----- 就成功了。
Q6:证书文件到底是谁复制的?
A :是 acme.sh 内部部署钩子(--install-cert 时记录的路径),不是计划任务,也不是你手动 copy。
十、安全提醒
-
AccessKey 是最高敏感凭证,一旦在任何公开场合泄露,立刻去阿里云 RAM 控制台禁用删除并重建。
-
永远用 RAM 子账号,权限只开「云解析 DNS」,不用主账号密钥。
-
别把 Secret 写进会被提交的脚本或日志 。
--install-cert之后 acme.sh 会把密钥加密存进配置,一般不用重复 export。 -
别用
--force反复续签,会触发 Let's Encrypt 限速,导致 7 天内无法再签发。
附录:最终状态清单
-
证书:Let's Encrypt,有效期 90 天
-
验证方式:阿里云 DNS API (
dns_ali),自动加 TXT,不占 80 端口 -
部署路径:
C:/nginx/certs/,nginx.conf 无需改动 -
续签触发:Windows 计划任务
acme.sh.cron,每天 0:12 -
续签判断:证书剩余 < 30 天
-
生效方式:自动覆盖证书文件 +
nginx -s reload -
人工介入:0
一句话总结:装好 Git → 装好 acme.sh(输密码别跳过)→ 配好阿里云 DNS 密钥 → 签发 → 部署到 Nginx → 计划任务已自动建好 → 从此不用再管。