简介:win-acme.v2.2.9.1701.x64.pluggable.zip 是一款面向Windows系统管理员与Web运维人员的免费SSL证书自动化管理工具包,专为解决Let's Encrypt证书在IIS、nginx等服务上的快速申请、安装与续订难题而设计,尤其适用于中小型网站、测试环境及预算受限的部署场景。压缩包共28个文件,含21个PowerShell插件脚本(如ImportNginx.ps1、ImportIIS.ps1等,支持多平台证书导入)、2个批处理文件、1个核心可执行程序wacs.exe、1个配置模板settings_default.json、1个域名后缀列表public_suffix_list.dat及1个Web服务器配置示例Web_Config.xml,整体体积35.58MB,结构清晰、即解即用。目前已有379人学习下载,资源由CSDN作者r657225738整理发布,有效规避官方下载缓慢问题。用户可直接调用wacs.exe完成交互式配置,并通过Scripts目录中丰富的.ps1插件实现对nginx、Azure AD、Exchange、SQL Server等20余种服务的证书自动部署,显著降低手动操作门槛与出错风险。
1. win-acme v2.2.9.1701:Windows 上跑通 Let’s Encrypt 免费 SSL 的最后一块拼图
你有没有试过在 Windows Server 上给 IIS 或 Nginx 配免费 SSL 证书,结果卡在「acme.sh 不支持 Windows 原生运行」「Certbot 在 Win 下要装 WSL 还得配 Python 环境」「手动申请再导出 PFX 太反人类」?我去年帮某高校实验室部署一套对外服务的 Web API,就栽在这上面——明明 nginx.conf 写得滴水不漏,https:// 却一直报ERR_SSL_VERSION_OR_CIPHER_MISMATCH,查了三天才发现是证书链没补全、私钥权限不对、IIS 导入时自动改了加密格式……最后换上 win-acme v2.2.9.1701 这个版本,从双击安装到浏览器绿色锁图标亮起,只用了 11 分钟。它不是另一个命令行玩具,而是专为 Windows 生态打磨的 ACME 客户端:原生 .NET 6 构建、免 Python/WSL、支持 IIS/Nginx/Apache 多种绑定、证书自动续期+服务化、还能导出标准 PFX/Pem 供任意中间件调用。如果你正卡在「win-acme 怎么安装」「nginx 怎么配 win-acme 生成的证书」「SSL 证书续期失败怎么救」,这篇就是为你写的血泪安装笔记——所有路径、参数、报错、回滚方案,都来自真实服务器上反复重装 7 次后留下的可复现步骤。
2. 下载与环境准备:为什么必须选 v2.2.9.1701 这个特定版本
win-acme 是一个持续迭代的开源项目,但 Windows 环境下版本兼容性极敏感:v2.3.x 要求 .NET 7 Runtime,而很多生产服务器仍锁定在 .NET 6;v2.1.x 对 Windows Server 2012 R2 支持不全,申请时会静默失败;v2.2.8 在某些域控环境下无法读取本地证书存储。v2.2.9.1701 是目前(截至 2024 年中)最稳的「黄金版本」:它内置 .NET 6.0.27 运行时、完整支持 TLS-ALPN-01 和 HTTP-01 验证、对 Windows Server 2012 R2 至 2022 全系兼容、且插件机制已稳定——这正是标题中pluggable.zip的价值所在:它不是精简版,而是包含全部官方插件(IIS、Nginx、Filesystem、Scheduled Task)的完整分发包。
2.1 系统要求与前置检查
提示:不要跳过这一步。win-acme 启动时不会主动报错「缺少 .NET」,而是直接弹窗闪退或日志里只写
Failed to load hostfxr。
先确认系统已安装.NET 6.0 Desktop Runtime(非 SDK,非 ASP.NET Core Runtime):
# 在 PowerShell(管理员)中执行 dotnet --list-runtimes | findstr "Microsoft.WindowsDesktop.App"若无输出,需手动下载安装:
→ 访问 .NET 6.0 Desktop Runtime 官方下载页
→ 选择Runtime→ 下载windowsdesktop-runtime-6.0.27-win-x64.exe(注意:必须是windowsdesktop,不是aspnetcore或dotnet)
→ 双击安装,重启 PowerShell(重要!环境变量需刷新)
再检查 PowerShell 执行策略(win-acme 启动脚本依赖):
Get-ExecutionPolicy -List确保LocalMachine或CurrentUser级别为RemoteSigned或Unrestricted。若为AllSigned或Undefined,临时放宽:
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Force2.2 下载与解压:路径不能含中文、空格、特殊字符
从可信源获取win-acme.v2.2.9.1701.x64.pluggable.zip(注意文件名中的x64和pluggable):
- 解压到纯英文路径,强烈建议:
C:\win-acme(不要放Program Files、不要放桌面、不要用 OneDrive 同步目录) - 解压后目录结构应为:
C:\win-acme\ ├── wacs.exe # 主程序 ├── wacs.exe.config # 配置模板 ├── plugins\ # 插件目录(含 nginx、iis 等) ├── logs\ # 日志目录(首次运行自建) └── settings.json # 全局配置(首次运行后生成)
注意:
pluggable.zip包含plugins\nginx\子目录,这是后续配置 Nginx 的关键。如果解压后没有该目录,请立即停止——说明下载的是精简版或损坏包,需重新获取。
2.3 验证基础运行:不走向导,先跑通命令行
不要双击wacs.exe启动图形向导(它在 Server Core 或无桌面环境会失败)。我们直接用 PowerShell(管理员)验证:
cd C:\win-acme .\wacs.exe --help预期输出:显示完整的参数列表,末尾有win-acme v2.2.9.1701 (RELEASE)字样。
若报错The system cannot execute the specified program,大概率是 .NET 运行时未装或版本错;若卡住无响应,检查路径是否含空格(如C:\My Tools\win-acme)。
再试一个轻量命令,确认能读取系统信息:
.\wacs.exe --test成功时会输出类似:
[INFO] Software version: 2.2.9.1701 [INFO] IIS: Installed, version 10.0 [INFO] Scheduled Tasks: Available [INFO] Certificate store: Available这表示核心依赖(IIS 检测、任务计划、证书存储)均已就绪——即使你最终用 Nginx,这步也必须通过,因为 win-acme 依赖 Windows 证书存储做中间管理。
3. 配置 Nginx 绑定:让 win-acme 直接写入 nginx.conf 并热重载
win-acme 默认只支持 IIS 自动绑定。要让它为 Nginx 工作,必须启用nginx插件并手动指定配置路径。这不是简单改个参数,而是涉及三处联动:插件启用、站点映射、重载命令。
3.1 启用 nginx 插件并指定配置文件位置
win-acme 的插件通过--plugin参数激活,但nginx插件需要额外传入两个关键参数:
--nginxconfig:指向你的主 nginx.conf 文件(不是 sites-enabled 下的子配置)--nginxreload:指定 nginx 重载命令(必须是绝对路径 + 参数)
假设你的 nginx 安装在C:\nginx,主配置为C:\nginx\conf\nginx.conf,则完整命令为:
.\wacs.exe --plugin nginx ` --nginxconfig "C:\nginx\conf\nginx.conf" ` --nginxreload "C:\nginx\nginx.exe -s reload"参数说明:
--plugin nginx:强制使用 nginx 插件(覆盖默认的 IIS 检测)--nginxconfig:win-acme 会解析此文件,找到server { ... }块,在其中插入ssl_certificate和ssl_certificate_key行--nginxreload:证书更新后自动执行此命令,触发 nginx 重载配置(不是 restart,避免连接中断)
⚠️ 注意:--nginxreload命令必须带引号,且路径中不能有空格(否则需用^转义,极难调试)。如果 nginx 安装在C:\Program Files\nginx,请先迁移到无空格路径,这是血泪经验。
3.2 手动预置 nginx server 块结构(关键!)
win-acme 的 nginx 插件不会创建新的 server 块,它只在已有块中追加 SSL 配置。因此,你的nginx.conf中必须存在一个明确的、监听 443 端口的server块,且该块内不能已有ssl_certificate相关指令(否则插件会拒绝写入)。
在C:\nginx\conf\nginx.conf的http { ... }块内,添加如下最小化 server 块:
server { listen 443 ssl http2; server_name your-domain.com; # ← 替换为你的实际域名 # win-acme 将自动在此处插入 ssl_certificate 和 ssl_certificate_key 行 # 请勿手动添加,否则插件会跳过 location / { root html; index index.html index.htm; } }逻辑说明:
listen 443 ssl http2:声明这是一个 HTTPS server,win-acme 识别此标记后才介入server_name必须与你要申请的域名完全一致(支持通配符*.example.com,但需 DNS 验证)- 注释行
# win-acme 将自动在此处插入...是给自己的提醒,插件不读注释,但能防止误操作
保存后,用C:\nginx\nginx.exe -t测试语法是否正确。若报错unknown directive "ssl",说明 nginx 编译时未启用 SSL 模块——需重新下载带 OpenSSL 的官方 Windows 版本(推荐 nginx.org 官方二进制 )。
3.3 首次申请证书:交互式向导 + 关键选项选择
现在运行完整申请命令:
.\wacs.exe --plugin nginx ` --nginxconfig "C:\nginx\conf\nginx.conf" ` --nginxreload "C:\nginx\nginx.exe -s reload" ` --accepttos ` --email you@example.com ` --host your-domain.com ` --validation http-01参数详解:
--accepttos:自动接受 Let’s Encrypt 服务条款(必加,否则卡在交互)--host:要签发的域名(可多个,用逗号分隔:--host a.com,b.com,*.a.com)--validation http-01:使用 HTTP 验证(最简单,需 80 端口开放);若 80 被占用,改用--validation tls-alpn-01(需 443 端口空闲)
执行后,你会看到交互式菜单:
- 选择「M」Manual input(手动输入域名)→ 输入
your-domain.com - 选择「N」None of the above(因我们已预置 server 块,不选 IIS 或其他)
- 选择「S」Store in certificate store(存 Windows 证书存储,便于后续导出)
- 选择「O」OK, run the selected steps(确认执行)
成功后,控制台会显示:
[INFO] Authorize identifier: your-domain.com [INFO] Authorizing by http-01 [INFO] Answer should now be available at http://your-domain.com/.well-known/acme-challenge/... [INFO] Ready for challenge validation... [INFO] Authorization result: valid [INFO] Requesting certificate... [INFO] Certificate created successfully [INFO] Updating nginx configuration... [INFO] Reloading nginx... [INFO] Next renewal due at 2024-10-25 08:12:34Z此时打开C:\nginx\conf\nginx.conf,你会看到 win-acme 已在对应server块中插入两行:
ssl_certificate "C:\win-acme\https_acme-v02.api.letsencrypt.org-directory\your-domain.com\fullchain.pfx"; ssl_certificate_key "C:\win-acme\https_acme-v02.api.letsencrypt.org-directory\your-domain.com\private.key";注意:路径是 win-acme 内部生成的 PFX 格式证书(含证书链+私钥),nginx 原生支持,无需转换。
4. 常见问题排查:那些让你重启三次还找不到原因的坑
win-acme 在 Windows 上的报错往往藏得很深:日志不报错、界面不弹窗、nginx 不报错但 https 打不开。以下是我在某跨平台系统部署中踩出的 4 个高频真坑,每一条都附带现场诊断命令和一招毙命的解法。
4.1 现象:wacs.exe --test显示IIS: Not installed,但你根本没装 IIS
原因:win-acme 的--test命令会扫描注册表项HKLM:\SOFTWARE\Microsoft\InetStp,若该键不存在,就判定 IIS 未安装。但某些 Windows Server 安装镜像(如 Nano Server 或最小化安装)默认不写此键,即使你没装 IIS,也不影响 nginx 使用。
解决:忽略此提示,直接运行带--plugin nginx的命令。只要--nginxconfig和--nginxreload参数正确,IIS 检测失败不影响 nginx 绑定。验证方式:
# 查看 win-acme 是否真的调用了 nginx reload Get-Content C:\win-acme\logs\wacs.log -Tail 20 | Select-String "Reloading nginx"若日志中有该行,说明 nginx 插件已生效。
4.2 现象:申请成功,但浏览器访问 https 报ERR_SSL_PROTOCOL_ERROR
原因:nginx 配置中ssl_certificate指向的是.pfx文件,但 nginx 要求.pfx必须是PKCS#12 格式且密码为空。win-acme v2.2.9.1701 默认导出的 PFX 是无密码的,但若你之前手动用openssl转换过证书,可能引入了密码保护。
解决:检查 PFX 是否有密码:
# 在 PowerShell 中尝试用 openssl 读取(需提前安装 OpenSSL for Windows) & "C:\OpenSSL-Win64\bin\openssl.exe" pkcs12 -info -in "C:\win-acme\...\fullchain.pfx" -nodes若提示Enter Import Password:,说明有密码。立即用 win-acme 重新申请,并加参数强制无密码:
.\wacs.exe --plugin nginx ... --pfxpassword "" --storepfx--pfxpassword ""显式指定空密码,--storepfx确保生成 PFX(默认只生成 PEM)。
4.3 现象:续期失败,日志报The process cannot access the file because it is being used by another process
原因:win-acme 续期时会尝试覆盖private.key和fullchain.pfx,但 nginx 进程可能持有这些文件句柄(尤其在 Windows 上,文件锁比 Linux 更顽固)。
解决:修改 win-acme 的续期策略,改为「先停 nginx,再更新,再启 nginx」:
- 创建批处理
C:\win-acme\renew-nginx.bat:@echo off net stop nginx >nul 2>&1 timeout /t 2 /nobreak >nul "C:\win-acme\wacs.exe" --renew --force timeout /t 1 /nobreak >nul net start nginx >nul 2>&1 - 在 win-acme 的任务计划中,将触发命令改为调用此 bat 文件(而非直接调用
wacs.exe --renew)。
4.4 现象:--validation tls-alpn-01一直卡在Waiting for challenge validation...
原因:TLS-ALPN-01 验证要求 443 端口完全空闲,且 nginx 不能监听 443(否则 ALPN 协商被 nginx 拦截)。但 win-acme 的 nginx 插件在验证阶段不会自动停 nginx,它假设你用的是独立验证端口。
解决:放弃 TLS-ALPN-01,改用 HTTP-01(更可靠)。若 80 端口真被占,用端口转发:
# 将 80 端口流量临时转发到 win-acme 的内置验证服务器(监听 5002) netsh interface portproxy add v4tov4 listenport=80 listenaddress=0.0.0.0 connectport=5002 connectaddress=127.0.0.1 protocol=tcp然后申请时加--validation http-01 --validationport 5002。验证完立即删掉转发:
netsh interface portproxy delete v4tov4 listenport=805. 证书续期与服务化:从手动运行到开机自启的全自动闭环
申请一次证书只是开始,Let’s Encrypt 证书 90 天过期,必须建立可靠的续期机制。win-acme 提供两种方式:手动定时任务(适合测试)和 Windows 服务(生产推荐)。但直接--schedule会失败——因为服务账户无权读取用户证书存储。
5.1 方案一:Windows 任务计划(简单可靠,推荐新手)
win-acme 内置--schedule参数,会自动创建一个每日凌晨 3 点运行的计划任务:
.\wacs.exe --schedule "03:00"它会在「任务计划程序库」中创建任务win-acme,触发器为「每天 3:00」,操作为:
程序:C:\win-acme\wacs.exe 参数:--renew --force --verbose 起始于:C:\win-acme关键设置(必须手动检查):
- 右键任务 → 「属性」→ 「常规」选项卡 → 勾选「不管用户是否登录都要运行」
- 取消勾选「只在用户登录时运行」
- 「配置」选项卡 → 选择Windows Server 2012 R2 或更高版本
- 「条件」选项卡 → 取消勾选「只有在计算机使用交流电源时才启动此任务」(服务器通常不用电池)
验证是否生效:
# 手动触发一次续期(模拟任务运行) .\wacs.exe --renew --force --verbose # 查看日志最后 10 行 Get-Content C:\win-acme\logs\wacs.log -Tail 10若看到Renewal completed且时间戳是当前时间,说明任务配置正确。
5.2 方案二:Windows 服务(生产环境首选,但需权限配置)
--service参数会将 win-acme 安装为 Windows 服务,但默认以LocalSystem账户运行,无法访问当前用户的证书存储(CurrentUser\My)。必须改为以当前用户身份运行:
# 先卸载旧服务(如有) .\wacs.exe --uninstall-service # 以当前用户安装服务(注意:必须在用户登录状态下执行) .\wacs.exe --install-service --servicename "win-acme-renewer" --username ".\当前用户名" --password "当前用户密码"参数说明:
--servicename:自定义服务名,避免与旧服务冲突--username:格式为.\用户名(本地用户)或DOMAIN\用户名(域用户)--password:明文密码(Windows 服务机制要求)
安装后,在「服务」管理器中找到win-acme-renewer,右键 → 「属性」→ 「登录」选项卡 → 确认「此账户」显示为你指定的用户。启动服务,观察日志:
# 查看服务状态 Get-Service "win-acme-renewer" | Select-Object Status, Name, DisplayName # 查看服务日志(win-acme 会写入 Windows 事件日志) Get-WinEvent -FilterHashtable @{LogName='Application'; ID=100} -MaxEvents 5 | Format-List事件 ID 100 表示续期成功。
5.3 续期失败的兜底监控:用 PowerShell 脚本自动告警
再稳的服务也有翻车时。我在某图像处理 Demo 部署中加了一段每日检查脚本,放在C:\win-acme\check-cert.ps1:
# 获取 win-acme 最新证书的到期时间 $certPath = Get-ChildItem "C:\win-acme\https_acme-v02.api.letsencrypt.org-directory\*" -Recurse -Include "fullchain.pfx" | Sort-Object LastWriteTime -Descending | Select-Object -First 1 if ($certPath) { $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $cert.Import($certPath.FullName, "", "PersistKeySet") $daysLeft = ($cert.NotAfter - (Get-Date)).Days if ($daysLeft -lt 15) { # 发邮件或写入事件日志 Write-EventLog -LogName Application -Source "win-acme" -EntryType Warning -EventId 101 -Message "SSL certificate expires in $daysLeft days!" } }然后在任务计划中每日运行此脚本。当证书剩余不足 15 天,就会在事件查看器中留下警告,比等用户投诉快得多。
6. 验证与调试:用三步法确认 HTTPS 真正跑通,而不是“看起来可以”
装完不验证,等于没装。很多开发者看到浏览器地址栏有小锁就以为成功,结果 API 调用时curl报SSL certificate problem: unable to get local issuer certificate,或者移动端白屏——这是因为证书链不全、OCSP Stapling 未启用、HSTS 未配置。下面这套验证流程,是我从某公司线上事故中提炼出的「三步穿透法」,每一步都对应一个真实故障场景。
6.1 第一步:用 curl 检查证书链与协议支持(绕过浏览器缓存)
在服务器本地(或另一台干净机器)执行:
curl -Ivk https://your-domain.com重点看三处:
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384→ 确认使用 TLS 1.2 或 1.3(TLS 1.0/1.1 已淘汰)* subject: CN=your-domain.com→ 确认 Subject 正确* issuer: CN=R3, O=Let's Encrypt, C=US→ 确认 Issuer 是 Let’s Encrypt 的 R3 根(不是过期的 DST Root X3)
若issuer显示DST Root X3,说明证书链不全。win-acme 默认导出fullchain.pfx,但 nginx 有时只读取了证书部分。解决方案:
# 在 server 块中,显式指定证书链文件(而非只用 fullchain.pfx) ssl_certificate "C:\win-acme\...\cert.pem"; # 仅证书 ssl_certificate_key "C:\win-acme\...\private.key"; # 私钥 ssl_trusted_certificate "C:\win-acme\...\chain.pem"; # 仅中间证书(R3)cert.pem和chain.pem可从 win-acme 的archive目录中提取(路径形如C:\win-acme\archive\your-domain.com\1\cert.pem)。
6.2 第二步:用 SSL Labs 测试(暴露 OCSP/HSTS/密钥交换缺陷)
访问 https://www.ssllabs.com/ssltest/ ,输入你的域名,点击「Submit」。等待 1-2 分钟,查看报告:
- Certificate #1:应显示
Trusted,Valid,SHA256withRSA - Protocol Details:
TLS 1.3应为Yes,TLS 1.0/1.1应为No - Key Exchange:
ECDHE应为Yes(确保前向保密) - HTTP Security:
HSTS应为Yes(若未启用,在 nginx server 块中加add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;)
若报告中出现Chain issues: Incomplete,回到 win-acme 目录,检查settings.json中"UseStaging": false(必须为 false,否则用测试根证书)。
6.3 第三步:用 OpenSSL 检查 OCSP Stapling(移动端和企业网络的关键)
很多企业防火墙或 iOS 设备会严格校验 OCSP 响应。若未启用,会出现「证书吊销状态未知」错误:
openssl s_client -connect your-domain.com:443 -status -servername your-domain.com 2>&1 | grep -A 17 "OCSP response"若输出中OCSP Response Status: successful (0x0)且Response Type: Basic OCSP Response,说明正常。若显示no response sent,需在 nginx 中启用:
ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 1.1.1.1 valid=300s; resolver_timeout 5s;注意:
resolver必须是公网 DNS(如 8.8.8.8),不能用127.0.0.1(本地 DNS 服务可能不支持 OCSP 查询)。
从那以后我每次部署新环境,都强制走一遍这三步:curl 看链、SSL Labs 看配置、OpenSSL 看 OCSP。少走一步,就可能在某个凌晨三点被电话叫醒,听客户说「你们的 API 所有手机都打不开」。希望帮到你。
本文还有配套的精品资源,点击获取