ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

win-acme:Windows平台免费SSL证书申请与自动续期指南

win-acme:Windows平台免费SSL证书申请与自动续期指南

简介:这是一款面向Windows 64位系统的免费SSL证书自动化管理工具,基于ACME协议实现,帮助个人用户、自由开发者与小规模站点快速获取、安装并自动续期Let's Encrypt免费证书,是为网站启用HTTPS并降低安全成本的上佳选择。资源包共27个文件,压缩后约29.58MB,其中包含15个PowerShell脚本、4个动态链接库、2个JSON配置、2个批处理脚本及可执行程序等,兼顾图形界面交互与命令行自动化,也便于脚本化集成。目前已有333人学习下载。使用该资源可系统掌握域名所有权验证、证书申请与Web服务器安装、90天周期自动续订、多域名通配符管理以及日志查看等完整流程;包内脚本与配置文件组织清晰,读者既能直接运行体验,也可按需修改后接入自有运维体系,适合希望深入理解ACME工作方式并落地免费HTTPS方案的开发者。

1. 从“免费域名”到免费证书:win-acme 的真正用途

搜索引擎里挂着“免费域名”关键词找到 win-acme 的人,十个里有九个最后都明白了——这工具申请的不是域名,而是免费 SSL 证书。域名得你自己注册、自己解析,win-acme 做的是:在 Windows 平台上,通过 ACME 协议自动向公共证书签发服务申请、验证、安装、续期 HTTPS 证书。它把这套原本要在 Linux 上靠命令行折腾的流程,完整搬到了 Windows 的图形界面和命令行里。适合 IIS 用户、局域网与公网并存的混合环境、个人站点、以及所有不想手动粘贴 CSR 和密钥文件的人。下文按“原理 → 落地 → 踩坑 → 进阶”的顺序展开。

2. win-acme 的定位与选型:为什么 Windows 平台选它而不是手动填 CSR

2.1 先弄懂 ACME 协议与两种验证方式

ACME 是“自动证书管理环境”协议,核心逻辑就是让客户端向证书签发服务证明“我确实拥有这个域名”,证明通过后服务把证书签发给你。完整流程分三步:客户端生成密钥对,包括公钥和私钥;然后通过 HTTP-01 或 DNS-01 提交域名验证;验证通过后换取正式签发的证书。这个设计把原先“人工向 CA 提交信息、等待审核、下载证书”的过程压缩成了机器之间自动完成的协议交互。

每一种验证方式都有明确的适用边界。HTTP-01 是最常见的:签发服务给你一个随机 token,你需要把它放到域名对应站点目录.well-known/acme-challenge/下面,服务再访问http://你的域名/.well-known/acme-challenge/随机串来确认。这种方式要求 80 端口可达,且你对该目录有写权限,门槛低、使用率高。DNS-01 则是把验证信息放在 DNS 记录里:你要去 DNS 管理后台添加一条_acme-challenge.example.com的 TXT 记录,内容由签发服务指定,服务查到这条记录且值匹配就算验证通过。DNS-01 不依赖 HTTP 端口和 Web 服务器,且天然支持通配符证书。

如果你只需要给example.com和www.example.com两张证书,HTTP-01 足够;但如果你希望一张证书同时覆盖example.com、.example.com以及十几个子域,就得用 DNS-01 签通配符。两种方式 win-acme 都支持,这也是我在 Windows 上选它的重要理由——早期用过的几个图形化 ACME 客户端要么只支持 HTTP-01,要么把 DNS-01 做成一堆没人维护的半成品插件。

2.2 为什么在 Windows 上不用 certbot 而用 win-acme

很多人问过这个问题:既然 certbot 名气更大,直接用 certbot 不就行了?答案是 certbot 在 Windows 上确实能跑,但它的主场是 Linux,systemd 定时器、Nginx、Apache 插件在 Windows 上要么用不上要么半残。你要么装 WSL 包一层,要么手动写注册表定时任务,IIS 集成更是接近没有。win-acme 是真正为 Windows 场景设计的 ACME 客户端:交互界面和命令行并存,对 IIS 原生支持,续期任务挂在 Windows 计划任务里,绑定更新在 Web 服务器这一层做掉了。这种“省掉所有手工步骤”的取向,才是 Windows 管理员真正需要的体验。

