前言 我之前已经写过一篇certbot申请ssl证书的文章 ,为什么这次还要再写一遍呢? 原因在于,certbot 虽能实现服务器内部的 SSL 证书申请与自动更新,但在使用 CDN 的场景下,无法自动将证书上传并配置到腾讯云 CDN (或许有方法但我未曾深入研究)。相比之下,acme.sh 在这一场景下表现更为出色,不仅灵活性强,还能满足我的定制化需求。
acme.sh与certbot的横向对比
特性维度
acme.sh
certbot
核心设计
纯 Shell 脚本编写
由 Let’s Encrypt 官方推荐,使用 Python 编写
安装与复杂度
安装简单,配置相对复杂 ,尤其在使用 DNS API 时
安装与配置较为简单 ,但对复杂或特殊环境的支持较弱
自动化与续期
自动设置定时任务 ,自动化程度高
更新证书需要手动设置 cron 任务
验证方式
支持多种验证方式(如 DNS、HTTP),尤其擅长通过 DNS API 进行验证 ,适合通配符证书
支持 HTTP 和 DNS 验证
灵活性
非常灵活,支持众多 DNS 服务商 API,可指定证书存放路径
与主流 Web 服务器(如 Apache、Nginx)集成较好,但路径定制相对不灵活
适用场景
需要通配符证书 、多域名管理 、与云平台/CDN 集成 、无 GUI 的服务器环境 或希望高度自动化 的场景
适合单机部署 、快速为现有 Web 服务器(如 Apache, Nginx)配置证书 、初学者 或命令行经验较少的用户
核心概念解析: 1.证书文件格式 申请SSL证书的过程中,通常会接触到如下几种文件格式:
文件后缀
通常格式
通常包含的内容
说明
.pem
PEM
非常灵活。可以是: 1. 证书 2. 私钥 3. 证书链 4. 其他 PKI 对象
一个“万能”容器。看到这个后缀,你需要查看文件内容 来确定它到底是什么。
.crt
或 .cer
多为 PEM ,也可能是 DER
证书
这两个后缀几乎可以互换,都表示“证书”。在 Linux/Unix 世界中更常用 .crt
,在 Windows 中更常用 .cer
。
.key
PEM
私钥
专门用于存放私钥的文件。必须严加保护!
.csr
PEM
证书签名请求
在向 CA 申请证书时生成的文件,包含你的公钥和公司信息。
2.证书颁发机构(CA)选择 CA是C ertificate A uthority的缩写,也就是证书颁发机构,常见的证书颁发机构有ZeroSSL 和 Let’s Encrypt,二者的对比如下
特性维度
ZeroSSL
Let’s Encrypt
验证方式
支持 DNS、HTTP 文件、邮箱验证
主要通过 DNS 和 HTTP 文件验证(通过 ACME 协议)
通配符证书
免费版不支持 ,付费版支持
支持 免费通配符证书
多域名证书
免费版支持(最多3个域名),付费版支持更多
支持(单证书最多100个域名)
IP证书
支持 为纯IP地址签发证书
不支持
API速率限制
相对宽松,免费账户有一定限制但“无同一IP多次申请被限制的问题”
有明确的速率限制(如每周同一主域名下最多签发50个证书)
管理界面
提供友好的Web管理后台 ,可可视化查看、申请、管理证书
无官方Web管理界面,完全通过命令行或第三方工具(如acme.sh, Certbot)管理
自动化与集成
支持 ACME 协议自动化,但免费版自动化功能可能不如Let’s Encrypt生态丰富
自动化生态极其成熟 ,与Certbot、acme.sh等工具无缝集成,非常适合自动化部署和续签
默认CA变化
acme.sh v3.0及以上版本默认CA已从Let’s Encrypt切换为ZeroSSL
曾是许多自动化工具(如acme.sh旧版)的默认选择
适用场景
需要IP证书 、多域名证书 (≤3个),偏好图形化界面 操作,或遇到Let’s Encrypt速率限制的用户
需要通配符证书 ,追求极致的自动化 和丰富的集成生态,有大量证书管理需求的技术用户
从 v3.0 版本开始,acme.sh的默认CA 已从Let’s Encrypt改为ZeroSSL,你可以通过以下命令切换:
1 acme.sh --set-default-ca --server letsencrypt
实战环节 服务器本地证书更新自动化 1. 安装 acme.sh 安装很简单,一条命令:
1 curl https://get.acme.sh | sh -s email=my@example.com
2.验证域名所有权(DNS自动验证方式) 以 腾讯云DNSPod.cn 为例,先登录DNSPod.cn ,获取 DNSPod API Key 和 ID 并执行下面的命令
1 2 export DP_Id="1234" export DP_Key="sADDsdasdgdsf"
命令执行后配置文件会存储在用户目录下的:~/.acme.sh/account.conf
3.签发ssl证书 以本站为例,执行以下命令,申请cyanfish.site以及包含所有子域名的通配符证书:
1 acme.sh --issue --dns dns_dp -d cyanfish.site -d *.cyanfish.site
这里报错了,提示
1 acme.sh: command not found
询问AI老师,得知重新加载shell配置应用环境变量,执行如下命令,先查看shell类型
然后执行对应的重新加载配置命令
1 2 3 source ~/.bashrcsource ~/.zshrc
再次尝试签发证书,成功后输出如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 ubuntu@VM-16-3-ubuntu:~/.acme.sh$ acme.sh --issue --dns dns_dp -d cyanfish.site -d *.cyanfish.site [Mon Sep 8 12:27:14 PM CST 2025] Using CA: https://acme.zerossl.com/v2/DV90 [Mon Sep 8 12:27:14 PM CST 2025] Multi domain='DNS:cyanfish.site,DNS:*.cyanfish.site' [Mon Sep 8 12:27:22 PM CST 2025] Getting webroot for domain='cyanfish.site' [Mon Sep 8 12:27:22 PM CST 2025] Getting webroot for domain='*.cyanfish.site' [Mon Sep 8 12:27:22 PM CST 2025] Adding TXT value: J8kRNAtgSArI9g-lCo8FyOzLjYu7WnO7JeSscjJFpBg for domain: _acme-challenge.cyanfish.site [Mon Sep 8 12:27:23 PM CST 2025] Adding record [Mon Sep 8 12:27:24 PM CST 2025] The TXT record has been successfully added. [Mon Sep 8 12:27:24 PM CST 2025] Adding TXT value: fWxb3zLS3embDHwjLf-M0cjMTaE5i9VmuCgIl09THHs for domain: _acme-challenge.cyanfish.site [Mon Sep 8 12:27:24 PM CST 2025] Adding record [Mon Sep 8 12:27:25 PM CST 2025] The TXT record has been successfully added. [Mon Sep 8 12:27:26 PM CST 2025] Let's check each DNS record now. Sleeping for 20 seconds first.
4.安装证书到nginx 先创建要存放证书和key的目录:
1 mkdir /etc/nginx/ssl/cyanfish.site
然后执行如下命令安装证书:
1 2 3 4 acme.sh --install-cert -d cyanfish.site \ --key-file /etc/nginx/ssl/cyanfish.site/key.pem \ --fullchain-file /etc/nginx/ssl/cyanfish.site/fullchain.cer \ --reloadcmd "service nginx reload"
💡重要提示:
Nginx 的配置项 ssl_certificate
需要使用 /etc/nginx/ssl/fullchain.cer
,而非 /etc/nginx/ssl/<domain>.cer
,否则 SSL Labs 的测试会报证书链问题(Chain issues Incomplete
)。
默认情况下,证书每 60 天更新一次(可自定义)。更新证书后,Apache 或者 Nginx 服务会通过 reloadcmd
传递的命令自动重载配置。
注意:reloadcmd
非常重要。证书会自动申请续签,但是如果没有正确的 reloadcmd
命令,证书可能无法被重新应用到 Apache 或者 Nginx,因为配置没有被重载。
我又遇到问题了,执行时提示权限不足,无法创建文件;尝试用管理员用户执行则提示找不到acme.sh的命令
1 2 3 4 5 6 7 ubuntu@VM-16-3-ubuntu:/etc/nginx$ acme.sh --install-cert -d cyanfish.site --key-file /etc/nginx/ssl/cyanfish.site/key.pem --fullchain-file /etc/nginx/ssl/cyanfish.site/fullchain.cer --reloadcmd "service nginx reload" [Tue Sep 9 11:22:02 AM CST 2025] The domain 'cyanfish.site' seems to already have an ECC cert, let 's use it. [Tue Sep 9 11:22:02 AM CST 2025] Installing key to: /etc/nginx/ssl/cyanfish.site/key.pem touch: cannot touch ' /etc/nginx/ssl/cyanfish.site/key.pem': Permission denied ubuntu@VM-16-3-ubuntu:/etc/nginx$ sudo acme.sh --install-cert -d cyanfish.site --key-file /etc/nginx/ssl/cyanfish.site/key.pem --fullchain-file /etc/nginx/ssl/cyanfish.site/fullchain.cer --reloadcmd "service nginx reload" sudo: acme.sh: command not found ubuntu@VM-16-3-ubuntu:/etc/nginx$
问题解决:将ubuntu用户安装的acme.sh脚本的环境变量链接给root用户,这样root用户就可以执行acme.sh命令了,链接命令如下:
1 sudo ln -s /home/ubuntu/.acme.sh/acme.sh /usr/local/bin/acme.sh
使用–version命令验证,成功的输出如下:
1 2 3 4 ubuntu@VM-16-3-ubuntu:/etc/nginx$ sudo ln -s /home/ubuntu/.acme.sh/acme.sh /usr/local/bin/acme.sh ubuntu@VM-16-3-ubuntu:~$ sudo acme.sh --version https://github.com/acmesh-official/acme.sh v3.1.2
回到主线,继续尝试执行安装证书命令 ,仍然报错😅,说检测到你在用sudo 执行命令,让你看一下文档:
1 2 3 ubuntu@VM-16-3-ubuntu:/etc/nginx$ sudo acme.sh --install-cert -d cyanfish.site --key-file /etc/nginx/ssl/cyanfish.site/key.pem --fullchain-file /etc/nginx/ssl/cyanfish.site/fullchain.cer --reloadcmd "service nginx reload" It seems that you are using sudo, please read this page first: https://github.com/acmesh-official/acme.sh/wiki/sudo
遵照提示看了下文档内容,说是不推荐使用sudo执行,如果权限配置不正确可能会导致后续自动更新脚本执行失败,那么我们转变思路,为ubuntu用户授予ssl目录的读写权限,这样ubuntu用户就可以创建和写文件了:
1 2 3 4 5 6 7 8 9 sudo usermod -aG www-data ubuntu sudo chown -R root:www-data /etc/nginx/ssl sudo chmod -R 775 /etc/nginx/ssl newgrp www-data
再次尝试执行安装证书命令 ,又遇到了新的问题😅——提示ubuntu用户没有权限执行service nginx reload
命令,并且提示输入root用户的密码:
1 2 3 4 5 6 7 8 9 10 11 12 ubuntu@VM-16-3-ubuntu:/etc/nginx/ssl/cyanfish.site$ acme.sh --install-cert -d cyanfish.site --key-file /etc/nginx/ssl/cyanfish.site/key.pem --fullchain-file /etc/nginx/ssl/cyanfish.site/fullchain.cer --reloadcmd "service nginx reload" [Tue Sep 9 11:48:43 AM CST 2025] The domain 'cyanfish.site' seems to already have an ECC cert, let 's use it. [Tue Sep 9 11:48:43 AM CST 2025] Installing key to: /etc/nginx/ssl/cyanfish.site/key.pem [Tue Sep 9 11:48:43 AM CST 2025] Installing full chain to: /etc/nginx/ssl/cyanfish.site/fullchain.cer [Tue Sep 9 11:48:43 AM CST 2025] Running reload cmd: service nginx reload ==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units === Authentication is required to reload ' nginx.service'. Authenticating as: qcloud (ubuntu) Password: Failed to reload nginx.service: Connection timed out See system logs and ' systemctl status nginx.service' for details. polkit-agent-helper-1: pam_authenticate failed: Authentication failure [Tue Sep 9 11:49:08 AM CST 2025] Reload error for: cyanfish.site
那么我们现在需要给ubuntu用户免密执行该命令的权限,给reloadcmd加一个sudo试试:
1 2 3 4 acme.sh --install-cert -d cyanfish.site \ --key-file /etc/nginx/ssl/cyanfish.site/key.pem \ --fullchain-file /etc/nginx/ssl/cyanfish.site/fullchain.cer \ --reloadcmd "sudo service nginx reload"
执行成功😆,输出如下:
1 2 3 4 5 6 7 8 9 ubuntu@VM-16-3-ubuntu:/etc/nginx/ssl/cyanfish.site$ acme.sh --install-cert -d cyanfish.site \ --key-file /etc/nginx/ssl/cyanfish.site/key.pem \ --fullchain-file /etc/nginx/ssl/cyanfish.site/fullchain.cer \ --reloadcmd "sudo service nginx reload" [Tue Sep 9 11:56:47 AM CST 2025] The domain 'cyanfish.site' seems to already have an ECC cert, let 's use it. [Tue Sep 9 11:56:47 AM CST 2025] Installing key to: /etc/nginx/ssl/cyanfish.site/key.pem [Tue Sep 9 11:56:47 AM CST 2025] Installing full chain to: /etc/nginx/ssl/cyanfish.site/fullchain.cer [Tue Sep 9 11:56:47 AM CST 2025] Running reload cmd: sudo service nginx reload [Tue Sep 9 11:56:47 AM CST 2025] Reload successful
5.查看已安装的证书信息: 执行如下命令,验证证书是否安装成功:
1 acme.sh --info -d cyanfish.site
输出如下,说明证书已安装成功,且证书每 60 天自动更新,你无需任何操作!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ubuntu@VM-16-3-ubuntu:/etc/nginx/ssl/cyanfish.site$ acme.sh --info -d cyanfish.site [Tue Sep 9 11:58:11 AM CST 2025] The domain 'cyanfish.site' seems to already have an ECC cert, let 's use it. DOMAIN_CONF=/home/ubuntu/.acme.sh/cyanfish.site_ecc/cyanfish.site.conf Le_Domain=cyanfish.site Le_Alt=*.cyanfish.site Le_Webroot=dns_dp Le_PreHook= Le_PostHook= Le_RenewHook= Le_API=https://acme.zerossl.com/v2/DV90 Le_Keylength=ec-256 Le_OrderFinalize=https://acme.zerossl.com/v2/DV90/order/dNSnMfE8Co8UsJDEUOWRdQ/finalize Le_RealCertPath= Le_RealCACertPath= Le_RealKeyPath=/etc/nginx/ssl/cyanfish.site/key.pem Le_ReloadCmd=sudo service nginx reload Le_RealFullChainPath=/etc/nginx/ssl/cyanfish.site/fullchain.cer Le_LinkOrder=https://acme.zerossl.com/v2/DV90/order/dNSnMfE8Co8UsJDEUOWRdQ Le_LinkCert=https://acme.zerossl.com/v2/DV90/cert/AIS4u6H7W6dZjVE1EebE5Q Le_CertCreateTime=1757389672 Le_CertCreateTimeStr=2025-09-09T03:47:52Z Le_NextRenewTimeStr=2025-11-07T03:47:52Z Le_NextRenewTime=1762487272
6.配置nginx中网站的ssl证书信息: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 # HTTPS 配置(新增) server { listen 443 ssl http2; server_name cyanfish.site www.cyanfish.site; #网站域名 # SSL 证书配置 ssl_certificate /etc/nginx/ssl/cyanfish.site/fullchain.pem; ssl_certificate_key /etc/nginx/ssl/cyanfish.site/key.pem; # SSL 协议和加密配置 ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; # 安全头部 add_header X-Frame-Options "SAMEORIGIN"; add_header X-XSS-Protection "1; mode=block"; add_header Cache-Control "public, max-age=3600"; # 网站内容配置 location / { root /var/www/blog/public; #网站内容路径 index index.html index.htm; try_files $uri $uri.html $uri/ =404; expires 7d; } }
至此,服务器本地的ssl证书更新自动化已完成!😋
证书上传及CDN配置自动化 如果你的网站使用了CDN加速,那么还需要上传服务器本地的证书到CDN服务商,并配置绑定到CDN加速的域名,具体实践步骤如下:
1.工具安装 本过程全程依赖于腾讯云提供的证书上传及CDN配置接口,都需要通过腾讯官方命令行工具tccli
来调用,先执行如下安装命令:
1 sudo pip install tccli-intl-en
安装成功的输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 root@VM-16-3-ubuntu:/home/ubuntu Looking in indexes: http://mirrors.tencentyun.com/pypi/simple Collecting tccli-intl-en Downloading http://mirrors.tencentyun.com/pypi/packages/12/37/ea374b123a0bb01c60011538ad3a5f526e7846165657b3bfa2a1de1250e5/tccli_intl_en-3.0.1255.1-py2.py3-none-any.whl (5.6 MB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5.6/5.6 MB 9.3 MB/s eta 0:00:00 Collecting tencentcloud-sdk-python-intl-en>=3.0.1255 Downloading http://mirrors.tencentyun.com/pypi/packages/6e/bb/b5647cfecc7063fa6978de742abba1c4783d244c67c6e2513481bcef22d1/tencentcloud_sdk_python_intl_en-3.0.1273-py2.py3-none-any.whl (6.7 MB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 6.7/6.7 MB 9.4 MB/s eta 0:00:00 Collecting jmespath==0.10.0 Downloading http://mirrors.tencentyun.com/pypi/packages/07/cb/5f001272b6faeb23c1c9e0acc04d48eaaf5c862c17709d20e3469c6e0139/jmespath-0.10.0-py2.py3-none-any.whl (24 kB) Requirement already satisfied: six==1.16.0 in /usr/lib/python3/dist-packages (from tccli-intl-en) (1.16.0) Requirement already satisfied: requests>=2.16.0 in /usr/lib/python3/dist-packages (from tencentcloud-sdk-python-intl-en>=3.0.1255->tccli-intl-en) (2.25.1) Installing collected packages: tencentcloud-sdk-python-intl-en, jmespath, tccli-intl-en Successfully installed jmespath-0.10.0 tccli-intl-en-3.0.1255.1 tencentcloud-sdk-python-intl-en-3.0.1273 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv root@VM-16-3-ubuntu:/home/ubuntu 3.0.1255.1
然后配置tccli,使其获得操作权限
1 2 tccli configure set secretId "你的腾讯云secretId" tccli configure set secretKey "你的腾讯云secretKey"
腾讯云API的secretId和sercretKey可以从腾讯云官网-访问管理 中获取,建议添加子用户,并配置CDN及SSL的全读写权限
2.证书上传 tccli配置完成后执行如下命令,测试能否上传证书:
1 2 3 4 5 tccli ssl UploadCertificate \ --CertificatePublicKey "$(cat /etc/nginx/ssl/cyanfish.site/fullchain.cer) " \ --CertificatePrivateKey "$(cat /etc/nginx/ssl/cyanfish.site/key.pem) " \ --CertificateType "SVR" \ --Alias "cyanfish-site-cert-$(date +%Y%m%d) "
成功的输出如下:
1 2 3 4 5 6 7 8 9 10 ubuntu@VM-16-3-ubuntu:~$ tccli ssl UploadCertificate \ --CertificatePublicKey "$(cat /etc/nginx/ssl/cyanfish.site/fullchain.cer) " \ --CertificatePrivateKey "$(cat /etc/nginx/ssl/cyanfish.site/key.pem) " \ --CertificateType "SVR" \ --Alias "cyanfish-site-cert-$(date +%Y%m%d) " { "CertificateId" : "RH5n72W9" , "RepeatCertId" : "" , "RequestId" : "59be0db8-395d-48ef-a5b4-a0473f1319c8" }
🧐参数里的SVR是什么?
这是与另一种证书类型 CA (Certificate Authority,证书颁发机构证书)相对应的证书类型,也就是服务器证书,固定这么写就行了。
SVR与CA证书的对比如下:
证书类型 (CertificateType)
用途
示例
SVR
服务器证书 。用于证明服务器身份,建立 HTTPS 加密连接。
你的网站 cyanfish.site
使用的 SSL 证书。
CA
CA 根证书或中间证书 。用于签发和验证其他证书的身份。
Let‘s Encrypt、DigiCert 等机构自己的证书。
然后上腾讯云看一下,新证书果然已经上传,美滋滋😋:
3.证书配置 证书上传完成后,还需要将新证书配置给CDN加速的域名,执行如下命令即可:
1 2 3 4 tccli cdn ModifyDomainConfig --cli-unfold-argument \ --Domain cyanfish.site \ --Route Https.CertInfo.CertId \ --Value '{"update":"这里换成你上传的新证书ID"}'
证书ID获取 :
细心的小伙伴可能注意到了,之前上传证书完成后,控制台打印了一个json,这其中就有新证书的ID
这个证书ID可以从之前的控制台复制,如果你找不到了,也可以到腾讯云SSL控制台 里找到,将其复制下来,填入上面的ID位置,来验证证书配置命令
成功的输出如下:
1 2 3 4 5 6 7 ubuntu@VM-16-3-ubuntu:~$ tccli cdn ModifyDomainConfig --cli-unfold-argument \ --Domain cyanfish.site \ --Route Https.CertInfo.CertId \ --Value '{"update":"RHPxxK6n"}' { "RequestId" : "b2cf9133-e5dd-45a0-a8cd-ff23c644e872" }
4.证书上传及配置自动化 上面的两个脚本如果添加到acme.sh的reloadcmd参数中也能实现自动化,但如果后续需要修改某些参数则不利于维护。
sh脚本封装 我这里将命令写到一个sh脚本中,并存放到/usr/local/bin/
目录下,命名为uploadCert:
1 touch /usr/local/bin/uploadCert
写入如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 #!/bin/bash echo "开始执行ssl证书上传脚本,版本:0.9" DOMAINS=("cyanfish.site" "picture.cyanfish.site" "demo.cyanfish.site" ) CERT_PUBLIC_KEY_FILE="/etc/nginx/ssl/cyanfish.site/fullchain.cer" CERT_PRIVATE_KEY_FILE="/etc/nginx/ssl/cyanfish.site/key.pem" if [ ! -f "$CERT_PUBLIC_KEY_FILE " ] || [ ! -f "$CERT_PRIVATE_KEY_FILE " ]; then echo "错误:证书文件不存在!" echo "公钥路径: $CERT_PUBLIC_KEY_FILE " echo "私钥路径: $CERT_PRIVATE_KEY_FILE " exit 1 fi echo "正在上传证书到腾讯云..." CERT_JSON=$(tccli ssl UploadCertificate \ --CertificatePublicKey "$(cat "$CERT_PUBLIC_KEY_FILE " ) " \ --CertificatePrivateKey "$(cat "$CERT_PRIVATE_KEY_FILE " ) " \ --CertificateType SVR \ --Alias "multi-domain-cert-$(date +%Y%m%d-%H%M%S) " ) CERT_ID=$(echo "$CERT_JSON " | jq -r '.CertificateId' ) if [ -z "$CERT_ID " ]; then echo "错误:获取 CertificateId 失败!原始响应:" echo "$CERT_JSON " exit 1 fi echo "证书上传成功,CertificateId: $CERT_ID " for DOMAIN in "${DOMAINS[@]} " ; do echo "正在配置 CDN 域名 $DOMAIN 使用新证书..." tccli cdn ModifyDomainConfig --cli-unfold-argument --Domain "$DOMAIN " --Route "Https.CertInfo.CertId" --Value "{\"update\":\"$CERT_ID \"}" if [ $? -eq 0 ]; then echo "域名 $DOMAIN 证书配置成功!" else echo "警告:域名 $DOMAIN 证书配置可能失败!" fi done echo "所有域名证书部署完成!"
🛠代码中的jq工具
为了解析JSON中的证书ID,使用了jq工具,安装jq:
执行如下命令测试jq,可以看到jq正确解析出了JSON中我们想要的值:
1 2 ubuntu@VM-16-3-ubuntu:~$ echo '{"CertificateId":"cert-123"}' | jq -r '.CertificateId' cert-123
为uploadCert
脚本添加可执行权限:
1 sudo chmod +x /usr/local/bin/uploadCert
执行脚本验证可用性:
成功的输出如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ubuntu@VM-16-3-ubuntu:/usr/local/bin$ uploadCert 开始执行ssl证书上传脚本,版本:0.9 正在上传证书到腾讯云... 证书上传成功,CertificateId: RHPawZEw 正在配置 CDN 域名 cyanfish.site 使用新证书... { "RequestId" : "df322dd6-e364-4109-a085-4517bcd3bab3" } 域名 cyanfish.site 证书配置成功! 正在配置 CDN 域名 picture.cyanfish.site 使用新证书... { "RequestId" : "825b8a2e-1b64-409d-9fbd-1aaf8b5f1a6e" } 域名 picture.cyanfish.site 证书配置成功! 正在配置 CDN 域名 demo.cyanfish.site 使用新证书... { "RequestId" : "ec66dcc2-ba9c-41e5-bb81-ddba5cb12e8c" } 域名 demo.cyanfish.site 证书配置成功! 所有域名证书部署完成!
acme.sh配置 然后执行如下命令,更新acme.sh的reloadcmd:
1 2 3 4 acme.sh --install-cert -d cyanfish.site \ --key-file /etc/nginx/ssl/cyanfish.site/key.pem \ --fullchain-file /etc/nginx/ssl/cyanfish.site/fullchain.cer \ --reloadcmd "sudo service nginx reload && uploadCert"
💡reloadcmd参数是一个命令,每60天(默认)acme.sh更新ssl证书时,会自动触发该参数中配置的命令
❤执行以上命令后,每次证书更新后,nginx会重启应用证书的更新,并且会执行uploadCert脚本
最终成功的输出如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 ubuntu@VM-16-3-ubuntu:/usr/local/bin$ acme.sh --install-cert -d cyanfish.site \ --key-file /etc/nginx/ssl/cyanfish.site/key.pem \ --fullchain-file /etc/nginx/ssl/cyanfish.site/fullchain.cer \ --reloadcmd "sudo service nginx reload && uploadCert" [Tue Sep 9 09:39:07 PM CST 2025] The domain 'cyanfish.site' seems to already have an ECC cert, let 's use it. [Tue Sep 9 09:39:07 PM CST 2025] Installing key to: /etc/nginx/ssl/cyanfish.site/key.pem [Tue Sep 9 09:39:07 PM CST 2025] Installing full chain to: /etc/nginx/ssl/cyanfish.site/fullchain.cer [Tue Sep 9 09:39:07 PM CST 2025] Running reload cmd: sudo service nginx reload && uploadCert 开始执行ssl证书上传脚本,版本:0.9 正在上传证书到腾讯云... 证书上传成功,CertificateId: RHPxxK6n 正在配置 CDN 域名 cyanfish.site 使用新证书... { "RequestId": "f5d3cf3e-34db-4845-85a9-72472a843c6a" } 域名 cyanfish.site 证书配置成功! 正在配置 CDN 域名 picture.cyanfish.site 使用新证书... { "RequestId": "ece0e617-d6c0-4552-beac-b5e7402fdd8e" } 域名 picture.cyanfish.site 证书配置成功! 正在配置 CDN 域名 demo.cyanfish.site 使用新证书... { "RequestId": "4a9aaf4d-2b6a-40de-9202-57fd00b0b855" } 域名 demo.cyanfish.site 证书配置成功! 所有域名证书部署完成! [Tue Sep 9 09:39:16 PM CST 2025] Reload successful ubuntu@VM-16-3-ubuntu:/usr/local/bin$
最后上腾讯云看一眼CDN里的证书,配置成功!😆
大功告成,妈妈再也不用担心我每三个月都要手动申请并上传一次ssl证书了,好耶!ㄟ(≧◇≦)ㄏ
最终成果
✅ 证书自动申请和续期(每60天)
✅ 自动安装到本地 Nginx
✅ 自动上传到腾讯云 SSL 证书服务
✅ 自动配置到所有 CDN 域名
✅ 全程无需人工干预
参考资料 1.acme.sh官网中文文档
2.tccli官方文档
3.nginx SSL配置指南