缘由
写这篇文章的原因是本人的博客收到了证书过期错误, 在Egde Beta浏览器无法访问, 故写了此篇文章来记录

介绍
由AI生成, 本人验证
使用 acme.sh
这类 ACME 客户端(特别是对接 Let's Encrypt 等免费 CA)来实现自动化申请和续订 TLS 证书,相比传统的到商业证书运营商(如 DigiCert, Sectigo, GlobalSign 等)手动申请证书,具有显著的优势,尤其是在自动化、成本和效率方面。
以下是详细的对比和优点分析:
✅ 1. 完全自动化(核心优势)
传统方式 | 使用 acme.sh |
---|---|
需要手动登录运营商网站,填写信息,选择域名,选择验证方式(文件验证、DNS验证、邮箱验证等),下载证书文件,再手动上传部署。 | 一行命令即可完成申请和部署,支持自动续期(默认每60天检查一次)。 |
续期也需要在证书到期前手动操作,容易忘记导致证书过期。 | acme.sh 安装时会自动创建 cron 定时任务,到期自动续期,无需人工干预。 |
高风险:一旦忘记续期,网站 HTTPS 会中断,影响用户体验和 SEO。 | 零风险:自动化流程确保证书永远有效。 |
🌟 优点总结 :省时、省力、避免人为失误,实现真正的"设置一次,永久有效" 。
✅ 2. 成本极低(通常是免费)
传统方式 | 使用 acme.sh |
---|---|
商业证书价格较高,尤其是 EV 证书或多域名证书,每年需要支付几百到上千元不等。 | 对接 Let's Encrypt 是完全免费的,不限制申请数量。 |
即使是便宜的 DV 证书,长期累积也是一笔开销。 | 0 成本,特别适合个人博客、开发测试、中小项目、微服务等场景。 |
💰 优点总结 :大幅降低 HTTPS 部署成本,推动全网加密普及。
✅ 3. 快速部署,即时生效
传统方式 | 使用 acme.sh |
---|---|
验证、审核、签发可能需要几分钟到几小时(尤其是 EV 证书)。 | 从申请到签发通常在 10-30 秒内完成,特别适合 CI/CD、容器化、Serverless 等动态环境。 |
无法满足快速上线需求。 | 可集成到自动化部署脚本中,新服务上线即拥有 HTTPS。 |
⚡ 优点总结 :极速响应,适合现代 DevOps 流程。
✅ 4. 支持现代验证方式(尤其是 DNS-01)
传统方式 | 使用 acme.sh |
---|---|
多数依赖 HTTP-01(需开放 80 端口)或邮箱验证。 | 支持多种验证方式,尤其是 DNS-01 API 自动化验证。 |
通配符证书申请复杂,价格昂贵。 | 使用 --dns dns_dp 等参数,一键申请通配符证书(*.example.com ) ,且免费。 |
在内网、无公网 IP、或 80/443 端口被占用的场景下难以部署。 | 只要能调用 DNS API,即可完成验证,不受网络拓扑限制。 |
🌐 优点总结 :灵活性强,适用场景更广。
✅ 5. 易于集成和管理
传统方式 | 使用 acme.sh |
---|---|
每个证书独立管理,容易混乱。 | 所有证书集中管理在 ~/.acme.sh/ 目录下,结构清晰。 |
需要手动配置 Web 服务器(Nginx/Apache)指向新证书。 | 使用 --install-cert 可自动复制证书到指定路径,并通过 --reloadcmd 自动重载服务(如 systemctl reload nginx )。 |
难以批量管理多个域名。 | 支持批量脚本化管理多个域名的证书。 |
🔧 优点总结 :标准化、可编程、易于运维。
⚠️ 传统商业证书的优势(acme.sh 的不足)
虽然 acme.sh
优势明显,但传统商业证书在某些场景下仍有价值:
场景 | 传统商业证书优势 |
---|---|
企业信任度要求高 | EV 证书会在浏览器地址栏显示公司名称,增强用户信任(Let's Encrypt 不提供 EV)。 |
需要更长有效期 | 商业证书可购买 1-2 年有效期;Let's Encrypt 证书最长 90 天(acme.sh 自动续期弥补了这一点)。 |
需要保险和 SLA 保障 | 商业 CA 通常提供证书保险(如签发错误导致损失可赔偿)和更高 SLA。 |
私有 CA 或内部 PKI | 企业内网可能使用私有 CA,不依赖公共 ACME 服务。 |
✅ 总结:何时选择 acme.sh?
使用场景 | 推荐方案 |
---|---|
个人网站、博客、开发测试环境 | ✅ 强烈推荐 acme.sh + Let's Encrypt |
中小型企业官网、API 服务、微服务架构 | ✅ 推荐 acme.sh ,成本低、自动化强 |
需要通配符证书的项目 | ✅ 首选 acme.sh (免费 + 自动化) |
对品牌信任要求极高(如银行、支付) | ⚠️ 考虑商业 EV 证书 |
内网或私有 CA 环境 | ⚠️ 使用企业内部 PKI 方案 |
🔚 结论
对于绝大多数现代 Web 应用和服务,使用 acme.sh
实现自动化申请和续订 TLS 证书,相比传统手动申请方式,具有压倒性的优势:
自动化 + 免费 + 快速 + 灵活 = 更高效、更安全、更现代的 HTTPS 管理方式。
它已经成为 DevOps 和云原生环境中事实上的标准工具之一。除非有特殊的企业信任或合规需求,否则 acme.sh
是部署 HTTPS 的首选方案。
安装
通常情况下, 网站,应用都在服务器里部署,服务器环境一般都使用Linux系统, 所以要求Linux发行版有Git
软件,多数的发行版都内置, 直接运行以下脚本即可, 或者在宿主机pull下来, 然后传递给服务器
bash
git clone https://github.com/acmesh-official/acme.sh.git
cd ./acme.sh
cp ./acme.sh /usr/local/bin
使用
根据你的域名所在的运营商, 例如腾讯云的DNSPod, 阿里云, cloudflare等,不同的运营商, 脚本有区别,这里以DNSPod来演示
使用DNSPod方式生成证书
- 访问DNSPod
- 创建密钥并填写到下方的
DP_Id
和DP_Key
变量中
填写对应的变量, 然后在服务器执行该脚本, 等待执行完毕之后留意结果, 它会告诉你TLS证书文件的位置.
证书文件通常是
fullchain.cer
。强烈推荐使用fullchain
文件 ,因为它不仅包含你的域名证书,还包含了必要的中间证书(Intermediate CA Certificates),这能确保大多数客户端(浏览器、手机等)都能完整地验证证书链,避免出现安全警告。当客户端(如浏览器)连接到你的 Nginx 服务器时,Nginx 会将这个文件里的证书发送给客户端。客户端会验证这个证书是否由可信的 CA 签发、是否在有效期内、域名是否匹配等。验证通过后,客户端会使用证书里的公钥来加密后续通信的密钥。
该脚本适用于第一次安装的情况, 如果后续需要重新生成证书, 重新运行上面的脚本失败时, 那么只需要在脚本末尾添加--force
参数
该脚本为申请一个主域 + 通配符多域名(SAN)证书:
bash
export DP_Id=<你的DNSPod id>
export DP_Key=<你的DNSPod key>
Daomain=<你的网站域名>
acme.sh --issue --dns dns_dp -d $Daomain -d *.$Daomain --keylength ec-256 --debug
参数说明:
--issue
是触发证书申请流程--dns dns_dp
: 使用 DNS 挑战(DNS-01) 方式验证域名所有权,acme.sh
会自动调用 DNSPod 的 API,在你的域名下添加一条_acme-challenge
的 TXT 记录来完成验证, 验证完成后, 会自动删除该 TXT 记录(临时添加), 它支持申请通配符证书(*.example.com
),无需开放 80/443 端口-d
或--domain
: 指定你要为哪些域名申请证书--keylength ec-256
: 指定生成的私钥类型和长度。ec-256
表示使用 椭圆曲线加密(ECC) ,具体是 prime256v1(NIST P-256) 曲线, 相比传统的 RSA 2048,ECC 提供了更高的安全性和更小的密钥体积,性能更好。可选值还包括:ec-384
,ec-521
,2048
,3072
,4096
等。--debug
: 开启调试模式,输出详细的日志信息
之后就可以复制证书文件到其他位置来使用了 例如:
bash
dir=/root/.acme.sh/example.com_ecc/
daomain=example.com
cp $dir/fullchain.cer /home/docker/nginx/ssl/nginx.crt
cp $dir/$daomain.key /home/docker/nginx/ssl/nginx.key
在Docker的nginx里使用TLS证书
示例nginx.conf:
ini
server {
listen 80;
server_name ${DOMAIN};
return 301 https://$host$request_uri;
}
server {
server_name ${DOMAIN} www.${DOMAIN};
# HTTP/3 with QUIC
listen 443 quic reuseport;
# HTTP/2 and HTTP/1.1
listen 443 ssl;
http2 on;
# Security headers
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Frame-Options SAMEORIGIN always;
add_header X-Content-Type-Options nosniff always;
add_header Alt-Svc 'h3=":443"; ma=86400; h3-29=":443"; ma=86400';
# SSL/TLS configuration
ssl_protocols TLSv1.3 TLSv1.2;
ssl_ecdh_curve X25519:P-256:P-384;
# 通用兼容性密码套件
ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256";
ssl_prefer_server_ciphers on;
# 显式声明 TLS 1.3 密码(需要 OpenSSL 1.1.1+)
ssl_conf_command Ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256;
# SSL certificates
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
location / {
root /etc/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}
方式1: 将证书文件(.crt或.pem或.cer后缀文件)和私钥文件(.key后缀文件)复制到nginx容器里
xml
docker cp <证书文件> <容器名称>:<nginx的ssl_certificate参数指定的文件路径>
docker cp <私钥文件> <容器名称>:<nginx的ssl_certificate_key参数指定的文件路径>
例如:
bash
docker cp "*.example.com_ecc/fullchain.cer" blog:/etc/nginx/ssl/nginx.cer
docker cp "*.example.com.key" blog:/etc/nginx/ssl/nginx.key
方式2: 将证书路径挂载到容器里
yml
services:
blog:
image: example/blog # 这里需要替换成你的镜像
container_name: blog # 镜像名称
build:
context: .
dockerfile: .
target: final
ports:
- '80:80'
- '443:443'
- '443:443/udp'
# 环境变量
environment:
DOMAIN: example.com # 这里需要替换成你的域名
restart: on-failure:4 # 重启策略,最多重启n次
volumes:
- /home/docker/blog/conf:/etc/nginx/conf.d # nginx.conf目录路径
- /home/docker/nginx/ssl:/etc/nginx/ssl:ro # tls证书文件目录路径
续订证书
一般情况下, acme.sh60天自动更新一次证书过期时间, 如果没有自动更新, 可以使用以下脚本来手动更新: 强制续订证书,默认是每60天自动更新:
bash
export DP_Id=<你的DNSPod id>
export DP_Key=<你的DNSPod key>
Daomain=<你的网站域名>
acme.sh --renew -d $Daomain --force
常见问题
Q: nginx无法读取文件, 缺少read权限: 2025/08/27 14:18:43 [emerg] 1#1: cannot load certificate key "/etc/nginx/ssl/nginx.key": BIO_new_file() failed (SSL: error:8000000D:system library::Permission denied:calling fopen(/etc/nginx/ssl/nginx.key, r) error:10080002:BIO routines::system lib)
bash
ls -l
out:
diff
-rw-r--r-- 1 root root 4116 Aug 27 22:17 nginx.crt
-rw-r----- 1 root root 227 Aug 27 22:17 nginx.key
A: 给对应的文件添加read权限:
bash
chmod +r nginx.key
Q: 查看证书是否过期: A:
- 方式1: 直接查看你的网站的锁图标的详细信息

- 方式2: 使用
openssl
工具:
bash
openssl x509 -in <证书文件> -noout -dates