具体和手动申请对比,三步就能看出差距。第一,证书服务商后台手动粘贴 CSR 那一步——你打开管理后台、生成私钥、复制粘贴 CSR、等审核邮件——在 win-acme 里压缩成“输入域名,回车”。第二,证书部署到哪台服务器、哪个 IIS 站点、绑定哪些域名,向导会一项项确认,而不是把 PEM 文件丢给你自己处理。第三,续期这件事彻底从人脑里挪走了:它默认创建一个每天运行一次的计划任务,证书剩余天数低于 20 天时自动续期。我从第一次用 win-acme 到现在,经手维护的 Windows 站点证书全部由它托管,没有一次半夜爬起来处理过过期证书。

不过也有一点要提前说明:win-acme 解决的是证书申请与部署,不解决域名来源。你想上 HTTPS,得先有一个能正常解析到服务器的域名,再谈证书自动化的价值。

2.3 版本选择 v2.1.18 的几个细节

我这次用的是 v2.1.18-x64,2.x 系列与 1.x 系列差异不小。2.x 把配置拆成独立的 JSON 文件,每个托管域名一个,放在 win-acme 目录下的config文件夹里,直接改配置比在界面上逐项点更可控。同时引入了--installation参数,把“申请证书”和“安装到 Web 服务器”解耦,这为批量脚本化创造了条件。1.x 是单文件集中配置,升级到 2.x 后旧配置不会自动迁移,如果你之前用 1.x,直接换 2.x 需要重新注册域名列表,不要尝试把旧配置硬复制过去,否则申请时会出现 “bindings not found” 一类的报错。

提示:win-acme 本质是命令行工具,交互界面只是它的操作外壳。你在界面上点击的每一个动作,最终都会映射成命令行参数,这一点理解得越早,后面做自动化越顺利。

3. 安装与首次申请:拿到一张免费证书的完整路径

3.1 安装前要确认的四个前置条件

先把 win-acme v2.1.18-x64 的压缩包解压到固定目录,我习惯放在C:\win-acme,不放 Program Files 是因为后续计划任务要引用完整路径,目录名带空格会让命令行脚本多一层引号处理。然后逐项确认前置条件:

第一,目标域名的 A 记录或 CNAME 已经解析到本机公网 IP,并且 HTTP 访问能通。如果域名还挂在内网或者指向别处,后面验证必然失败。第二,Windows 防火墙放行 80 和 443。80 是 HTTP-01 验证时公共签发服务访问你的路径,443 是证书部署后客户端访问的入口,两个端口都不能被挡。第三,安装 .NET Framework 4.7.2 以上运行时,win-acme 编译目标就在这里,缺少依赖会直接闪退或在日志里报找不到 DLL。第四,网站根目录对 win-acme 的运行身份可写,验证时要往里写.well-known临时文件;如果站点目录权限设得很死,申请会在最后一步失败。

3.2 用交互界面完成首次申请

解压后直接双击wacs.exe,程序会自动检测 IIS 状态和 80/443 端口占用情况。主菜单里选 “Create certificate (default)”,然后输入域名。这里有个容易忽略的输入规则:多个域名用英文逗号分隔,第一个会被当作主域名,后续证书信息、文件命名都以它为准。比如我维护某个模拟项目 X 的站点时输入的是example.com,www.example.com,申请到的证书会同时覆盖这两个域名。

之后进入验证方式选择。IIS 里已有对应站点时,选 HTTP-01 并指向 webroot 路径;没有现成站点或者端口被别的 Web 服务器占用时,选 “Self-host” 模式,让 win-acme 自己起一个临时 HTTP 响应服务,专门响应验证请求。验证通过后,再选择是否创建 IIS HTTPS 绑定。下面这条命令是我在这台机器上实际执行过的等价命令行流程:

