基于 acme.sh 和 dnspod API 自动生成与续期泛域名SSL证书

摘要

如果你有一个域名并用它来搭建互联网服务,提供 https 服务是基本的安全要求,那么就绕不开 SSL 证书的申请。本文介绍一种基于基于 acme.sh 和 dnspod API 生成网站泛域名证书的详细流程与方法,以供有类似场景和需求的同学参考。

目录
[隐藏]

如果你有一个域名并用它来搭建互联网服务,提供 https 服务是基本的安全要求,那么就绕不开 SSL 证书的申请。

目前阿里云、腾讯云等云产商都提供了免费申请和管理 SSL 证书的功能支持,但如果你需要使用的子域名比较多,泛域名 SSL 证书才是最好的选择,然而各厂商提供的泛域名证书基本都是需要收费的。

本文介绍一种基于基于 acme.sh 和 dnspod API 生成网站泛域名证书的详细流程与方法,以供有类似场景和需求的同学参考。其基本思路为:

  1. 通过 ZeroSSL 平台可以申请有效期为 90 天的免费泛域名 SSL 证书;
  2. 将域名免费托管至 dnspod.cn,借助 dnspod 提供的 API 可以以代码编程方式程序化验证和设置域名解析;
  3. 著名的开源项目 acme.sh 以程序化脚本的方式,支持自动化的从 ZeroSSL 申请和续期泛域名 SSL 证书,支持调用 dnspod 平台 API 设置和验证域名解析。

下面的内容均以在 CentOS 7.x 系统下的操作为例,仅供参考。首先应保证 curlcron 已安装,否则可执行如下安装命令:

yum update & yum install curl cron socat -y

1 基于 acme.sh 和 dnspod API 生成网站泛域名证书

1.0 快速开始

一键执行脚本参考:

# 设置 dnspod 的 DNS API Token
export DP_Id="你的 ID"
export DP_Key="你的 KEY"

# 安装 acme.sh
curl https://get.acme.sh | sh
source ~/.bashrc
acme.sh --version

# 注册账号
acme.sh --register-account -m test@lzw.me
# 获取证书
acme.sh --issue --dns dns_dp -d lzw.me -d *.lzw.me
# 查看已安装的证书
acme.sh --list

# 安装证书
mkdir -p /etc/nginx/acme.sh/lzw.me/
acme.sh --install-cert -d lzw.me \
--cert-file      /etc/nginx/acme.sh/lzw.me/cert.pem  \
--key-file       /etc/nginx/acme.sh/lzw.me/key.pem  \
--fullchain-file /etc/nginx/acme.sh/lzw.me/fullchain.pem \
--reloadcmd "nginx -s reload"

# 开启 acme.sh 自动更新
acme.sh --upgrade --auto-upgrade

# 查看定时任务
crontab -l

# TODO: 请手动配置 nginx
  • 以上为一键执行脚本示例,具体说明可参考下文介绍。
  • 请注意设置你的 dnspod API Token 信息,并将 lzw.me 替换为你的域名。

1.1 安装 acme.sh

一键安装:

curl https://get.acme.sh | sh
source ~/.bashrc
acme.sh --version

提示:

如果安装了 git,也可以直接使用 git 拉取仓库的方式安装。参考:

git clone https://github.com/acmesh-official/acme.sh.git
alias acme.sh=~/.acme.sh/acme.sh

1.2 使用邮箱注册 ZeroSSL 账号

acme.sh 当前默认使用 ZeroSSL 服务,ZeroSSL 可以颁发有效期为 90 天的 SSL 证书。我们需要先注册一个 ZeroSSL 的账号:

$ acme.sh --register-account -m test@lzw.me

# 输出信息参考:
No EAB credentials found for ZeroSSL, let's get one
Registering account: https://acme.zerossl.com/v2/DV90
Registered
ACCOUNT_THUMBPRINT='9d1k6jRbSrzKy9iqiaMwaLz3kv2vmQ5LwAhc7tlEXN8'

1.3 生成 dnspod API Token

登录 dnspod.cn,打开地址 https://console.dnspod.cn/account/token/apikey,在API秘钥 -> DNSPod Token 下创建一个秘钥,接着复制 ID 和 Token,执行如下命令将其配置到环境变量中:

