📋前言

现在的网站和 API 服务基本都需要 HTTPS 支持。

相比以前购买 SSL 证书,Let’s Encrypt 提供了免费的 DV(Domain Validation)证书,并且支持自动续期,非常适合个人项目、小型服务以及中小企业应用。

根据我项目的特点,采用通配符证书(Wildcard Certificate)+ DNS-01 验证的方式。
通配符证书 *.waisaa.com 覆盖所有子域名,加新项目无需重签。
通配符必须用 DNS-01 验证(acme.sh + 阿里云 DNS API)。

本文记录一种比较常见的生产部署方案:

  • Ubuntu 服务器
  • Nginx 使用 Docker 部署
  • Certbot 使用宿主机安装
  • Let’s Encrypt 免费证书
  • Webroot 方式验证域名
  • 自动续期并自动 Reload Nginx

这种架构简单稳定,适合:

  • 个人服务器
  • SaaS 项目
  • 前后端分离应用
  • API 服务
  • 多域名部署

最终实现:

Internet
      │
      ▼
 Let's Encrypt
      │
      │ DNS-01
      ▼
 acme.sh
      │
      │ 调用
      ▼
 阿里云 DNS API
      │
      ▼
 自动添加 TXT
      │
      ▼
 验证成功
      │
      ▼
 /etc/letsencrypt/
      │
      ▼
 Docker Nginx

一、安装 acme.sh

curl https://get.acme.sh | sh -s email=waisaa@qq.com
  • 或重新登录,使别名生效
source ~/.bashrc
  • 安装到 ~/.acme.sh/
  • 自动创建 cron 任务(crontab -l 可见)
  • 默认 CA 是 ZeroSSL,可切回 Let’s Encrypt(见下方说明)
  • 验证
acme.sh --version

在这里插入图片描述
在这里插入图片描述

二、阿里云创建 RAM 子账号

登录 RAM 控制台

1.身份管理 → 用户 → 创建用户

  • 登录名:acme-dns
  • 访问方式:勾选「使用永久 AccessKey 访问」
  • 创建后立即保存 AccessKey IDAccessKey Secret(只显示一次)

在这里插入图片描述
2.授权:选中该用户 → 添加权限 → 搜索并勾选 AliyunDNSFullAccess

不要用主账号 AccessKey,泄露风险高。

在这里插入图片描述

三、配置阿里云 DNS 凭证

acme.sh 的 dns_ali 插件读取环境变量:

export Ali_Key="你的AccessKeyID"
export Ali_Secret="你的AccessKeySecret"
  • 重要:这两条只在当前 shell 生效。申请证书时 acme.sh 会自动把凭证保存到 ~/.acme.sh/account.conf,后续续期不需要再 export。所以只需在首次申请命令前执行一次即可。
  • 首次申请后检查 ~/.acme.sh/account.conf 里是否有 SAVED_Ali_KeySAVED_Ali_Secret,确认已持久化。

四、申请通配符证书(DNS-01)

acme.sh --issue \
  --dns dns_ali \
  -d waisaa.com \
  -d '*.waisaa.com' \
  --keylength ec-256
  • --dns dns_ali:用阿里云 DNS API 自动加/删 TXT 记录,全自动
  • *.waisaa.com 必须用引号包裹,防止 shell 展开
  • --keylength ec-256:ECC 证书,比 RSA 更小更快(nginx 完全支持)
  • 过程:acme.sh 调阿里云 API 加 TXT → 等 DNS 传播(默认 120s)→ 验证 → 删 TXT

成功后证书在 ~/.acme.sh/waisaa.com_ecc/。

关于 CA:acme.sh 默认 ZeroSSL,首次运行会自动注册账号。若想用 Let’s Encrypt:

acme.sh --set-default-ca --server letsencrypt

两者都免费,ZeroSSL 支持泛域名,Let’s Encrypt 也支持,任选其一。
建议保持默认 ZeroSSL 即可。

在这里插入图片描述

在这里插入图片描述

五、安装证书到 nginx 引用路径

我的当前 nginx 配置和 docker 挂载都指向 /etc/letsencrypt/live/waisaa.com/,用 --install-cert 复制过去,配置零改动:

# 先创建目录
mkdir -p /etc/letsencrypt/live/waisaa.com

acme.sh --install-cert -d waisaa.com --ecc \
  --key-file       /etc/letsencrypt/live/waisaa.com/privkey.pem \
  --fullchain-file /etc/letsencrypt/live/waisaa.com/fullchain.pem \
  --reloadcmd      "docker exec nginx nginx -s reload"

参数说明:

  • –ecc 对应第 4 步的 ec-256,必须带
  • –reloadcmd:续期后自动 reload nginx 容器,容器名 nginx 来自 docker-compose.yml:5
  • acme.sh 会把 install-cert 配置记录下来,后续续期自动执行复制 + reload,无需手动干预

验证文件就位:

# 应有 fullchain.pem 和 privkey.pem
ls -l /etc/letsencrypt/live/waisaa.com/
# 查看证书的关键信息,不做任何修改
openssl x509 -in /etc/letsencrypt/live/waisaa.com/fullchain.pem -noout -subject -dates

在这里插入图片描述

六、配置 Nginx HTTPS

修改 Nginx:

server { 
	listen 443 ssl; 
	server_name example.com; 

	ssl_certificate /etc/letsencrypt/live/waisaa.com/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/waisaa.com/privkey.pem;
	
	location / { 
		root /usr/share/nginx/html; 
	} 
}

HTTP 自动跳转 HTTPS:

server { 
	listen 80; 
	server_name example.com; 
	
	return 301 https://$host$request_uri; 
}

重启 Nginx:

docker restart nginx

测试:

curl -I https://example.com

如果返回:

HTTP/2 200

说明 HTTPS 配置成功。

七、启动 nginx

cd /srv/waisaa/infra/nginx
docker compose up -d

# 检查
docker logs nginx --tail 20
curl -I https://tally.waisaa.com/

八、验证自动续期

acme.sh 安装时已自动配好 cron(crontab -l 可见,每天 00:00 检查)。手动模拟一次续期:

acme.sh --renew -d waisaa.com --ecc --force

成功输出 ``Cert success!` 即表示续期 + 复制 + reload 链路完整。

acme.sh 默认在证书到期前 30 天自动续期,ECC 通配符证书有效期 90 天。

更多推荐