# 在 wacs.exe 所在目录执行,用 webroot 方式完成 HTTP-01 验证 wacs.exe --create --host example.com,www.example.com --validation http --webroot C:\inetpub\wwwroot\example

各段参数含义:--create表示发起新证书申请;--host后跟域名列表,逗号分隔,第一项是主域名;--validation http指定 HTTP-01 验证方式;--webroot指向验证临时文件的写入目录。执行后 win-acme 会在C:\inetpub\wwwroot\example\.well-known\acme-challenge\下生成随机文件,公共证书服务通过访问该路径完成确认。如果你切换到--validation manual,则是 DNS-01 手动模式,后面第 4 章细讲。

3.3 证书生成后的文件都落在了哪里

申请成功后,证书文件默认输出到 win-acme 安装目录下的certs文件夹,按域名分目录组织,比如certs\example.com\。里面主要文件包括带完整证书链的example.com-chain.pfx、PEM 格式的证书本体example.com-crt.pem、私钥example.com-key.pem,以及 IIS 绑定直接可用的example.com.pfx。pfx 的导入密码 win-acme 会自动生成随机密码并写入同目录下的.pfx-password.txt,导入 IIS 时记得先打开这个文件读密码。

我整理了一个文件对应表,方便你结合自己的部署场景看:

文件内容推荐使用场景
example.com-chain.pfx完整证书链(含中间证书)云负载均衡、Nginx 反向代理导入
example.com-crt.pem证书公开部分Nginx/Apache 手动配置
example.com-key.pem私钥需要证书私钥分开存放的场景
example.com.pfx主证书+私钥打包IIS 绑定直接导入
.pfx-password.txtpfx 的导出密码IIS 导入时读取

首次跑通之后,切到 IIS 管理器检查对应站点,应该能看到新增的 https 绑定。浏览器访问https://example.com,地址栏不会再报证书无效,说明证书链和站点绑定都已经正常。到这里,你已经跑完了整条链路中最核心的一段——从申请到上线。

4. 把验证跑通:HTTP-01 与 DNS-01 两种场景的配置细节

4.1 HTTP-01 场景:IIS 站点与独立 Web 服务器的差异

HTTP-01 验证模式里有个选型误区:很多人以为只要 IIS 里站点的物理路径在,验证就一定通过。实际上,win-acme 的 webroot 参数指向的目录必须是可写的物理目录,而不是 IIS 默认站点的只读目录。尤其需要注意 IIS 的“请求筛选”功能,默认规则可能拦截带点分段的路径,.well-known这个目录直接就夹在中间。验证文件明明写进去了,但公共签发服务访问时被返回 404,日志里留一串失败记录。

解决方式有两种:一是在 IIS 管理器的“请求筛选—URL 规则”里加一条允许规则,放行.well-known/acme-challenge/;二是更彻底的办法,把验证目录单独建一个站点或应用池,webroot 指向它,和主业务站点的复杂规则完全隔离。后面这种方式我在一台跑了多套老系统的服务器上用过,效果很干净,不会牵动其他站点的请求规则。

Nginx 和 Apache 场景同理,只是换了个配置文件的位置。Nginx 需要确认站点配置里有这样的块,并且根目录对运行用户可写:

location ^~ /.well-known/acme-challenge/ { allow all; root /var/www/html; default_type "text/plain"; }

这里default_type很重要。ACME 验证请求不要求特定 Content-Type,但某些 Nginx 版本会默认对未知类型返回错误,显式声明成文本类型能减少不必要的 404。Apache 则要确认AllowOverride没有锁掉.well-known目录的访问规则。win-acme 也提供了一种 “internal” 验证方式,自己不依赖任何 Web 服务器,临时监听 80 端口响应请求。当你的 IIS 端口被大量占用,或者 80 端口由别的软件接管时,这种方式是绕开站点配置问题的最优解,前提是防火墙放行了 80 端口。

4.2 DNS-01 场景:通配符证书与手动验证路径

