使用 Certbot DNS 质询颁发 Let's Encrypt 通配符 SSL

通配符 SSL 证书 *.example.com 可在同一张证书下覆盖所有子域名(blog.example.comshop.example.com)——但 Let's Encrypt 无法通过 HTTP-01 颁发通配符证书,必须使用 DNS-01 质询

本指南介绍如何在 Ubuntu VPS 上使用 Certbot + DNS 质询获取免费的 Let's Encrypt 通配符证书,包括手动方式和通过 Cloudflare DNS API 自动续期(每 60 天)两种路径。

前提条件:一个您控制 DNS 的域名(Web 服务器可在其他位置)、一台具有 sudo 权限的 Ubuntu VPS。若使用自动路径,需创建具有 Zone:DNS Edit 权限范围的 Cloudflare API Token。

HTTP-01 与 DNS-01 质询对比

项目HTTP-01DNS-01
验证方式.well-known/acme-challenge/ 放置文件在 DNS 中添加 TXT 记录
通配符❌ 不支持✅ 支持
需要 Web 服务器是 — 需开放 80 端口
自动续期简单 — Certbot 自动处理需要 DNS API
适用场景单主机证书通配符证书、内部服务

为何通配符 SSL 是多子域名 VPS 部署的最佳选择

当您的服务器托管多个子域名——shop.example.comblog.example.comapi.example.comadmin.example.com——为每个子域名单独申请证书会大幅增加管理负担和续期工作。一张通配符证书即可消除这种复杂性。在 VPS 上使用通配符证书的主要优势:

需要注意的关键限制:通配符证书仅覆盖一级子域名。*.example.com 覆盖 a.example.com,但不覆盖 b.a.example.com。如需覆盖更深层子域名,需要单独的通配符(如 *.a.example.com)或多 SAN 证书。

方式一 — 手动 DNS 质询(一次性)

适用于偶尔使用且 DNS 无 API 的情况——但每 90 天续期时都需要手动粘贴 TXT 记录。

1.1 安装 Certbot

sudo apt update
sudo apt install -y certbot

1.2 手动申请通配符证书

sudo certbot certonly --manual --preferred-challenges=dns \
  --email [email protected] --agree-tos --no-eff-email \
  -d example.com -d "*.example.com"

Certbot 将打印需要部署的 TXT 记录,例如:

Please deploy a DNS TXT record under the name:
_acme-challenge.example.com.

with the following value:
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

在 DNS 管理面板(Cloudflare / Route 53 / DirectAdmin DNS)中添加该 TXT 记录,等待 1–2 分钟传播后按 Enter。Certbot 验证后将在 /etc/letsencrypt/live/example.com/ 下颁发证书,同时覆盖根域名和所有子域名。

方式二 — 通过 Cloudflare DNS 插件自动续期

若您的 DNS 托管在 Cloudflare,Certbot 可以在无需任何手动操作的情况下自动颁发和续期证书。

2.1 安装 Cloudflare 插件

sudo apt install -y python3-certbot-dns-cloudflare

2.2 创建 Cloudflare API Token

前往 我的个人资料 → API 令牌 → 创建令牌 → 编辑区域 DNS,选择相应区域并保存令牌。

2.3 存储令牌(重要:chmod 600)

sudo mkdir -p /etc/letsencrypt/cloudflare
sudo nano /etc/letsencrypt/cloudflare/credentials.ini

文件内容:

dns_cloudflare_api_token = YOUR_CLOUDFLARE_TOKEN_HERE
sudo chmod 600 /etc/letsencrypt/cloudflare/credentials.ini

⚠️ 凭据文件权限必须设为 600。否则 Certbot 出于安全原因将拒绝使用该文件。

2.4 申请通配符证书

sudo certbot certonly --dns-cloudflare \
  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare/credentials.ini \
  --dns-cloudflare-propagation-seconds 30 \
  --email [email protected] --agree-tos --no-eff-email \
  -d example.com -d "*.example.com"

Certbot 调用 Cloudflare API 自动添加和删除 TXT 记录,证书将存放于 /etc/letsencrypt/live/example.com/

步骤三 — 配置 Nginx

在您的 Nginx server 块中:

server {
    listen 443 ssl http2;
    server_name example.com *.example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # recommended hardening
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;

    root /var/www/example;
    index index.html;
}

测试配置并重载:

sudo nginx -t
sudo systemctl reload nginx

步骤四 — 每 60 天自动续期

Certbot 自带 systemd 定时器,查看状态:

sudo systemctl list-timers | grep certbot

模拟续期测试:

sudo certbot renew --dry-run

每次续期后自动重载 Nginx:

sudo nano /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh

文件内容:

#!/bin/bash
systemctl reload nginx
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh

配置 Nginx 虚拟主机共用一张通配符证书

获取通配符证书后,可在每个虚拟主机中引用同一组证书文件。以下示例展示两个子域名分别使用独立配置文件:

# /etc/nginx/sites-available/shop.conf
server {
    listen 443 ssl http2;
    server_name shop.example.com;
    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    root /var/www/shop;
    index index.html index.php;
}

# /etc/nginx/sites-available/blog.conf
server {
    listen 443 ssl http2;
    server_name blog.example.com;
    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    root /var/www/blog;
    index index.html index.php;
}

两个虚拟主机共享同一套证书。Certbot 每 60 天自动续期,续期钩子会自动重载 Nginx——您无需修改各个虚拟主机的配置文件。

ls -la /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

常见通配符 SSL 问题排查

下表列出了 DNS-01 颁发和续期过程中最常见的错误:

问题 原因 解决方法
DNS 传播超时 Certbot 检查前 TXT 记录尚不可见 增大 --dns-cloudflare-propagation-seconds 60
credentials.ini 权限错误 文件权限不是 600 sudo chmod 600 credentials.ini
超出频率限制 每个域名每周失败订单超过 5 次 等待 7 天或测试时使用 --staging
续期后 Nginx 未重载 续期钩子缺失或无执行权限 检查 chmod +x reload-nginx.sh

开发测试时请务必先使用 staging 环境,避免触碰频率限制:

sudo certbot certonly --dns-cloudflare \
  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare/credentials.ini \
  --staging \
  -d example.com -d "*.example.com"

检查证书有效期

sudo certbot certificates
# or
sudo openssl x509 -in /etc/letsencrypt/live/example.com/fullchain.pem -noout -dates

通配符 SSL 安全加固清单

  1. 保持 credentials.ini 权限为 600
  2. 使用范围限定的 Cloudflare API Token(Zone:DNS Edit)— 切勿使用全局 API Key
  3. Nginx 中仅允许 TLSv1.2 TLSv1.3,禁用 TLS 1.0/1.1
  4. 配置自动续期并设置续期钩子以重载 Nginx
  5. 定期通过 AsiaGB SSL 服务器检测 扫描
  6. 通配符仅覆盖一级子域名*.example.com 覆盖 a.example.com,但不覆盖 b.a.example.com

需要用于 Web + 通配符 SSL 的 VPS?

AsiaGB VPS 起价 500 泰铢/月,提供完整 root 权限——可自由开放端口用于 Let's Encrypt 和 Nginx。支持泰国/新加坡数据中心。

查看 VPS 套餐