如果你有一个域名并用它来搭建互联网服务,提供 https 服务是基本的安全要求,那么就绕不开 SSL 证书的申请。
目前阿里云、腾讯云等云产商都提供了免费申请和管理 SSL 证书的功能支持,但如果你需要使用的子域名比较多,泛域名 SSL 证书才是最好的选择,然而各厂商提供的泛域名证书基本都是需要收费的。
本文介绍一种基于基于 acme.sh 和 dnspod API 生成网站泛域名证书的详细流程与方法,以供有类似场景和需求的同学参考。其基本思路为:
- 1. 通过
ZeroSSL
平台可以申请有效期为 90 天的免费泛域名 SSL 证书; - 2. 将域名免费托管至 dnspod.cn[1],借助 dnspod 提供的 API 可以以代码编程方式程序化验证和设置域名解析;
- 3. 著名的开源项目 acme.sh[2] 以程序化脚本的方式,支持自动化的从
ZeroSSL
申请和续期泛域名 SSL 证书,支持调用 dnspod 平台 API 设置和验证域名解析。
下面的内容均以在 CentOS 7.x 系统下的操作为例,仅供参考。首先应保证 curl
和 cron
已安装,否则可执行如下安装命令:
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.cer \
--key-file /etc/nginx/acme.sh/lzw.me/key.key \
--fullchain-file /etc/nginx/acme.sh/lzw.me/fullchain.cer \
--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_Id
和 DP_Key
会被保存到 ~/.acme.sh/account.conf
文件中,后续再执行时会自动读取并使用它。
查看已生成的证书:
acme.sh list
提示:
这里是我的域名托管在了 dnspod 上,如果你托管在其他服务商,可以从官方文档中查找对应的实现方式及命令:How to use DNS API[3]
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.cer \
--key-file /etc/nginx/acme.sh/lzw.me/key.key \
--fullchain-file /etc/nginx/acme.sh/lzw.me/fullchain.cer \
--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.cer;
ssl_certificate_key /etc/nginx/acme.sh/lzw.me/key.key;
ssl_trusted_certificate /etc/nginx/acme.sh/lzw.me/cert.cer;
# 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/
原创文章,作者:速盾高防cdn,如若转载,请注明出处:https://www.sudun.com/ask/78503.html