免费SSL证书多域名申请acme.sh完整脚本
如果你手上有多个域名需要部署 HTTPS,又不想花钱买证书,acme.sh 是目前比较省心的免费方案。
它支持 Let's Encrypt、ZeroSSL 等 CA,能自动完成域名验证和续期,而且一个脚本就能把多个域名写进同一张证书。
下面按零基础也能跟做的节奏,从安装到验证一步步来。
准备工作:域名解析和服务器环境
开始之前,先把要签发的域名都解析到当前服务器 IP。
acme.sh 支持两种验证方式:HTTP 文件验证和 DNS 验证。
如果你申请的是通配符证书,或者域名没法绑到同一台机器,就得用 DNS 验证。
服务器上需要具备:
- 能访问外网的 Linux 环境,常见发行版均可
- 当前用户有 sudo 权限,或直接用 root 操作
- 如果走 HTTP 验证,80 端口要能被外网访问
- 如果走 DNS 验证,需要拿到 DNS 服务商的 API 密钥
关键判断:只有主域名和具体子域名需要证书,且服务器能临时开放 80 端口,优先用 HTTP 验证;
需要通配符或多台服务器共用证书,用 DNS 验证更灵活。
安装 acme.sh 并配置默认 CA
acme.sh 的安装脚本会把它装到用户目录下,不会污染系统包管理器。
执行下面这条命令:
curl https://get.acme.sh | sh -s email=你的邮箱@example.com
安装完成后,重新加载一下 shell 配置,让 acme.sh 命令生效:
source ~/.bashrc
默认情况下,acme.sh 使用 ZeroSSL 作为 CA。
如果你想换回 Let's Encrypt,可以执行:
acme.sh --set-default-ca --server letsencrypt
建议在申请前先确认当前 CA 设置,避免验证方式不匹配导致失败。
用 DNS 验证申请多域名证书
下面以 DNS 手动验证为例,展示如何把多个域名写进同一张证书。
假设要签发的域名是 example.com、www.example.com 和 api.example.com。
第一步,发起申请并进入手动 DNS 验证模式:
acme.sh --issue --dns -d example.com -d www.example.com -d api.example.com --yes-I-know-dns-manual-mode-enough-go-ahead-please
执行后,脚本会输出类似下面的提示,要求你添加 TXT 记录:
Domain: '_acme-challenge.example.com'
TXT value: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
你需要登录域名 DNS 管理后台,为每个域名添加对应的 TXT 记录。
全部添加完成后,等待 DNS 生效,再执行续期命令让 acme.sh 去验证:
acme.sh --renew -d example.com -d www.example.com -d api.example.com --yes-I-know-dns-manual-mode-enough-go-ahead-please
验证通过后,证书文件会保存在 ~/.acme.sh/example.com/ 目录下。
提醒:手动 DNS 模式每次续期都需要重新添加 TXT 记录,不适合长期自动续期。
如果 DNS 服务商提供 API,建议改用 --dns dns_ali、--dns dns_cf 等自动模式。
安装证书并配置 Nginx
证书签发后,不要直接引用 ~/.acme.sh/ 下的文件,而是用 --install-cert 把证书复制到指定位置,并设置重载命令:
acme.sh --install-cert -d example.com \
--key-file /etc/nginx/ssl/example.com.key \
--fullchain-file /etc/nginx/ssl/example.com.pem \
--reloadcmd "nginx -s reload"
然后在 Nginx 配置中引用这两个文件:
server {
listen 443 ssl;
server_name example.com www.example.com api.example.com;
ssl_certificate /etc/nginx/ssl/example.com.pem;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
# 其他配置...
}
保存后执行 nginx -t 检查语法,再 nginx -s reload 重载。
避坑指南:常见报错和处理方式
DNS 验证一直失败:先确认 TXT 记录是否已生效,可以用 dig txt _acme-challenge.example.com 查看。
如果记录值不对或还没传播,等待几分钟再试。
80 端口被占用导致 HTTP 验证失败:acme.sh 的 HTTP 验证需要临时监听 80 端口。
如果 Nginx 或 Apache 占用了,可以先停掉,验证完成后再启动。
证书续期后 Nginx 没加载新证书:检查 --install-cert 时的 --reloadcmd 是否写对。
可以手动执行一次 acme.sh --cron 看输出,确认续期任务是否正常。
通配符证书申请失败:通配符必须用 DNS 验证,且需要 DNS 服务商的 API 密钥。
以 Cloudflare 为例,先导出 CF_Token 环境变量,再用 acme.sh --issue --dns dns_cf -d example.com -d '*.example.com' 申请。
验证证书是否生效
证书安装后,用浏览器打开 https://example.com,点击地址栏锁图标查看证书详情,确认域名列表包含所有签发的域名。
命令行下可以用 openssl 检查:
openssl s_client -connect example.com:443 -servername example.com | openssl x509 -noout -dates -subject -ext subjectAltName
输出中会显示证书有效期和备用名称列表。
如果所有域名都在 subjectAltName 里,说明多域名证书已经生效。
另外,acme.sh 默认会添加一个 cron 任务自动续期,可以用 crontab -l 查看。
证书到期前 30 天左右会自动续期,续期成功后按 --reloadcmd 重载服务。
几个容易搞混的细节
手动 DNS 模式适合临时测试,长期使用建议配置 DNS API 自动验证。
安装证书时指定的路径要提前创建好,并确保 Nginx 进程有读取权限。
如果服务器同时跑多个站点,每个站点单独申请证书更清晰,避免一个证书出问题影响所有域名。
最后,acme.sh 的续期逻辑依赖 cron,如果服务器重启后 cron 服务没启动,续期就会中断。
建议把 acme.sh --cron 加入系统级定时任务,或定期检查证书到期时间。