win-acme全自动管理Let‘s Encrypt免费证书:申请续期部署一篇搞定
简介win-acme.v2.1.18-x64是一款面向Windows 64位系统的免费域名SSL证书自动化管理工具适合个人站长、中小企业及需要快速配置HTTPS的开发者使用。它基于ACME协议可自动完成Lets Encrypt免费证书的申请、验证、安装与续期支持HTTP与DNS挑战还能一次申请通配符证书并覆盖多域名大幅降低网站加密门槛。资源包内含27个文件以PowerShell脚本ps1为主承担自动化逻辑另有主程序exe、依赖dll、配置json及批处理bat等压缩包约29.58MB目录结构清晰便于按需部署和二次修改。工具提供图形界面与命令行接口附带详细日志和报告功能可跟踪证书状态与更新历史默认配置和示例脚本能帮助新手快速完成首次申请运维人员也可通过计划任务实现无人值守续期。该资源已有332人学习下载是零成本获取和管理SSL证书、提升网站安全性的实用选择。1. win-acme 免费域名证书申请把三个月手动续期变成全自动手里有四五个域名申请页面上明明写着免费证书有效期三个月结果每次到期都要登录后台、点申请、做 DNS 验证再下载证书手动替换一遍。win-acme v2.1.18-x64 这个工具就是来终结这种重复劳动的它运行在 Windows 上对接 Lets Encrypt 免费证书签发服务支持 HTTP-01 和 DNS-01 两种验证方式申请到证书后还能自动续期并部署到 IIS、nginx 或指定目录。想先澄清一点它解决的是证书申请和续期不是域名注册。你只需要有一个能管理 DNS 记录的域名就行哪怕是免费的域名也一样签发。适合独立站站长、中小企业运维以及和三个月提醒邮件搏斗许久的一线网管。2. 运行环境与首次启动依赖、目录和网络三件事2.1 缺运行库的典型症状0xc000007b、闪退与进程消失纯净版 Windows 或云厂商镜像上解压 win-acme 后双击最常看到的是“应用程序无法正常启动 0xc000007b”或者任务管理器里进程出现一两秒就消失。很多 x64 工具跑不起来十有八九是系统缺 Visual C 运行库。win-acme 本身是 .NET 程序但它同期的 x64 组件和附带脚本也依赖 VC 环境先把这一层补齐再排查操作问题。先查系统里已经装了哪些 VC x64 版本。管理员 PowerShell 里执行Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*, HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Where-Object { $_.DisplayName -match Visual C\\.*x64 } | Select-Object DisplayName, DisplayVersion这条命令同时扫了 64 位和 32 位注册表路径只要能看到Microsoft Visual C 2015-2022 Redistributable (x64)说明运行库已经就位。看不到就下载微软官方的 vc_redist.x64.exe静默安装.\vc_redist.x64.exe /install /quiet /norestart/quiet 表示不弹界面/norestart 表示装完不重启这两个都是 MSI 风格的通用参数装完重启一次再双击主程序。注意系统里多个版本的 VC Redistributable 共存是最稳的状态不要手动卸载老版本。删了一半其他 x64 软件连带崩掉的情况我见过不止一次。2.2 解压后的目录结构哪些文件能改、哪些不能动win-acme 不是那种往系统里塞一堆服务的软件解压出来就是绿色目录。建议固定放在C:\win-acme不要放桌面不要放带空格的路径。虽然多数情况下带空格也能跑但计划任务和命令行批处理一旦碰上路径转义问题排查起来非常玄学。标准解压包里关键文件和目录路径作用能不能动win-acme.exe主程序交互和命令行全靠它不能动settings.json全局配置包括邮件通知、代理、插件密钥可以改改动前先备份default.json命令行模式下的默认参数模板可以由交互模式自动生成letsencrypt/证书、私钥、订单和续期状态存放目录不能手动改整目录备份即可logs/运行日志报错第一现场只读参考很多新手把 letsencrypt 目录当成普通文件夹反复拷贝容易把证书私钥的权限搞乱。正确做法是整目录备份到备份盘或对象存储恢复时整目录放回来不要单独拖某个文件出来。settings.json 里最常改的是邮箱通知{ EmailOnRenewalFailure: true, NotificationMailAddress: youexample.com, Proxy: }EmailOnRenewalFailure 设成 true 后续期失败时会给 NotificationMailAddress 发邮件。v2.1.18 的邮件通知依赖系统 SMTP配不配都不影响证书续期但建议配上翻车时能第一时间收到风声。2.3 网络检查80 端口、443 端口与 ACME 服务商连通性申请之前先把网络通路验一遍。HTTP-01 验证要求公网 IP 能通过 80 端口访问验证文件DNS-01 验证只要求能添加 TXT 记录。win-acme 默认对接 Lets Encrypt国内网络环境下偶发连接不稳提前验证连通性很有必要。Test-NetConnection acme-v02.api.letsencrypt.org -Port 443 Test-NetConnection yourdomain.com -Port 80 Test-NetConnection yourdomain.com -Port 443三条命令分别返回 TcpTestSucceeded全部为 True 说明网络层没问题。第二条和第三条测的是你的域名解析和 Web 服务端口。HTTP-01 验证时 win-acme 会临时在站点根目录放验证文件Lets Encrypt 那边来抓取对公网 80 端口要求很高。如果 80 端口没放通直接走 DNS-01别硬刚浪费的时间够申请十张证书。反向代理或 CDN 场景还要注意一个问题验证请求被 CDN 缓冲导致 Lets Encrypt 抓到的内容不对。常见做法是先用直连模式申请到证书再套 CDN不要全程套着 CDN 去申请。2.4 日志目录排错第一现场logs 目录下每个运行周期一个文件命名带日期时间。遇到莫名其妙的失败先翻最新的日志找 Error 和 Warn 级别的行。Get-ChildItem C:\win-acme\logs -Recurse | Sort-Object LastWriteTime -Descending | Select-Object -First 1 | Get-Content -Tail 50这条命令先按修改时间倒序找到最新日志文件再取最后 50 行。我每次处理 win-acme 反馈问题时都让对方先跑这一条把输出贴过来比反复猜测快得多。日志里能看到验证请求发送到了哪个地址、返回了什么状态码DNS 验证失败最常见的就是 404 和 time out 两种下一步动作完全不同。3. 申请第一张证书交互菜单和命令行两种走法3.1 交互模式申请按序号走的完整流程win-acme 没有图形界面主程序启动后是纯文本菜单。第一次运行建议先走一遍交互模式因为它每步都有提示比直接丢命令行参数更直观。v2.1.18 的流程大致是这样启动 win-acme.exe 后主菜单出现按键盘方向键和回车操作。选择创建新证书工具会先问用哪种验证方式HTTP 验证自动匹配 IIS 站点DNS 验证手动加 TXT 记录。选 HTTP 后输入要申请证书的域名比如 example.com。如果域名绑定了 IIS 站点win-acme 会列出站点 ID 让你确认如果是独立部署的 nginx 或 Tomcat就选不关联站点让它只生成证书文件。交互模式跑完之后默认会生成一份 default.json里面记录了这次申请的完整参数。下次想用命令行重跑或批量申请直接复用这个文件不用再对着菜单点一遍。这是第一单推荐走交互的原因先让工具把配置模板生成出来再往里面加域名。交互过程中如果输错域名或者验证方式选错了不用退出重来。v2.1.18 的菜单支持返回上一级直接按退到上一步的快捷键即可日志里不会有脏数据残留。3.2 验证方式对比HTTP-01 与 DNS-01 各管什么验证方式原理适用场景前置条件HTTP-01在域名的 Web 根目录放验证文件CA 抓取比对域名解析指向本机或有反代80 端口公网可达DNS-01添加 _acme-challenge 的 TXT 记录CA 读取泛域名、内网服务器、DNS 在第三方托管能操作 DNS 控制台或 APIHTTP-01 的优点是拿到验证文件后能自动部署到 IIS几乎零运维缺点是服务器必须直接暴露 80 端口。DNS-01 的优点是只要 DNS 能解析服务器在内网都能签发还能签泛域名*.example.com缺点是 TXT 记录生效有延迟每次验证都要改一次 DNS手工操作很痛苦必须配合自动化插件才有体验。不少国内运营商会封禁 80 端口这也是很多线上事故最后靠 DNS-01 救回来的原因。如果你只维护个人站点第一张证书建议两种都试一遍HTTP-01 能让你理解证书怎么和 Web 服务绑定DNS-01 能让你理解证书签发本质上只跟域名所有权有关。3.3 命令行一次申请参数拆解与证书输出不想走菜单或者想写脚本批量跑直接命令行。以申请同时覆盖 example.com 和 www.example.com 的证书为例.\win-acme.exe --source manualhost --host example.com,www.example.com --validation http --target iis --install iis逻辑说明--source manualhost 表示主机列表由我手动指定--host 后面跟逗号分隔的域名列表包在引号里防止命令行把逗号当成元字符--validation http 指定走 HTTP-01 验证--target iis 表示证书准备给 IIS 用--install iis 表示自动绑定到 IIS 对应站点执行前确认 IIS 里有同名站点存在。如果用的是 nginx、Apache 或纯手动部署把--target iis --install iis换成--target manual --install none证书只生成不安装输出路径在C:\win-acme\letsencrypt\你的域名\下。申请完成后的关键文件文件名内容建议用途certificate.crt叶子证书单独部署场景备用chain.pem中间证书链配合叶子证书使用key.pem私钥务必别泄漏fullchain.pem叶子中间链合并nginx/IIS 导入首选拿到证书先验证有效期openssl x509 -in certificate.crt -noout -datesnotBefore 和 notAfter 一般覆盖 90 天因为 Lets Encrypt 按 90 天周期签发。后续续期成功会生成新文件旧文件带时间戳归档别拿旧文件部署。4. 自动续期与多域名批处理计划任务加参数组合4.1 注册计划任务每日触发与续期参数win-acme 不常驻后台它靠 Windows 计划任务按天唤醒。设置每日或每周跑一次 --renew 即可Lets Encrypt 的续期宽限期足够长不用担心漏跑。用 PowerShell 注册一个每天早上触发的计划任务$action New-ScheduledTaskAction -Execute C:\win-acme\win-acme.exe -Argument --renew $trigger New-ScheduledTaskTrigger -Daily -At 04:30 Register-ScheduledTask -TaskName WinACME_Renew -Action $action -Trigger $trigger -RunLevel Limited -Description 每日检查SSL证书续期逻辑说明New-ScheduledTaskAction 指定程序路径和参数--renew 是 win-acme 的续期开关New-ScheduledTaskTrigger 定义触发时间Register-ScheduledTask 把两者注册成计划任务。-RunLevel Limited 很关键win-acme 多数场景不需要管理员权限用 Limited 运行既安全又能避免 UAC 弹窗。提示计划任务的启动时间建议避开整点。ACME 服务商在整点附近请求量巨大提前或延后十几分钟并错开能明显降低验证超时概率这是批量运维的默认习惯。注册完之后检查任务上次运行结果Get-ScheduledTaskInfo -TaskName WinACME_RenewLastTaskResult 为 0 表示上一次执行成功。非 0 就去事件查看器或 win-acme 的 logs 目录翻原因别等证书过期了才发现任务根本没跑过。4.2 多域名组合一张证书多 SAN 还是每个域名独立同一个站点挂了多个域名优先做成一张证书多个 SAN 域名。上面 3.3 的命令已经演示了逗号分隔的写法--host 里每一个域名都会写进证书的 Subject Alternative Name 字段浏览器访问任何一个都能正常显示锁标识。如果多个域名分散在不同服务器、不同站点或者生命周期不同就分开申请。分开申请的好处是一条链路挂掉不影响另一条坏处是计划任务日志里会有多个订单提醒。我的习惯是同一台服务器上、同一个站点绑定的域名全合成一张证书跨服务器、跨用途的域名各管各的。特别提醒一点多 SAN 证书有个常见误用是把域名 A 和域名 B 绑在不同服务器上然后把证书复制到两台服务器。证书本身没问题但私钥同时在两台机器上出现泄露面扩大了一倍而且续期逻辑会变复杂。能分开就分开。4.3 DNS 插件接入阿里云/腾讯云 API 密钥配置DNS-01 做到全自动就得让 win-acme 通过 API 动态添加 TXT 记录而不是每次手工去控制台改。v2.1.18 的插件体系不把每家 DNS 服务商的插件都放进主程序包常见做法是去对应版本下载页找 DNS 插件 dll放到 win-acme 主程序目录然后在 settings.json 里写 API 密钥。配置文件里的写法大致是这样{ Plugins: { Aliyun: { AccessKeyId: 你的AccessKeyId, AccessKeySecret: 你的AccessKeySecret } } }逻辑说明Aliyun 段只在签名和调用 API 时使用。密钥不要用主账号的去 RAM 控制台开一个只授权 DNS 解析权限的子账号把 AccessKeyId 和 AccessKeySecret 换上去。插件 dll 放入主程序目录后 win-acme 启动时会自动加载加载失败会在启动界面报类型加载异常。排查时先看 dll 位数x64 主程序必须放 x64 编译的插件 dll32 位插件在 x64 进程里会报不兼容异常。密钥明文放在 settings.json 里确实有风险尤其配置文件可能被拷贝到其他机器时。更稳的做法是先用交互模式把 DNS 验证的插件配置走通让工具自己生成配置文件再配合 Windows 文件权限把 settings.json 设为仅管理员可读写。4.4 续期失败时的人肉兜底再稳定的自动化也有失效的一天。计划任务虽然每天跑但如果服务器当天关机、网络断开、或者密钥过期--renew 会静默失败。EmailOnRenewalFailure 能帮忙通知但邮件也可能进垃圾箱。我一般再加一条巡检计划任务每周跑一次脚本把证书剩余天数少于 20 天的域名列出来。具体脚本在第六章会写全这里先提一个命令手动触发全量检查.\win-acme.exe --renew --force--force 会忽略续期状态文件强制重新走一遍签发流程。这个参数不要每天都用它有触发频率限制只在确认证书快过期但 --renew 没动静时手动执行。5. 避坑记录五条从安装到验证的高频故障实录5.1 安装报错 1603多半是运行库冲突现象使用安装包版本部署 win-acme 时进度条跑到一半弹窗警告由于错误 1603安装回滚主程序没装上。原因1603 是 Windows Installer 通用错误码绝大多数是系统里已有的 Visual C 运行库版本与安装包要求冲突也有小概率是杀毒软件锁定安装目录。解决先把所有 Visual C 2015-2022 x64 相关组件卸载干净再静默重装wmic product where name like %Visual C%x64% call uninstall /nointeractive .\vc_redist.x64.exe /install /quiet /norestartwmic 那条命令会把匹配到的 VC 组件全部卸载执行前确认没有其他依赖这些运行库的软件在运行。这个粗暴办法能解决八成 1603剩下两成是安装缓存损坏清理缓存需要专业工具。我一般直接换绿色解压版 zip 包彻底绕开 MSI 安装这条链路。5.2 win-acme.exe 双击没反应先看事件查看器现象双击 exe 后任务管理器里进程出现一两秒就消失没有窗口也没有报错。原因v2.1.18 依赖对应版本的 .NET Framework 运行时纯净系统往往没装全。Windows Server 2016 默认带的 .NET 版本偏低win-acme 起不来。解决打开事件查看器Windows 日志 → 应用程序找级别为错误的条目看到 .NET Runtime 字样就去装 .NET Framework 4.8 离线安装包。装完重启再双击主程序。# 查看当前.NET Framework版本4.8对应Release值528040以上 (Get-ItemProperty HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full).Release输出值大于等于 528040 表示 4.8 已就绪。这类问题在开发机上很少遇到反而是云服务器纯净镜像上高频出现属于典型的环境坑。5.3 DNS-01 验证超时先手动解析再重试现象用 DNS-01 申请证书win-acme 在等 CA 校验 TXT 记录等了半小时最终报 Failed日志里写着 timed out waiting for dns。原因最常见三种情况TXT 记录值粘贴少了字符、TTL 设置太长导致公共 DNS 缓存了旧记录、或者 DNS 服务商的子账号没有 TXT 添加权限。解决先不要重试申请手动解析验证域名Resolve-DnsName _acme-challenge.example.com -Type TXT -Server 8.8.8.8看到输出的 Strings 字段有完整验证串再和 win-acme 日志里的记录值逐字比对包括末尾的点和大写字母。都能对上后重新执行申请通常直接跳过等待期。TTL 太长导致的超时把 TXT 记录 TTL 临时改成 60 秒验证通过后再调回默认值。5.4 证书装好了浏览器仍报警缺中间链或端口不匹配现象win-acme 日志显示证书已生成并安装IIS 站点也绑定了证书但浏览器访问仍然是 NET::ERR_CERT_AUTHORITY_INVALID。原因安装时选了不完整的证书文件。IIS 或 nginx 只配了叶子证书 certificate.crt没把中间证书链配上CA 无法通过中间证书回溯到根证书。解决HTTP-01 验证后直接选自动安装到 IIS它会用完整链绑定手动部署时一定用 fullchain.pem 这个合并文件ssl_certificate C:/win-acme/letsencrypt/example.com/fullchain.pem; ssl_certificate_key C:/win-acme/letsencrypt/example.com/key.pem;改成 fullchain 后重新 reload 服务再访问一次。除了缺链还有一种玄学是服务器把证书绑在了非 443 端口浏览器默认请求 443拿到的自然是旧证书用开发者工具看实际响应端口就能定位。5.5 续期报告Nothing to renew但证书快过期了现象计划任务跑得挺勤日志里每天都是 Nothing to renew但浏览器提示证书还有 10 天过期。原因win-acme 的 --renew 只认 letsencrypt 目录下的续期状态文件。如果证书是手工拷进去的或者有人手动改过文件状态可能不一致它认为不需要更新实际上文件已经旧了。解决不带 --force 参数的 --renew 只是检查不实际执行。确认证书确实快过期用 --force 强制续期一次.\win-acme.exe --renew --force从那以后我每次手动动 letsencrypt 目录里的文件都会顺手把日志翻一遍确认状态没有错乱再交给计划任务托管。6. 进阶技巧一键续期部署与到期日巡检6.1 续期加部署一体化脚本计划任务只负责 --renew证书续期后还得手工复制到目标服务并 reload等于自动化了一半。我的习惯是写一个 PowerShell 脚本把续期、复制、reload 三件事串起来# renew_and_deploy.ps1 $ErrorActionPreference Stop C:\win-acme\win-acme.exe --renew if ($LASTEXITCODE -eq 0) { Copy-Item C:\win-acme\letsencrypt\example.com\fullchain.pem \\web01\c$\ssl -Force Copy-Item C:\win-acme\letsencrypt\example.com\key.pem \\web01\c$\ssl -Force ssh adminweb01 nginx -s reload }逻辑说明win-acme 的 --renew 在无新证书可续时会返回非 0 退出码用 $LASTEXITCODE 判断后续步骤是否执行避免空跑复制命令。证书文件通过 Windows 共享路径复制到目标服务器再通过 OpenSSH 触发 nginx 重载让新证书立刻生效。如果用的是 IIS把 ssh 那条换成 iisreset。这个脚本能直接用前提是 win-acme 所在机器的账户对 web01 的 C$\ssl 目录有写权限且 OpenSSH 免密登录已配好。第一次跑之前在 web01 上手动执行 nginx -t 确认语法没问题再交给计划任务托管。6.2 全部证书到期日巡检脚本除了自动续期定期巡检是防翻车的最后防线。下面这段脚本递归扫描 letsencrypt 目录把每张证书的剩余天数列出来Get-ChildItem C:\win-acme\letsencrypt -Recurse -Filter *.crt | ForEach-Object { $cert New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($_.FullName) [PSCustomObject]{ Domain $_.Directory.Name Expires $cert.NotAfter.ToString(yyyy-MM-dd) DaysLeft [math]::Round(($cert.NotAfter - [DateTime]::Now).TotalDays) } } | Sort-Object DaysLeft | Format-Table -AutoSize逻辑说明$_.Directory.Name 是域名目录名一眼能看出哪张证书要到期Expires 换算成习惯的日期格式DaysLeft 显示剩余天数负数代表已经过期。把这段脚本加进每周巡检的 bat 里哪天看到 DaysLeft 小于 30就去人工确认计划任务有没有漏跑比纯靠心里记日期靠谱得多。从那以后我每次部署 win-acme都强制走一遍同样的流程先查运行库和 .NET 版本再验 80 端口连通性然后才启动主程序申请证书DNS 验证前也一定会手动解析 TXT 记录确认值完整。这套习惯救过好几次急希望帮到你。本文还有配套的精品资源点击获取