export DP_Id="你的 ID"
export DP_Key="你的 KEY"

1.4. 基于 dnspod 的 dns API 验证生成泛域名证书

这里以 lzw.me 为例,基于 dnspod 的 dns 验证方式生成泛域名证书。参考命令:

acme.sh --issue --dns dns_dp -d lzw.me -d *.lzw.me

# 主要输出信息参考:
Cert success.

Your cert is in: /root/.acme.sh/lzw.me_ecc/lzw.me.cer
Your cert key is in: /root/.acme.sh/lzw.me_ecc/lzw.me.key
The intermediate CA cert is in: /root/.acme.sh/lzw.me_ecc/ca.cer
And the full chain certs is there: /root/.acme.sh/lzw.me_ecc/fullchain.cer

执行成功后,DP_IdDP_Key 会被保存到 ~/.acme.sh/account.conf 文件中,后续再执行时会自动读取并使用它。

查看已生成的证书:

acme.sh list

提示:

这里是我的域名托管在了 dnspod 上,如果你托管在其他服务商,可以从官方文档中查找对应的实现方式及命令:How to use DNS API

1.5 安装证书

acme.sh 生成的证书默认保存在 ~/.acme.sh 目录下,原则上可以直接使用它进行 nginx 的 https 配置。但是当需要续签重新生成证书时,还需要手动去重载 nginx。通过 acme.sh 提供的 install 命令,可以在自动续签完成后将证书安装到指定的位置,并调用 nginx 配置重载动作。命令参考:

mkdir -p /etc/nginx/acme.sh/lzw.me/

acme.sh --install-cert -d lzw.me \
--cert-file      /etc/nginx/acme.sh/lzw.me/cert.pem  \
--key-file       /etc/nginx/acme.sh/lzw.me/key.pem  \
--fullchain-file /etc/nginx/acme.sh/lzw.me/fullchain.pem \
--reloadcmd "nginx -s reload"
# --reloadcmd  "sesystemctl restart nginx"

2 配置 nginx 使用该证书

请参考以下配置:

# 禁用 http,80 端口重定向到 https
server {
    listen 80;
    server_name lzw.me *.lzw.me;

    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl http2;
    server_name lzw.me;

    ssl on;
    ssl_certificate /etc/nginx/acme.sh/lzw.me/fullchain.pem;
    ssl_certificate_key /etc/nginx/acme.sh/lzw.me/key.pem;
    ssl_trusted_certificate /etc/nginx/acme.sh/lzw.me/cert.pem;

    # api 服务 nginx 反向代理示例
    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

3 acme.sh 与证书的自动更新

设置 acme.sh 自动更新:

acme.sh --upgrade --auto-upgrade

acme.sh 成功生成证书后,还会自动生成一条 cron 定时任务用于自动更新证书,这样就不用每次手动执行了。可以通过 crontab -l 查看:

$ crontab -l

# 每天 20:25 自动检测是否需要更新证书
25 20 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null

我们手动执行一下这条命令试一试:

$ "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh"

[Wed Jan 31 15:34:10 CST 2024] ===Starting cron===
[Wed Jan 31 15:34:11 CST 2024] Already uptodate!
[Wed Jan 31 15:34:11 CST 2024] Upgrade success!
[Wed Jan 31 15:34:11 CST 2024] Auto upgraded to: 3.0.8
[Wed Jan 31 15:34:11 CST 2024] Renew: 'lzw.me'
[Wed Jan 31 15:34:11 CST 2024] Renew to Le_API=https://acme.zerossl.com/v2/DV90
[Wed Jan 31 15:34:11 CST 2024] Skip, Next renewal time is: 2024-03-30T04:10:45Z
[Wed Jan 31 15:34:11 CST 2024] Add '--force' to force to renew.
[Wed Jan 31 15:34:11 CST 2024] Skipped lzw.me_ecc
[Wed Jan 31 15:34:11 CST 2024] ===End cron===

4 扩展参考

  • https://github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_dpi
  • https://letsencrypt.org/zh-cn/docs/client-options/
点赞 (26)
  1. jiyouzhan说道:
    Firefox 108.0 Firefox 108.0 Windows 7 x64 Edition Windows 7 x64 Edition

    这篇文章写得深入浅出,让我这个小白也看懂了!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Captcha Code