CentOS搭建:HTTPS证书
acme.sh:纯 Shell 实现的 ACME 协议客户端(ACME 是 Let's Encrypt 等证书机构使用的自动化签发协议),不依赖 Python,适合 CentOS 7 这类已停止维护的系统。
HTTPS:在 HTTP 之上套了一层 TLS 加密,浏览器地址栏出现锁标即为生效。HTTP/2 依赖 TLS,因此必须先有证书才能谈提速。
环境依赖
| 软件/环境 | 版本 | 包名/来源 | 备注 |
|---|---|---|---|
| Linux | CentOS 7.x | - | 宿主机 OpenSSL 为 1.0.2k,不支持 TLS 1.3(容器内另算) |
| Nginx | 1.24+ | 需含 --with-http_ssl_module | nginx -V 可查;开启 HTTP/2 需 1.25.1+ |
| acme.sh | 3.x | https://get.acme.sh | 纯 Shell,无需编译 |
| 防火墙 | - | firewalld / 云安全组 | 必须放行 80 与 443,80 是证书签发与续期的通道 |
| 域名 | - | DNS 解析至本机公网 IP | 解析未生效则签发必失败 |
⚠️ 80 与 443 的用途不同:80 端口用于证书签发/续期期间被 CA 机器人访问,签发完成后可保留可跳转;443 才是用户实际访问的加密端口。
原理:CA 怎么确认域名是你的
签发证书前,证书机构(CA)必须确认"这个域名确实归你管",这个确认过程叫挑战(challenge),具体做法在 ACME 协议(RFC 8555)里有固定几种写法,每种叫一个挑战类型:
- HTTP-01:CA 派机器人访问
http://<域名>/.well-known/acme-challenge/<随机串>,能读到指定内容就放行——等价于一个普通访客读网页; - DNS-01:要求你在
_acme-challenge.<域名>的 TXT 记录里写一个指定值,需要 DNS 服务商 API 密钥,泛域名(*.xxx.com)只能走这条; - tls-alpn-01:走 TLS 握手完成验证,几乎无人使用。
为什么选 HTTP-01:① 80 端口本来就开着;② 零密钥,不需要 DNS 服务商 API;③ 配 webroot 模式后,验证文件落在站点目录内,签发全程不必停 Nginx、不必重启容器。代价是要求 80 端口公网可达,且不能签泛域名。
"HTTP-01 能自动续期"这一点常被误解——不只是 DNS API 能自动续期,HTTP-01 同样全自动(定时任务到点自动重跑);两者差别只在续期时那次校验走网站还是走 DNS。
SAN(Subject Alternative Name,证书主体备用名):一张证书可以覆盖哪些域名。现代浏览器只看 SAN,不看 CN 字段,所以多域名必须签在同一张证书的 SAN 里。
前置检查
# 1. 确认域名已解析到本机(应返回本机公网 IP)
dig +short www.example.com
# 2. 确认 80 端口未被占用,且防火墙放行
netstat -tunlp | grep ':80 '
sudo firewall-cmd --list-ports
# 3. 确认 Nginx 已编译 SSL 模块(应含 with-http_ssl_module)
sudo nginx -V 2>&1 | tr ' ' '\n' | grep http_ssl
# 4. 确认未安装过其它证书工具,避免 crontab 任务打架
which certbot
ls -d ~/.acme.sh 2>/dev/null| 检查项 | 不通过的后果 |
|---|---|
| 域名解析 | CA 机器人访问到的是别人的服务器,签发必失败 |
| 80 端口被占 | Nginx 起不来,或验证文件取不到 |
| 缺少 ssl 模块 | Nginx 无法提供 HTTPS,需重新编译安装 |
| 已存在 certbot | 两套定时任务可能互相吊销证书 |
安装 acme.sh
# 一行安装:邮箱用于 CA 账户注册与到期提醒(Let's Encrypt 已取消邮件提醒,但部分 CA 仍要求填)
curl https://get.acme.sh | sh -s email=your_email@example.com
# 让 acme.sh 的快捷命令(acme.sh / acme.sh-cron)写入当前 shell 的别名
source ~/.bashrc
# 确认版本与安装位置(默认 ~/.acme.sh)
acme.sh --version
# 切换默认 CA 为 Let's Encrypt(acme.sh 默认是 ZeroSSL,不切会走 ZeroSSL)
acme.sh --set-default-ca --server letsencrypt
# 确认自动续期的定时任务已登记(应有一条 acme.sh --cron)
crontab -l | grep acme
acme.sh安装时会自动往 crontab 追加一条acme.sh --cron任务,此时没有证书,任务空转,属正常。
acme.sh 卸载:
acme.sh --uninstall && rm -rf ~/.acme.sh
crontab -e # 手动删除 acme.sh --cron 那一行验证目录与 Nginx 配置
webroot 模式的关键约定:acme.sh 会把验证文件写在 <webroot>/.well-known/acme-challenge/ 下,而不是直接写在 <webroot> 根目录。
# 建验证目录(推荐直接用站点根目录,避免多套一层目录导致路径算错)
sudo mkdir -p /usr/share/nginx/html/.well-known/acme-challenge在 80 端口的 server 块内插入(放在 location / 之前,^~ 表示前缀匹配优先级高于正则):
server {
listen 80;
server_name www.example.com;
# 证书验证专用通道:对外提供 /.well-known/acme-challenge/ 下的文件
location ^~ /.well-known/acme-challenge/ {
root /usr/share/nginx/html;
}
location / {
# ... 原有站点配置
}
}先校验再 reload(nginx -t 的输出走 stderr,判据要看退出码):
sudo nginx -t 2>&1
echo "EXIT=$?" # 期望 EXIT=0
sudo nginx -s reload用零成本探针文件验证通道(不要直接拿签发去试错,CA 有每周 5 次的频率限制):
# 按 acme.sh 的真实目录布局造探针文件
echo probe-content-xyz | sudo tee /usr/share/nginx/html/.well-known/acme-challenge/probe-xyz
# 从公网侧访问,期望 200 且内容一致
curl -sI http://www.example.com/.well-known/acme-challenge/probe-xyz
curl -s http://www.example.com/.well-known/acme-challenge/probe-xyz⚠️ 不要用扁平文件测。随手在 webroot 根下丢一个
test.txt能返回 200,看似通道正常,但 acme.sh 实际访问的是.well-known/acme-challenge/子路径,签发时照样 404——这叫假绿。测试对象的行为必须与被测对象一致。
常见错误:root 与 alias 的语义差异
给 challenge 配错路径是本流程最高频的坑,两者的语义完全不同:
| 写法 | 语义 | 请求 /.well-known/acme-challenge/x 的实际查找路径 |
|---|---|---|
root /data/html/acme-challenge; | 拼接(root + 完整 URI) | /data/html/acme-challenge/.well-known/acme-challenge/x ← 多一层,404 |
alias /data/html/acme-challenge/; | 整段替换(丢掉匹配前缀) | /data/html/acme-challenge/x |
alias /data/html/acme-challenge/.well-known/acme-challenge/; | 同上 | /data/html/acme-challenge/.well-known/acme-challenge/x ✅ |
推荐做法:直接把 --webroot 指向站点根目录,Nginx 里用 root 指向同一个根目录——此时"拼接"与"替换"恰好等价,两条路都能算对,最不容易错:
# 签发时
acme.sh --issue -d www.example.com --webroot /usr/share/nginx/html
# Nginx 配置
location ^~ /.well-known/acme-challenge/ {
root /usr/share/nginx/html;
}只有当你的 webroot 是一个独立的专用目录(不是站点根)时,才必须用 alias,且 alias 值必须写成 <webroot>/.well-known/acme-challenge/。
签发证书
# 签发:多个 -d 即多域名(全部写进同一张证书的 SAN)
acme.sh --issue \
-d www.example.com \
-d example.com \
--webroot /usr/share/nginx/html \
--server letsencrypt| 参数 | 说明 |
|---|---|
-d | 域名,可重复;根域与 www 都要写,否则访问根域时浏览器报证书错误 |
--webroot | 验证文件落地的目录;等价简写为 -w |
--server letsencrypt | 指定 CA;acme.sh 默认是 ZeroSSL |
--keylength ec-256 | 密钥类型;acme.sh 3.x 默认就是 ECC,通常无需显式指定 |
产物默认落在 ~/.acme.sh/<主域名>_ecc/:
ls -la ~/.acme.sh/example.com_ecc/
# example.com.cer 证书本体
# example.com.key 私钥(私钥不是证书链的组成部分,不可泄露)
# fullchain.cer 证书链(nginx 的 ssl_certificate 要用这个)ECC vs RSA:同等加密强度下 ECC 密钥更短、握手更快、体积更小,是当前首选;只有极老的客户端(不支持 ECC)才需要退回 RSA(
-k 2048,产物目录无_ecc后缀)。
签发频率限制:Let's Encrypt 对同一域名每周最多 5 次签发,失败也算。失败后不要盲目重试,先读错误信息定位(见文末速查表)。
签发结果校验
cd ~/.acme.sh/example.com_ecc/
# 1. 签发主体、签发机构、有效期(期望约 90 天)
openssl x509 -noout -subject -issuer -dates -in fullchain.cer
# 2. SAN 是否覆盖全部域名(期望两个域名都在)
openssl x509 -noout -text -in fullchain.cer | grep -A1 "Subject Alternative Name"
# 3. 30 天内不会过期(退出码 0 即通过)
openssl x509 -noout -checkend 2592000 -in fullchain.cer
echo "EXIT=$?"
# 4. 证书与私钥是否配对(两串 md5 必须相等,不等会在 Nginx 报 495/502)
openssl x509 -in fullchain.cer -pubkey -noout | openssl md5
openssl ec -in example.com.key -pubout | openssl md5安装证书到 Nginx 目录
acme.sh 内部目录名带主域名与版本后缀,不适合直接写进 Nginx 配置(换域名或换 CA 就会失效)。用 --install-cert 把证书复制到固定路径:
# 建证书目录并收紧权限(目录 700、私钥 600,防止同机其他用户读取)
sudo mkdir -p /etc/nginx/certs
sudo chmod 700 /etc/nginx/certs
acme.sh --install-cert -d www.example.com --ecc \
--key-file /etc/nginx/certs/key.pem \
--fullchain-file /etc/nginx/certs/fullchain.pem \
--reloadcmd "sudo nginx -s reload"
# 确认权限与落盘结果
sudo stat -c '%a %n' /etc/nginx/certs /etc/nginx/certs/key.pem /etc/nginx/certs/fullchain.pem| 参数 | 说明 |
|---|---|
--ecc | 选择 ECC 版本证书(对应 _ecc 目录);RSA 证书去掉此参数 |
--key-file | 私钥落地路径,权限必须是 600 |
--fullchain-file | 证书链落地路径,Nginx 的 ssl_certificate 指向它 |
--reloadcmd | 每次自动续期成功后执行,是自动续期闭环的关键,填 Nginx 的 reload 命令 |
--reloadcmd里不要用会退出的命令(如systemctl restart nginx会中断现有连接)。用nginx -s reload热切换,不断连接。命令会被 base64 保护后存进~/.acme.sh/<域名>_ecc/<域名>.conf,可用grep Le_ReloadCmd查看。
自动续期闭环
acme.sh 的续期逻辑是"证书剩余寿命不足 30 天时才真正重新签发",平时定时任务空跑。因此必须做零成本闭环验证:
# 模拟一次定时任务:走完"检查有效期 → 触发续期 → 复制证书 → 执行 reloadcmd"全链路
acme.sh --cron --force 2>&1 | tail -20输出中应出现 Reload successful(或你 --reloadcmd 里那条命令的成功标志)。看到它才说明自动续期真的闭环——否则可能出现"证书 90 天后悄悄过期、reloadcmd 却因路径写错而静默失败"的情况。
配置 Nginx 提供 HTTPS
在原有 80 server 块之外新增一个 443 server 块:
server {
listen 80;
server_name www.example.com;
# 证书验证通道(续期时要用,不能删)
location ^~ /.well-known/acme-challenge/ {
root /usr/share/nginx/html;
}
location / {
# ... 原有站点配置,保持不变
}
}
# 新增:443 server,仅提供 HTTPS
server {
listen 443 ssl;
server_name www.example.com;
# 证书与私钥路径(由 acme.sh --install-cert 落地)
ssl_certificate /etc/nginx/certs/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/key.pem;
# TLS 协议:只保留 TLS 1.2 / 1.3,禁用 SSLv3、TLS 1.0/1.1
ssl_protocols TLSv1.2 TLSv1.3;
# 会话复用:10MB 缓存可存约 4 万条会话,减少重复握手
ssl_session_cache shared:SSL:10m;
# 会话保持时长
ssl_session_timeout 10m;
# 优先使用服务端偏好的加密套件
ssl_prefer_server_ciphers on;
# 根目录、location 等必须与 80 块完全一致,否则 https 与 http 呈现的内容会不同
root /usr/share/nginx/html;
index index.html;
location / {
# ... 与 80 块相同的业务配置
}
}| 配置项 | 作用 |
|---|---|
listen 443 ssl; | 监听 443 并启用 TLS;ssl 关键字不可省略 |
ssl_certificate | 必须指向 fullchain(含中间证书),只填证书本体部分客户端会报"证书链无效" |
ssl_certificate_key | 私钥路径;与证书不配对会报 495/502 |
ssl_protocols | 只留 TLSv1.2 TLSv1.3;TLS 1.3 需要 OpenSSL 1.1.1+ |
ssl_session_cache | 共享内存缓存,避免每次请求都重新握手 |
生效并验证:
sudo nginx -t 2>&1 && echo "EXIT=$?"
sudo nginx -s reload
# https 可访问,期望 200
curl -sI https://www.example.com/ | head -5
# 协议版本(本步骤后期望 1.1,开启 HTTP/2 后变 2)
curl -s -o /dev/null -w "%{http_version}\n" https://www.example.com/
# 证书链信任校验,期望 "Verify return code: 0 (ok)"
echo | openssl s_client -connect www.example.com:443 -servername www.example.com 2>/dev/null | grep -i "Verify return code"检测 TLS 能力要用同环境的 openssl
CentOS 7 宿主机自带 OpenSSL 1.0.2k(2017 年),本身不支持 TLS 1.3,用它去探测会得到"服务端不支持 TLS 1.3"的错误结论——这是客户端能力问题,与服务端无关:
# 宿主机(可能不支持 1.3,不代表服务端不行)
openssl version
# 容器内 Nginx 用的 openssl(与实际提供 TLS 的进程同环境)
docker exec nginx openssl version
docker exec nginx sh -c "echo | openssl s_client -connect 127.0.0.1:443 -servername www.example.com 2>/dev/null | grep -E 'Protocol|Cipher'"
# 强制降级验证 1.2 仍可用
docker exec nginx sh -c "echo | openssl s_client -connect 127.0.0.1:443 -servername www.example.com -tls1_2 2>/dev/null | grep -E 'Protocol|Cipher'"原则:判断服务端能力时,探测工具必须与服务端同环境,否则结论真伪会被工具版本决定。
进阶配置
HTTP 强制跳转 HTTPS
确认 https 稳定可用后再做跳转(改一行 + reload,秒级可回滚):
server {
listen 80;
server_name www.example.com;
# 证书验证通道必须放在跳转之前,否则续期会 301 跟随失败
location ^~ /.well-known/acme-challenge/ {
root /usr/share/nginx/html;
}
# 其余请求一律跳到 https
location / {
return 301 https://$host$request_uri;
}
}不要一签完就做跳转。保留 http 入口意味着 https 出问题时还有退路,且能留出 1~2 天观察期(浏览器锁标、移动端微信内置浏览器表现、搜索引擎收录)。跳转的判据是"用户明确用 http 访问时不再泄露明文",而不是"越早做越好"。
| 维度 | 做跳转 | 不做跳转 |
|---|---|---|
| https 出问题时 | 全站不可达(http 被导走,无退路) | http 仍正常服务 |
| 验证期 | 无独立观察期 | 可观察 1~2 天再决定 |
| 额外成本 | 0 | 后续一次小变更(改一行 + reload) |
多域名场景的坑:若根域 80 块原本就有跳转到 http://www.example.com 的规则,开启 https 后照抄会让 https 访问根域降级回 http。443 块的跳转目标必须写成 https://www.example.com。
开启 HTTP/2
HTTP/2 把 HTTP/1.1 的"单连接串行请求"改为"单连接多路复用",页面里几十上百个请求不再排队等待,首屏加载时间明显下降。前提是先有证书(HTTP/2 over TLS 是浏览器实际支持的形态)。
Nginx 1.25.1 起 http2 是独立指令(新语法):
server {
listen 443 ssl;
http2 on; # 开启 HTTP/2,只加这一行
server_name www.example.com;
ssl_certificate /etc/nginx/certs/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
# ...
}sudo nginx -t 2>&1 && sudo nginx -s reload
# 期望输出 2(若仍是 1.1,说明改动没生效)
curl -s -o /dev/null -w "%{http_version}\n" https://www.example.com/旧写法
listen 443 ssl http2;在 1.25.1+ 已废弃。http2 on;与不写它的差别仅在协议协商——不写它时 443 照常提供 HTTPS(走 HTTP/1.1 over TLS),所以"先上证书、后开 HTTP/2"天然可分两步,互不阻塞。不支持 HTTP/2 的客户端会自动回落 HTTP/1.1,无需额外配置。
证书与私钥的分离存放
私钥不要放在站点根目录下——放在可被 HTTP 直接访问的目录里,等于把私钥公开发布,任何人都能下载。正确做法是独立目录 + 收紧权限:
# 错误示范:/usr/share/nginx/html/certs/ 可被 HTTP 直接下载
# 正确做法:独立目录 + 只对 Nginx 进程可读
sudo mkdir -p /etc/nginx/certs && sudo chmod 700 /etc/nginx/certs
sudo chmod 600 /etc/nginx/certs/key.pem关于 ssl_stapling
浏览器可由服务端"盖章"(OCSP Stapling),省掉一次客户端查询请求。Let's Encrypt 已逐步停止 OCSP 服务,证书链上不再有可用的 OCSP 响应地址,配置 ssl_stapling 不会有收益(甚至可能拖慢握手)。除非使用的是自建 CA 或仍在运营 OCSP 的商业证书,否则不必配置。
Docker 部署场景的额外注意事项
若 Nginx 跑在容器里,除上面所有步骤外还要注意三点:
单文件挂载禁止 sed -i(inode 陷阱)
sed -i 的工作方式是"写临时文件 → 改名替换",会替换文件的 inode;而 Docker 的单文件 bind mount 绑定的是挂载时刻的旧 inode。结果是:宿主机已改、容器永远读旧内容,nginx -t 通过、reload 成功、变更静默无效,全程零报错。
# 错误:换 inode,容器读不到
sudo sed -i 's/old/new/' /data/nginx/conf/nginx.conf
# 正确:cat > 截断写回,inode 不变,容器实时可见
sudo sed 's|old|new|' /data/nginx/conf/nginx.conf > /tmp/nginx.conf.new
sudo cat /tmp/nginx.conf.new > /data/nginx/conf/nginx.conf && rm /tmp/nginx.conf.new强制关卡:reload 前必须从容器内验证配置已更新,宿主机侧任何校验都不能代替。
docker exec nginx grep -c "<变更特征>" /etc/nginx/conf.d/example.conf整目录挂载(如
conf.d/、html/)按路径解析,不受此限制——受影响的只有单文件挂载。宿主机直接用 vim 编辑挂载文件(备份替换式保存)同样可能触发。
证书目录要挂进容器并保持只读
宿主机上的 certs/ 目录需要额外挂进容器;新增挂载必须重建容器(docker run 的挂载参数无法追加到已有容器):
# 1. 重建前留档,从 inspect 里提取原容器的镜像、网络、端口、ExtraHosts、全部挂载
docker inspect nginx > /root/ops_backup/nginx-inspect-$(date +%Y%m%d-%H%M%S).json
# 2. 按留档原样重建,仅新增 certs 只读挂载
docker rm -f nginx
docker run -d --name nginx \
-p 80:80 -p 443:443 \
-v /data/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro \
-v /data/nginx/conf/conf.d:/etc/nginx/conf.d:ro \
-v /data/nginx/html:/usr/share/nginx/html:ro \
-v /data/nginx/certs:/etc/nginx/certs:ro \
--restart always \
nginx:1.28
# 3. 重建后必查:容器内配置是否与宿主机一致(否则改动全部静默失效)
docker exec nginx md5sum /etc/nginx/nginx.conf
md5sum /data/nginx/conf/nginx.conf重建是高危操作:原端口映射、
--add-host、网络名、--restart策略、镜像标签任一漏掉,都会导致服务异常。执行前务必用docker inspect留档,并逐项核对后再重建。重建会造成数秒闪断,安排在低峰期。
--reloadcmd 里要能操作容器
Nginx 在容器里时,重载命令要带 docker exec:
acme.sh --install-cert -d www.example.com --ecc \
--key-file /data/nginx/certs/key.pem \
--fullchain-file /data/nginx/certs/fullchain.pem \
--reloadcmd "docker exec nginx nginx -s reload"验证清单
| # | 验证项 | 命令 | 期望 |
|---|---|---|---|
| 1 | https 可访问 | curl -sI https://www.example.com/ | 200 |
| 2 | 证书链可信 | openssl s_client ... | grep "Verify return code" | 0 (ok) |
| 3 | SAN 覆盖全部域名 | openssl x509 -noout -text | grep -A1 "Subject Alternative Name" | 根域 + www 都在 |
| 4 | 有效期 | openssl x509 -noout -dates | 约 90 天 |
| 5 | 30 天内不过期 | openssl x509 -noout -checkend 2592000 | 退出码 0 |
| 6 | 证书私钥配对 | 两串 openssl md5 | 完全相等 |
| 7 | TLS 协议 | 容器内 openssl s_client | TLSv1.3(降级 1.2 也通) |
| 8 | 验证通道完好 | curl -sI http://www.example.com/.well-known/acme-challenge/probe-xyz | 200 |
| 9 | 自动续期闭环 | acme.sh --cron --force | 出现 Reload successful |
| 10 | 浏览器实测 | 访问 https | 地址栏出锁标,内容与 http 一致 |
反证检查(证明"该变的变了、该不变的没变"):
| 检查 | 期望 | 说明 |
|---|---|---|
| http 响应码 | 未跳转时仍 200 | 确认没误加跳转 |
| 目录权限 | certs 为 700、key.pem 为 600 | 私钥未泄露 |
| 私钥是否可下载 | curl http://www.example.com/certs/key.pem | 应 404 |
| 容器内配置 md5 | 与宿主机一致 | 防止单文件挂载静默失效 |
常见错误速查
| 现象 | 根因 | 处理 |
|---|---|---|
Invalid response from http://...: 404 | challenge location 路径算错(root/alias 语义混用,或少了 .well-known 一层) | 见「root 与 alias 的语义差异」一节,用零成本探针先验证 |
Timeout during connect | 80 端口不通:安全组/防火墙未放行,或 Nginx 未监听 80 | 检查云安全组 + firewall-cmd --list-ports + netstat -tunlp |
dns problem NXDOMAIN | 域名未解析到本机 | dig +short 域名 确认 |
too many certificates already issued | 触发 CA 每周 5 次频率限制 | 停止重试,等待额度重置或换测试域名 |
用了 CDN 时 timeout during connect | CDN/代理把 /.well-known/ 路径拦截或缓存了 | 给该路径单独配置放行与不缓存规则 |
浏览器报 ERR_CERT_COMMON_NAME_INVALID | SAN 未覆盖当前访问的域名 | 补 -d 重新签发 |
浏览器报 ERR_CERT_DATE_INVALID | 续期失败或 reloadcmd 未生效 | acme.sh --cron --force 走一遍闭环,看是否 reload 成功 |
Nginx 报 SSL_CTX_use_PrivateKey 失败 / 502 | 证书与私钥不配对 | 用 md5 比对法(见验证清单第 6 项)确认后重新 --install-cert |
| 客户端报证书链无效 | ssl_certificate 指向了证书本体而非 fullchain | 改指 fullchain.pem |
| 改了配置 reload 后无变化 | 单文件 bind mount 的 inode 陷阱 | 见「单文件挂载禁止 sed -i」一节 |
nginx -t 输出看着像没报错 | 输出走 stderr,远程不加 2>&1 会得到空字符串 | 显式看退出码 echo "EXIT=$?",别只看有没有输出 |
| 探测 TLS 1.3 报不支持 | 宿主机 OpenSSL 1.0.2k 客户端能力不足 | 换容器内或新版 openssl 探测 |
| 续期后站点仍用旧证书 | --reloadcmd 命令写错或执行失败 | 检查 ~/.acme.sh/<域名>_ecc/<域名>.conf 中的 reloadcmd 配置,手动执行一次该命令 |
证书的续期与生命周期
- 有效期 90 天:Let's Encrypt 证书自 2020 年起固定为 90 天,短有效期意味着私钥泄露后的影响窗口也小;
- 续期时机:acme.sh 定时检查,剩余寿命不足 30 天才真正重新签发;
- 多域名注意:证书的任一 SAN 域名验证失败都可能导致整个订单失败,所以域名越多越容易续期失败——不用的域名应及时从
-d中移除,或改用 DNS-01 逐个校验; - 更换证书类型:从 RSA 换 ECC(或反之)相当于换一张证书,需重新
--issue后再--install-cert,并记得给--install-cert加上/去掉--ecc; - 卸载时:
acme.sh --remove -d 域名可移除单个域名的记录;彻底卸载见「安装 acme.sh」小节。
