Skip to content
Go back

为 acme.sh 配置 Cloudflare 的 DNS 验证来申请泛域名 SSL 证书

| 0 Views Edit page

前言

easycrawl.dev 网站需要一个 SSL 证书,但是不清楚后面会有多少子域名,因此直接申请泛域名证书吧。
顺便提一下,dev 后缀的域名是强制使用 HTTPS 的,用 HTTP 访问可能会报以下错误:

网址为 https://easycrawl.dev/ 的网页可能暂时无法连接,或者它已永久性地移动到了新网址。
ERR_SSL_UNRECOGNIZED_NAME_ALERT


方案概述

  1. 安装 acme.sh
  2. 配置 Cloudflare 的 DNS 验证
  3. 创建可以修改 Cloudflare DNS 的 API Token
  4. 配置 acme.sh 使用 Cloudflare 的 DNS 验证
  5. 申请泛域名 SSL 证书
  6. 安装 Nginx
  7. 安装证书并配置自动更新
  8. 配置 Nginx 使用 SSL 证书

操作步骤

一、安装 acme.sh

# 安装所需软件
apt-get install curl
apt-get install socat
# 安装 acme
curl https://get.acme.sh | sh
# 添加软链接
ln -s  /root/.acme.sh/acme.sh /usr/local/bin/acme.sh
# 查看 acme.sh 版本
acme.sh --version

v3.1.2

二、配置 Cloudflare 的 DNS 验证

我是在 Namecheap 上注册的域名,因此需要先在 Namecheap 上配置 DNS 解析。
进入控制台选择对应的域名,点击 Manage 进入域名管理页面:
点击 Manage 按钮 选择 Custom DNS 并填入 Cloudflare 分配给你的 Nameserver
填写两个 Nameserver

在你的 Cloudflare 控制台选择 加入域(添加域名)后继续操作,会在某一步提供给你两个 Nameserver
加入域

三、创建可以修改 Cloudflare DNS 的 API Token

进入 Cloudflare 的用户 API 令牌页面,选择 创建令牌
创建令牌
选择 编辑区域 DNS 的模板:
编辑区域 DNS
选择特定的区域(域名):
选择特定的区域
之后一步步确认并创建即可。
创建完成后,你就拥有了下面三个内容:

  • token: xxxxxxxxxxxxxxxxx8faebc
  • zone_id: 023e105f4ecefXXXXXxxxxxxxxx
  • account_id: 023e105f4ecefXXXXXxxxxxxxxx

其中 zone_idaccount_id 是固定的,token 是刚刚生成的。
zone_id(区域 ID)和account_id(账户 ID)在 Cloudflare 对应域名的控制台右上角可以找到:
区域 ID 和账户 ID

四、配置 acme.sh 使用 Cloudflare 的 DNS 验证

其实只要设置一下环境变量即可:

export CF_Token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
export CF_Zone_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
export CF_Account_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

五、申请泛域名 SSL 证书

acme.sh --issue --dns dns_cf -d easycrawl.dev -d '*.easycrawl.dev'

如果出现下面的错误:

[Sun Aug 31 13:33:01 BST 2025] Using CA: https://acme.zerossl.com/v2/DV90
[Sun Aug 31 13:33:02 BST 2025] No EAB credentials found for ZeroSSL, let’s obtain them
[Sun Aug 31 13:33:02 BST 2025] acme.sh is using ZeroSSL as default CA now.
[Sun Aug 31 13:33:02 BST 2025] Please update your account with an email address first.
[Sun Aug 31 13:33:02 BST 2025] acme.sh —register-account -m my@example.com
[Sun Aug 31 13:33:02 BST 2025] See: https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA
[Sun Aug 31 13:33:02 BST 2025] Please check log file for more details: /root/.acme.sh/acme.sh.log

则需要先随便使用一个邮箱注册一下:

acme.sh --register-account -m example@example.com

之后再申请证书即可。

没问题的话,大概 30 秒证书就申请成功了:
证书申请成功

六、安装 Nginx

你可以简单地安装旧版本的 Nginx:

apt-get install nginx

或者使用我的脚本来安装最新版的:rabbir/nginx.bash

七、安装证书并配置自动更新

我习惯将证书安装到 /etc/nginx/ssl 目录下,因此使用下面的命令:

mkdir -vp /etc/nginx/ssl/easycrawl.dev
acme.sh --install-cert -d easycrawl.dev \
  --fullchain-file /etc/nginx/ssl/easycrawl.dev/certificate.crt \
  --key-file /etc/nginx/ssl/easycrawl.dev/private.key \
  --reloadcmd "systemctl reload nginx"

之后每隔大概 2 个月,acme.sh 会自动更新证书,并使用 systemctl reload nginx 重新加载 Nginx 来使用新的证书。

八、配置 Nginx 使用 SSL 证书

我的 /etc/nginx/conf.d/default.conf 文件内容如下:

# 非域名访问返回 500 错误
server {
    listen      80;
    listen      [::]:80;
    server_name _;

    location / {
        return      500;
    }

    # 特殊的证书认证用的路径
    location /.well-known/acme-challenge/ {
        # acme.sh --webroot 模式,认证文件生成后放置的路径
        root /var/acme/webroot/;
    }
}

# 非域名访问防止发送 SSL 证书
server {
    listen      443 ssl default_server;
    server_name _;
 
    ssl_protocols           TLSv1.2 TLSv1.3;
    # 启用拒绝 TLS 握手
    ssl_reject_handshake    on;
    # SSL Session 缓存,不设置的话无缓存配置不生效
    ssl_session_cache       shared:SSL:10m;
    ssl_session_timeout     10m;

    # log 位置自行替换
    access_log  /var/log/nginx/host.access.log;
}

需要新建一下 api.easycrawl.dev.conf 文件来让子域名使用泛域名证书:

vi /etc/nginx/conf.d/api.easycrawl.dev.conf
server {
    listen      443 ssl;
    server_name api.easycrawl.dev;

    # SSL 配置
    ssl_certificate             /etc/nginx/ssl/easycrawl.dev/certificate.crt;
    ssl_certificate_key         /etc/nginx/ssl/easycrawl.dev/private.key;
    ssl_protocols               TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_ciphers                 ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Port $server_port;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        # This allows the ability for the execute shell window to remain open for up to 15 minutes. Without this parameter, the default is 1 minute and will automatically close.
        proxy_read_timeout 900s;
    }
}

之后重启 Nginx 即可:

systemctl reload nginx

不一样版本的 Nginx 支持的配置不一样,一般出错的话删除对应的配置项即可。

再次访问 https://api.easycrawl.dev/docs 就可以看到 SSL 证书已经生效了:
SSL 证书已经生效
结束。


参考资料:


Edit page