跳到主要内容

VPS 申请 HTTPS 证书:Cloudflare + acme.sh 实际配置记录


VPS 申请 HTTPS 证书:Cloudflare + acme.sh 实际配置记录

这篇记录我现在更常用的一套证书申请方式:域名 DNS 托管在 Cloudflare,用 acme.sh 调 Cloudflare DNS API 完成 DNS-01 验证,然后把证书安装到 VPS。

它特别适合:

VPS 没有开放 80 端口
服务只监听 443
域名套了 Cloudflare
需要 *.example.com 通配符证书
希望后续自动续期

相比手工添加 _acme-challenge TXT,DNS API 最大的优势是续期时不需要再登录 Cloudflare 手动改记录。

一、先理解这套流程

整个过程实际上只有四步:

acme.sh
  ↓ 调 Cloudflare API
创建 _acme-challenge TXT
  ↓
Let's Encrypt 验证域名控制权
  ↓
签发证书
  ↓
安装到 Nginx / Caddy / x-ui / 其它服务

Cloudflare 在这里主要负责 DNS,不是证书签发机构。

如果你的网站橙云代理在 Cloudflare 后面,也仍然可以给源站申请 Let’s Encrypt 证书;DNS-01 不依赖 80/443 端口是否公开。

二、安装 acme.sh

Linux 常见安装:

curl https://get.acme.sh | sh -s email=my@example.com

安装后重新加载 shell,或者直接使用:

~/.acme.sh/acme.sh --version

截至本文更新时,acme.sh 主线版本已经到 3.1.6。

这里有一个很容易忽略的变化:acme.sh 默认 CA 不是 Let’s Encrypt,而是 ZeroSSL。

如果本文明确要申请 Let’s Encrypt,可以二选一:

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

或者每次签发时显式加:

--server letsencrypt

三、创建 Cloudflare API Token

现在优先使用 API Token,不要为了图省事直接把 Global API Key 放到 VPS。

Cloudflare Dashboard:

My Profile
→ API Tokens
→ Create Token

可以从 Edit Zone DNS 模板开始,再把资源范围限制到需要申请证书的那个域名。

建议权限:

Zone → DNS → Edit / Write
Zone → Zone → Read

资源范围:

Include → Specific zone → example.com

这样即使 Token 泄露,影响范围也比 Global API Key 小很多。

Token 创建完成后只会完整显示一次,立即保存到密码管理器,不要截图发群,也不要写进博客仓库。

在 VPS 当前 shell 中设置:

export CF_Token='你的 Cloudflare API Token'

如果你明确知道 Zone ID,也可以额外设置:

export CF_Zone_ID='你的 Zone ID'

acme.sh 当前 dns_cf 同时支持:

CF_Token
CF_Account_ID
CF_Zone_ID

旧式 Global API Key 则使用:

export CF_Key='Global API Key'
export CF_Email='Cloudflare 登录邮箱'

但新部署没有必要优先用这套旧方式。

四、申请普通域名证书

假设域名是:

example.com
www.example.com

使用 Cloudflare DNS API:

acme.sh --issue \
  --dns dns_cf \
  -d example.com \
  -d www.example.com \
  --server letsencrypt

acme.sh 会自动:

创建 _acme-challenge TXT
等待 DNS 生效
让 Let's Encrypt 验证
删除自己创建的 TXT
保存证书

当前 dns_cf 的清理逻辑会按:

TXT 名称 + TXT 内容

精确寻找自己创建的记录,然后删除对应记录 ID,不会粗暴删除同名下的所有 TXT。

五、申请通配符证书

如果希望同时覆盖:

example.com
*.example.com

可以:

acme.sh --issue \
  --dns dns_cf \
  -d example.com \
  -d '*.example.com' \
  --server letsencrypt

通配符证书必须使用 DNS-01,所以 Cloudflare API 方式非常适合这一场景。

申请成功后查看:

acme.sh --list

六、把证书安装到固定路径

不要让 Nginx、x-ui 或其它服务直接引用 ~/.acme.sh/ 里的内部文件。正确做法是使用 --install-cert 复制到你自己的正式路径,并配置 reload 命令。

先创建目录:

sudo mkdir -p /etc/ssl/example.com

如果申请的是 ECC 证书,可以:

acme.sh --install-cert -d example.com --ecc \
  --key-file       /etc/ssl/example.com/key.pem \
  --fullchain-file /etc/ssl/example.com/fullchain.pem \
  --reloadcmd      "systemctl reload nginx"

如果不是 ECC,去掉 --ecc。

Nginx 中引用:

ssl_certificate     /etc/ssl/example.com/fullchain.pem;
ssl_certificate_key /etc/ssl/example.com/key.pem;

检查配置并重载:

nginx -t
systemctl reload nginx

验证证书:

openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null |
  openssl x509 -noout -issuer -subject -dates

七、自动续期怎么确认

acme.sh 安装时一般会建立 cron / 定时任务。

可以手动跑一次:

acme.sh --cron --home ~/.acme.sh

也可以强制测试:

acme.sh --renew -d example.com --force

如果是 ECC:

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

真正的自动续期不仅要“证书签出来”,还要确认 --install-cert 保存的 reload 命令能正常执行,否则磁盘上的新证书更新了,服务仍可能继续加载旧证书。

八、Cloudflare Authentication error 怎么排查

我之前就踩过这个坑:TXT 添加阶段直接返回 Cloudflare Authentication error,看起来像 acme.sh 坏了,实际一般是凭据或 Token 权限问题。

按这个顺序查:

1. Token 是否复制完整
2. Token 是否已经被删除/轮换
3. 是否给了目标 Zone 的 DNS Edit / Write
4. 是否给了 Zone Read
5. Resource 是否包含实际域名
6. shell 里的旧 CF_Key / CF_Email / CF_Token 是否互相干扰

查看当前变量名即可,不要直接把值打印到聊天或截图:

env | grep '^CF_'

需要重新绑定 Token 时,推荐重新 export 正确的变量后重新 issue 一次,让 acme.sh 保存新的 DNS API 凭据;不要习惯性手改内部配置文件。

如果旧 Global API Key 方案一直失败,改用最小权限 API Token 往往更清楚:

unset CF_Key
unset CF_Email
export CF_Token='新的 API Token'

然后重新签发。

九、证书撤销和重新签发

撤销证书:

acme.sh --revoke -d example.com --ecc

如果不是 ECC,去掉 --ecc。

但实际运维中,“域名换 VPS / 更换密钥 / 重新绑定服务”并不一定需要先 revoke。很多时候直接重新签发一张新证书并替换服务端文件即可。

如果怀疑私钥泄露,再撤销旧证书并重新生成新的私钥更合理。

十、Cloudflare Origin Certificate 和 Let’s Encrypt 怎么选

如果源站永远只允许 Cloudflare 回源,Cloudflare Origin CA 也可以用,而且有效期很长。

如果源站可能被浏览器、程序、其他 CDN 或非 Cloudflare 客户端直接访问,我更偏向 Let’s Encrypt 这类公开受信任证书。

简单理解:

只给 Cloudflare 看        → Origin Certificate 可以
需要公网客户端直接信任    → Let's Encrypt 更通用

十一、参考资料


文章作者: 0xdadream
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 0xdadream !
赏
评论

评论将在接近此处时加载,也可点击立即加载。

  目录