前阵子帮朋友看他那个小公司的服务器账单,一年两千多的通配符 SSL 证书,续了三年。我说你知不知道这玩意有免费的,他愣了一下:"免费的不是只有 90 天吗,到期了网站不就挂了?"
这种误解太常见。好像"90 天有效期"等于"90 天后手动续命"。其实免费证书跟商业证书最大的区别,不在安不安全、能不能用,而在你有没有把自动续期配好。配好了,它就是永久的。
下面我把 Linux 和 Windows 两套方案一次性写完,都是我自己实际跑过的。

Linux:Nginx + acme.sh
为什么是 acme.sh,不是 Certbot
Let's Encrypt 官方推荐的客户端叫 Certbot,这个谁都知道。早几年我也用,但每次换服务器、换系统版本,Python 依赖就崩一次。后来在 GitHub 上翻到 acme.sh,看了下 Star 数——40K+。再看它的实现,纯 Shell,零依赖。
意思是服务器只要有 bash,它就能跑。不挑系统,不挑环境。而且安装完自动给你加一条 crontab 定时任务,每天零点检查证书到期情况。快过期了?自己续,续完自己重载 Nginx。装上之后真的可以忘了它。
第一步:安装
# 一行命令搞定
curl https://get.acme.sh | sh -s email=你的邮箱地址
就这一行。安装过程会在 home 目录下创建 ~/.acme.sh/,同时自动写入 crontab。你可以看一眼确认下:
crontab -l
应该能看到类似这样一条:
0 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null
有了它,以后证书续期就不用操心了。
国内服务器:访问 GitHub 慢的话,用 Gitee 镜像:
curl https://gitee.com/neilpang/acme.sh/raw/master/acme.sh | sh
第二步:申请证书
两种验证方式。我个人推荐第二种,省事太多。
方式 A:HTTP 验证(需要 80 端口对外开放)
acme.sh --issue -d example.com -d www.example.com -w /你的网站根目录
它会往你的网站根目录放一个临时验证文件,CA 通过 HTTP 访问确认域名是你的,然后签发证书。
方式 B:DNS 验证(推荐,支持通配符,不需要开 80 端口)
内网服务器也能用。通配符证书免费拿,一个 *.example.com 覆盖所有子域名。
以阿里云为例,先去控制台拿 AccessKey:
# 阿里云
export Ali_Key="你的AccessKey"
export Ali_Secret="你的AccessSecret"
acme.sh --issue -d example.com -d '*.example.com' --dns dns_ali
腾讯云 DNSPod 改一下变量名:
# 腾讯云 DNSPod
export DP_Id="你的ID"
export DP_Key="你的Key"
acme.sh --issue -d example.com -d '*.example.com' --dns dns_dp
Cloudflare、华为云、Namecheap、GoDaddy 都支持,acme.sh 内置了几十家 DNS 服务商的 API,具体名字去官方 Wiki 查就行。
第三步:装到 Nginx
证书生成后会放在 ~/.acme.sh/example.com/ 下面,但这个目录最好不要直接在 Nginx 里引用,因为 acme.sh 内部目录结构可能会变。用官方推荐的 install-cert 命令拷到你自己的 ssl 目录:
mkdir -p /etc/nginx/ssl
acme.sh --install-cert -d example.com \
--key-file /etc/nginx/ssl/example.key \
--fullchain-file /etc/nginx/ssl/example.pem \
--reloadcmd "nginx -s reload"
这条命令干了三件事:把证书拷到你指定的目录、记下路径、以及每次续签后自动帮你 nginx -s reload。
Nginx 配置正常写就行:
server {
listen443 ssl http2;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.pem;
ssl_certificate_key /etc/nginx/ssl/example.key;
location / {
proxy_pass http://127.0.0.1:3000;
}
}
配完 reload,浏览器打开看见小锁,这事就算完了。
我踩过的坑
第一个坑是 DNS API 的 key 没设对,跑了三次都报验证失败。后来发现阿里云 AccessKey 的 Secret 复制时多了个空格。建议直接 echo $Ali_Key 确认一下。
第二个坑——换服务器时把旧服务器的 .acme.sh 文件夹直接拷过去,结果续期签名对不上。正确做法是在新服务器上重新装 acme.sh,重新申请。反正一条命令的事。
Windows:Nginx + win-acme(wacs.exe)
Windows 上没有原生 bash 环境,acme.sh 那套 crontab 自动续期的逻辑跑不转。我直接用的 win-acme——专门为 Windows 写的 ACME 客户端,.NET 原生,自带菜单向导,自动续期用 Windows 计划任务实现。
GitHub 地址:github.com/win-acme/win-acme
第一步:下载解压
去上面链接的 Releases 页面,下载最新的 win-acme.v2.x.x.xxx.x64.pluggable.zip,解压到一个固定目录,比如 C:\tools\win-acme。
第二步:运行 wacs.exe
以管理员身份打开 PowerShell,进到解压目录:
cd C:\tools\win-acme
.\wacs.exe
会弹出一个命令行交互菜单。全程就是回答问题,不需要记参数:
- 选证书类型,一般选 1(单个域名)或 2(多个域名含通配符)
- 输入你的域名,比如
example.com、www.example.com - 选择验证方式。HTTP 验证会问你网站根目录,填 Nginx 的 html 路径就行,比如
C:\nginx\html。DNS 验证需要提供 DNS 服务商的 API Key,跟 acme.sh 一个逻辑。 - 选证书存储方式,推荐选 2(PEM 文件存到指定文件夹),后面 Nginx 直接引用。
整个流程五分钟走完。win-acme 会自动生成两个关键文件:example.com-chain.pem 和 example.com-key.pem,存在你指定的目录里。
第三步:配 Nginx
在 nginx.conf 里正常写 HTTPS server 块:
server {
listen443 ssl http2;
server_name example.com;
ssl_certificate C:/tools/win-acme/certs/example.com-chain.pem;
ssl_certificate_key C:/tools/win-acme/certs/example.com-key.pem;
location / {
proxy_pass http://127.0.0.1:3000;
}
}
Windows 下路径用正斜杠 /,Nginx 完全认。配完 nginx -s reload。
第四步:确认自动续期
win-acme 在第一次申请证书时就会自动创建一个 Windows 计划任务,每天运行一次,快到期自动续签。打开"任务计划程序",在"任务计划程序库"里应该能看到一个叫 win-acme renew 的任务。
这跟 Linux 上的 crontab 一样,配好之后你不用再管它。
这套方案跟商业证书比,到底差在哪
我用这套跑了两三年,从个人博客到公司的小项目,没出过问题。咱们客观一点,把账算清楚:
商业证书一年几百到几千块,给你的东西是:有效期长(1-2 年)、有技术支持工单、出了问题有公司可以追责。大企业选商业证书不是因为免费的不能用,是合规和审计需要那张发票。
但对绝大多数个人开发者、小团队、创业公司来说,acme.sh / win-acme + Let's Encrypt 的组合跟商业证书在技术层面没有任何区别。浏览器信任链一样,加密强度一样,通配符支持一样。
唯一所谓的"缺点"是 90 天有效期。自动续期都配好了,这个缺点就不存在了。
最后
acme.sh 在 GitHub 上 40K+ Star,win-acme 也是 Windows 上同类项目里最活跃的一个。这些 Star 不是刷的,是一台服务器一台服务器跑出来的。
如果你还在花钱续 SSL 证书,或者还在手动每三个月更新一次,花十分钟把对应的工具装上就行。省下来的钱,留着吃饭也好。