摘要
文章内容 在 Gentoo 上通过 Certbot 配合 Cloudflare DNS-01 验证获取通配符证书的完整配置指南,涵盖插件安装、API Token 创建、凭据配置、证书签发及自动续期。
通配符匹配规则
- 通配符证书仅匹配单层子域名,不匹配裸域和多层子域
- 如需同时覆盖裸域和子域,签发时需同时指定两者
- 公共 CA 不支持多层通配符形式
多层子域策略 可通过添加额外的单层通配符解决,例如为 service 子域单独申请一个通配符。
关键注意事项
- 凭据文件权限必须设为 600,否则 Certbot 将拒绝使用
- 通配符证书只能通过 DNS-01 方式签发
- Gentoo 特有:需处理测试分支关键字依赖问题
流程概览
| 步骤 | 操作 | 关键文件/命令 |
|---|---|---|
| 1 | 安装 Certbot 及插件 | emerge app-crypt/certbot-dns-cloudflare |
| 2 | 创建 API Token | Cloudflare Dashboard |
| 3 | 配置凭据文件 | /root/.secrets/certbot/cloudflare.ini |
| 4 | 签发证书 | certbot certonly --dns-cloudflare |
| 5 | 自动续期 | crontab + certbot renew |
安装 Certbot 与 Cloudflare DNS 插件
安装 Certbot
同步 Portage 后安装 certbot:
app-crypt/certbot-nginx 为可选组件,用于自动配置 Nginx(Apache 用户可安装 app-crypt/certbot-apache)。
添加 overlay 并安装插件
Cloudflare DNS 插件位于 certbot-dns-plugins overlay:
# 安装 overlay 管理工具
# 启用并同步 overlay
# 安装插件
验证安装:
输出应包含 dns-cloudflare authenticator。
处理 ~amd64 关键字依赖
安装 certbot-dns-cloudflare 时可能遇到以下错误:
!!! All ebuilds that could satisfy ">=dev-python/cloudflare-2.19.0[...]" have been masked.
!!! One of the following masked packages is required to complete your request:
- dev-python/cloudflare-2.19.4::certbot-dns-plugins (masked by: ~amd64 keyword)
这表示依赖包 dev-python/cloudflare 仅有测试分支(~amd64)版本,需要手动接受该关键字。
手动添加关键字
若存在其他 ~amd64 依赖,按相同方式添加即可。
使用 autounmask(可选)
创建 Cloudflare API Token
相比 Global API Key,API Token 支持细粒度权限控制,安全性更高。
创建步骤:
- 登录 Cloudflare Dashboard
- 进入 My Profile → API Tokens → Create Token
- 选择 "Edit zone DNS" 模板,或手动配置权限
- 保存生成的 Token
| 配置项 | 值 |
|---|---|
| Permissions | Zone: DNS: Edit |
| Zone Resources | 选择目标域名 |
Warning
Token 仅在创建时显示一次,请妥善保存。
配置凭据文件
创建凭据文件并设置权限:
| 对象 | 权限 |
|---|---|
| 凭据文件 | 600 |
| 上级目录 | 700 |
Caution
权限设置不当会导致 Certbot 拒绝使用该凭据。
签发证书
插件会自动通过 Cloudflare API 创建 _acme-challenge TXT 记录完成验证。
单域名证书
根域名 + 通配符证书
DNS 传播较慢时可添加 --dns-cloudflare-propagation-seconds 60 延长等待时间。
证书存储位置:
/etc/letsencrypt/live/example.com/
├── fullchain.pem # 证书链
└── privkey.pem # 私钥
自动续期
测试续期
配置 cron
Gentoo 需手动安装 cron 实现:
添加定时任务:
# 每天 0:15 和 12:15 检查续期
15 0,12 * * * certbot renew -q
续期后重载 Nginx:
15 0,12 * * * certbot renew -q --deploy-hook "systemctl reload nginx"
签发时使用的插件和参数会自动保存在 /etc/letsencrypt/renewal/*.conf,续期时无需重复指定。
通配符证书覆盖范围
匹配规则
*.example.com 仅匹配单层子域名:
| 域名 | 匹配 *.example.com |
|---|---|
www.example.com |
是 |
api.example.com |
是 |
example.com |
否(裸域) |
a.b.example.com |
否(多层) |
同时覆盖裸域和子域
证书将包含两个 SAN 条目,可覆盖 example.com 及所有单层子域。
多层子域的证书策略
*.example.com 无法用于 a.b.example.com。TLS 握手阶段客户端会验证证书 SAN/CN 与域名的匹配关系,这发生在应用层之前,无法通过服务器配置绕过。
中间层固定的情况
若子域结构为 *.service.example.com,可申请额外的通配符:
注意:这仍是多个单层通配符的组合,而非 *.*.example.com——公共 CA 不支持多层通配符。
中间层不固定的情况
若子域结构无规律(如 a.b.example.com、x.y.example.com),需逐一列出:
或重新规划域名结构,统一中间层后使用通配符方案。
常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 403 错误 | Token 权限不足 | 确保 Token 具有 Zone: DNS: Edit 权限 |
| 权限警告 | 凭据文件权限不当 | cloudflare.ini 设为 600,目录设为 700 |
| 凭据读取错误 | 多凭据冲突 | 移除环境变量、cloudflare.cfg 等其他凭据来源 |
| 通配符签发失败 | 验证方式错误 | 通配符仅支持 DNS-01,不支持 HTTP-01 和 TLS-ALPN-01 |
| 续期失败 | 配置文件损坏 | 重新运行 certbot certonly(指定相同 --cert-name) |
命令速查
# 安装
# 配置凭据
# 签发证书
# 测试续期
# 配置自动续期
# crontab: 15 0,12 * * * certbot renew -q --deploy-hook "systemctl reload nginx"