需要给一个域名下所有子域名统一上 HTTPS 时,HTTP-01 要逐个申请再合并,效率极低。DNS-01 模式可以一次签发*.example.com覆盖所有子域,这也是它的核心价值。具体操作是:创建向导里选择--validation manual,win-acme 会生成一条 TXT 记录要求,形如_acme-challenge.example.com TXT "随机值"。你到 DNS 服务商后台添加这条记录,添加完成后回到向导按回车确认。签发服务随即去查询这条记录,匹配上之后签发通配符证书。

在 v2.1.18 里,DNS-01 除了 manual 半自动模式,还有两个实用选项。第一个是--dnstestmode,它只校验 DNS 记录的配置是否正确,不实际发起签发操作,适合在正式申请前做检查,避免因为记录没生效浪费申请额度。第二个是把 DNS 操作脚本化——如果你的 DNS 服务商提供 API,可以把添加记录、等待生效、按回车确认、签发成功后删除记录这几步写进脚本,做到全程无人值守。通配符证书签发成功后,证书文件命名会变为*_example.com一类,IIS 绑定的域名栏填*.example.com即可全覆盖。

4.3 常用命令行参数:把界面操作翻译成脚本

win-acme 的命令行参数体系是 2.x 版本最值得花时间的部分。界面再直观,仍然是一次性操作;只有命令行参数才能进入脚本和计划任务。下面这三条是我在不同场景下实际用过的组合:

# 1. 静默创建证书,验证成功后不打开界面,适合脚本调用 wacs.exe --create --host example.com --validation http --webroot C:\web\example --certificatestore default --quiet # 2. 批量续期所有托管证书,静默执行 wacs.exe --renew --all --quiet # 3. 只检查当前托管配置和证书状态,不执行任何变更 wacs.exe --list --staging

--quiet让所有输出只写入日志文件,不弹窗,避免计划任务执行时卡在交互提示上;--certificatestore default指定证书同时存入系统证书库,之后 IIS 绑定可以直接从证书库中选择而不用手动导入 pfx;--staging切换到测试环境,所有验证和签发都走测试证书,不消耗正式签发的额度;--renew --all表示一次性检查所有站点的续期情况。

界面操作和命令行参数的映射关系,我整理成了下表,方便你把已经会点的界面动作翻译成脚本:

界面操作位置等价命令行参数常见取值
域名输入框--hostexample.com,www.example.com
验证方式选择--validationhttp/dns/manual
网站根目录--webroot物理路径,如C:\inetpub\wwwroot
证书存储位置--certificatestoredefault或自定义名称
创建后绑定 IIS--installationiis/none
静默运行--quiet无值参数,出现即生效

5. 避坑指南:证书申请失败的典型原因与排查路径

5.1 现象:验证请求超时,错误日志出现 408 或连接重置

HTTP-01 验证模式最常见的报错是公共签发服务访问不到验证路径。先打开 win-acme 安装目录下的.log日志文件,如果看到 “connection timed out” 或 408,基本可以锁定是域名解析问题。域名可能解析到了内网 IP,或者指向了另一台服务器,外网服务访问你的域名时找不到正确地址。

排查路径是:先在另一台网络环境独立的机器上 ping 一下域名,看返回的 IP;再用在线 DNS 查询工具确认公网解析结果;最后检查云服务商的安全组规则。我之前在一台云服务器上排查了一个多小时,最后发现安全组只放行了 443,80 端口从没开过,HTTP-01 验证当然一直超时。

5.2 现象:证书申请成功但 IIS 绑定不生效

证书已经出现在certs目录里,IIS 管理器里对应站点却没有更新 https 绑定,这种问题也不少。大概率是创建向导里安装那一步选了“手动”——win-acme 认为你自己会去挂载,它只把证书放进了证书库,没有动 IIS 绑定。

解决方式是:创建向导最后一步明确选择 “Create/update IIS bindings” 再执行;已经申请完的可以用--installation iis参数补一次绑定。另一种模仿现象是多域名组合证书,但 IIS 站点只绑定了主域名,访问时浏览器还是显示旧证书。这种情况要去 IIS 绑定的编辑界面,把域名列表改成和证书覆盖范围完全一致,再重启站点生效。

5.3 现象:通配符证书始终签不下来

通配符证书的申请失败大概率出在 DNS 记录环节。常见错误是:在 DNS 服务商后台添加_acme-challenge记录时,服务商自动补全了域名后缀,记录名变成_acme-challenge.example.com.example.com,TXT 查询自然匹配不上。

确认方法是用nslookup -type=TXT _acme-challenge.example.com检查,返回的应该是记录值完全匹配的一条 TXT 条目。另一个隐蔽的坑是--dnstestmode模式没关掉:这个模式只校验记录不发起签发,如果你一直开着它,就会一直拿不到正式证书,日志里也根本不会出现签发请求记录。

5.4 现象:续期任务失效,证书到期才被发现

这是我踩得最多的一种情况。win-acme 默认创建的续期计划任务运行身份是 SYSTEM,正常情况下每 24 小时自动检查一次,到期前自动续。但如果你移动过安装目录、计划任务被清理软件禁用、或者服务器安全策略锁定过计划任务的运行,续期就会悄悄停掉。

我的处理习惯是:每次部署完 win-acme,立刻手动运行一次计划任务,确认日志里出现续期成功或“暂无需要续期”的记录,才认为续期链路真正通了。另一个隐蔽因素是certs目录如果被同步盘或备份软件锁住文件,计划任务写新密钥时会失败,日志里会看到文件写入被拒绝。检查计划任务时一定要连这层一起看。

5.5 现象:申请额度被耗尽

公共 ACME 证书服务对同一域名的签发频率有限制,调试期如果频繁执行--create又删除证书,很容易触发限流报错。解决思路是把调试和正式分开:一切验证都先在--staging模式下跑通,再切回正式环境一次性完成申请。这样额度消耗几乎可以忽略。如果短期额度真的用完了,不要想绕开限制的花招,等待限流窗口过去即可,通常不会太久。

注意:--staging签出的是测试证书,浏览器和移动端都不信任。如果忘记去掉这个参数,你会拿到“证书已生效但访问者全部报错”的尴尬结果。

6. 进阶:命令行全自动续期与多站点批量签发

把流程固化成一条命令,是 win-acme 真正释放效率的地方。我平时维护的服务器上只放一个批处理文件,内容很短:

@echo off cd /d C:\win-acme wacs.exe --renew --all --quiet --installation iis

这段脚本的含义是:切到安装目录、静默检查所有托管站点的续期情况、需要续期的自动续期并同步 IIS 绑定。配合计划任务每天早上 8 点执行一次,所有站点的证书生命周期就和你脱开关系了。多站点场景里,你还可以加--host参数指定范围,比如只续期某台服务器上的核心业务域名,其他非敏感域名不纳入自动续期。

对于覆盖站点特别多的场景,建议再带一个--smear参数,它会让续期检查在一天内随机分散开,避免所有证书集中在一个时间点向签发服务发起请求,降低被限流的概率。

验证自动化是否真的在工作,方法要比部署本身更严谨。我的每月例行检查是手动跑一次上面的renew_all.bat,然后打开日志看最后几行是否出现 “renewal succeeded”;再去浏览器无痕窗口访问几个站点,确认证书链有效。快速查看所有证书剩余天数可以用这条命令:

wacs.exe --list --formatted

输出里会直接列出每个证书的到期日期,比逐个站点开浏览器检查快得多。有一次正是靠这个列表发现某套证书剩余天数只有 12 天,而计划任务日志显示上次运行已经是 20 天前——中间被安全策略悄悄锁掉了。从那以后,我每次部署完 win-acme 都会强制走一遍“申请 → 续期 → 检查 → 记录”四步流程,全部跑通才把站点交给业务。这个习惯帮我避免了好几次证书静默过期的夜间救火,希望这些细节也能让你的证书管理少一些突发状况,多一些确定性。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进