znlgis 博客

GIS开发与技术分享 — GDAL · GeoServer · PostGIS · QGIS · OpenLayers · Cesium · FreeCAD · NPOI

第10章 - 常见问题与故障排查

本章汇总了使用 acme.sh 过程中最常见的问题,提供详细的诊断步骤和解决方案。


10.1 安装与初始化问题

10.1.1 安装脚本下载失败

问题:执行 curl https://get.acme.sh | sh 时连接超时或失败。

原因:在中国大陆,访问 get.acme.sh(托管在 GitHub)可能存在网络问题。

解决方案:

# 方案一:使用 Gitee 镜像
git clone https://gitee.com/neilpang/acme.sh.git
cd acme.sh
./acme.sh --install -m your@email.com

# 方案二:下载 zip 包
wget https://github.com/acmesh-official/acme.sh/archive/refs/heads/master.zip
unzip master.zip
cd acme.sh-master
./acme.sh --install -m your@email.com

# 方案三:如有 Git 访问,直接克隆
git clone --depth 1 https://github.com/acmesh-official/acme.sh.git
cd acme.sh
./acme.sh --install -m your@email.com

10.1.2 acme.sh 命令未找到

问题:安装完成后执行 acme.sh 提示 command not found

解决方案:

# 重新加载 Shell 配置
source ~/.bashrc
# 或
source ~/.zshrc

# 如果仍然无效,直接使用完整路径
~/.acme.sh/acme.sh --version

# 手动添加别名
echo 'alias acme.sh=~/.acme.sh/acme.sh' >> ~/.bashrc
source ~/.bashrc

10.2 证书申请失败

10.2.1 CA 服务器连接问题

问题:申请时提示连接 CA 服务器失败,如 Connecting to acme-v02.api.letsencrypt.org... 超时。

诊断:

# 检查网络连通性
curl -v https://acme-v02.api.letsencrypt.org/directory
curl -v https://acme.zerossl.com/v2/DV90

# 如果 ZeroSSL 可以访问,切换默认 CA
acme.sh --set-default-ca --server zerossl

# 如果 Let's Encrypt 可以访问
acme.sh --set-default-ca --server letsencrypt

中国大陆常见情况

# 测试各 CA 连通性
for ca in "acme-v02.api.letsencrypt.org" "acme.zerossl.com" "api.buypass.com"; do
    echo -n "Testing $ca... "
    if curl -s --connect-timeout 5 https://$ca > /dev/null; then
        echo "OK"
    else
        echo "FAILED"
    fi
done

10.2.2 HTTP-01 验证失败

问题:HTTP 验证时 CA 无法访问验证文件。

诊断步骤:

# 1. 在申请前手动测试验证路径是否可访问
# 先申请(会失败并显示 token)
acme.sh --issue -d example.com -w /var/www/html --debug

# 记录 token,手动测试
TOKEN="xxxxxx"
echo "test" > /var/www/html/.well-known/acme-challenge/$TOKEN
curl http://example.com/.well-known/acme-challenge/$TOKEN

常见原因及解决:

原因 解决方案
防火墙阻止 80 端口 在云服务商安全组中开放入站 80 端口
Nginx 将 HTTP 重定向到 HTTPS /.well-known/acme-challenge/ 添加例外
Web 根目录权限问题 chmod 755 /var/www/html/.well-known/
DNS 未解析到当前服务器 检查 DNS A 记录是否指向正确 IP
CDN 缓存 临时绕过 CDN 或使用 DNS-01 验证

Nginx 配置修复(解决重定向问题):

server {
    listen 80;
    server_name example.com;

    # ACME 验证路径例外(不重定向)
    location /.well-known/acme-challenge/ {
        root /var/www/html;
        allow all;
    }

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

10.2.3 DNS-01 验证失败

问题:DNS API 模式验证失败,提示 Error: Could not check dns_xx 或 TXT 记录验证超时。

诊断步骤:

# 1. 开启调试模式查看 API 调用详情
acme.sh --issue --dns dns_ali -d example.com --debug 2

# 2. 手动验证 DNS API 是否正常工作
# 临时手动添加测试记录,然后检查是否可查询
dig @8.8.8.8 _acme-challenge.example.com TXT

# 3. 检查凭据是否正确
cat ~/.acme.sh/account.conf | grep -E "Ali_|CF_|DP_|Tencent_"

常见原因:

原因 解决方案
DNS API 凭据错误/过期 重新获取并更新凭据
DNS 传播速度慢 添加 --dnssleep 120 或更长时间
DNS 服务商 API 限流 减少申请频率,检查 API 配额
域名不在该账户下 确认域名和 API Key 归属同一账户
二级域名证书,需要根域 API Key 确保 API Key 有根域的 DNS 管理权限

增加 DNS 传播等待时间:

# 申请时指定等待时间(秒)
acme.sh --issue --dns dns_ali -d example.com --dnssleep 300

# 通过修改配置文件永久设置
echo 'Le_DNSSleep=300' >> ~/.acme.sh/example.com/example.com.conf

10.2.4 Rate Limit(速率限制)错误

问题:提示 Error: too many certificates already issuedrateLimited

Let’s Encrypt 限额:

  • 每个注册域名每周 50 张证书
  • 每个域名每小时 5 次失败重试
  • 相同名称集的证书每周最多 5 张

解决方案:

# 使用测试环境避免消耗配额
acme.sh --issue --dns dns_cf -d example.com --server letsencrypt_test

# 等待一周后重试(如果已达上限)
# 或切换到 ZeroSSL(不受 Let's Encrypt 限额影响)
acme.sh --issue --dns dns_cf -d example.com --server zerossl --force

# 查看当前配额使用情况
# https://crt.sh/?q=example.com&caid=183267

10.2.5 证书申请成功但 fullchain 为空

问题:申请成功,但 fullchain.cer 文件大小异常或不完整。

解决方案:

# 强制重新申请
acme.sh --renew -d example.com --force

# 检查文件完整性
openssl x509 -in ~/.acme.sh/example.com/fullchain.cer -noout -text | head -20

# 检查是否包含中间证书
grep -c "BEGIN CERTIFICATE" ~/.acme.sh/example.com/fullchain.cer
# 正常应该输出 2 或 3(至少有域名证书 + 中间证书)

10.3 证书安装与配置问题

10.3.1 Nginx 启动失败(SSL 证书问题)

问题:安装证书后 Nginx 启动或 reload 失败。

诊断:

# 测试 Nginx 配置
nginx -t

# 查看 Nginx 错误日志
tail -50 /var/log/nginx/error.log

# 验证证书文件是否存在
ls -la /etc/nginx/ssl/example.com/

# 验证证书和私钥匹配
openssl x509 -noout -modulus -in /etc/nginx/ssl/fullchain.pem | openssl md5
openssl rsa  -noout -modulus -in /etc/nginx/ssl/privkey.pem | openssl md5
# 两行输出应相同

常见错误及解决:

错误信息 原因 解决
PEM_read_bio_X509_AUX() failed 证书格式错误或文件为空 重新执行 --install-cert
SSL_CTX_use_certificate_file() failed 证书路径错误或权限不足 检查路径和权限 chmod 644
SSL_CTX_use_PrivateKey_file() failed 私钥路径错误或权限 确认私钥文件存在,权限 600
key values mismatch 证书与私钥不匹配 重新申请或重新 install-cert

修复权限:

chmod 644 /etc/nginx/ssl/example.com/fullchain.pem
chmod 600 /etc/nginx/ssl/example.com/privkey.pem
chown root:root /etc/nginx/ssl/example.com/

10.3.2 浏览器提示”不安全”(证书链不完整)

问题:网站 HTTPS 浏览器显示”您的连接不安全”或证书链错误。

原因:使用了不包含中间证书的 example.com.cer 而不是 fullchain.cer

解决方案

确保 Nginx/Apache 配置使用的是 fullchain.pem(包含中间证书),而非 example.com.cer

# 正确
ssl_certificate /etc/nginx/ssl/example.com/fullchain.pem;

# 错误(不含中间证书)
ssl_certificate /etc/nginx/ssl/example.com/cert.pem;

验证证书链:

# 使用 openssl 验证 SSL 握手
openssl s_client -connect example.com:443 -servername example.com

# 在线工具(推荐)
# https://www.ssllabs.com/ssltest/
# https://myssl.com/

10.3.3 reloadcmd 未执行(续期后服务未重载)

问题:证书续期成功,但 Nginx/Apache 未自动重载,导致服务仍使用旧证书。

诊断:

# 查看证书配置文件,确认 reloadcmd 存在
cat ~/.acme.sh/example.com/example.com.conf | grep Le_ReloadCmd

# 手动测试 reloadcmd 是否可执行
systemctl reload nginx
# 或
nginx -s reload

解决方案:

# 重新设置 reloadcmd
acme.sh --install-cert -d example.com \
  --key-file       /etc/nginx/ssl/privkey.pem \
  --fullchain-file /etc/nginx/ssl/fullchain.pem \
  --reloadcmd      "systemctl reload nginx"

# 确认配置已保存
cat ~/.acme.sh/example.com/example.com.conf | grep Le_ReloadCmd

10.4 自动续期问题

10.4.1 自动续期未执行

问题:证书已过期,但 cron 未自动续期。

诊断步骤:

# 1. 检查 cron 任务是否存在
crontab -l | grep acme

# 2. 检查 cron 服务是否运行
systemctl status cron
# 或
systemctl status crond

# 3. 手动执行续期命令测试
/root/.acme.sh/acme.sh --cron --home /root/.acme.sh

# 4. 检查是否有权限问题
ls -la /root/.acme.sh/

修复方案:

# 重新安装 cron 任务
acme.sh --install-cronjob

# 如果 cron 服务未运行
# Ubuntu/Debian
apt install cron && systemctl enable --now cron

# CentOS/RHEL
yum install cronie && systemctl enable --now crond

10.4.2 续期时 DNS API 调用失败

问题:首次申请正常,但续期时 DNS API 失败(API Key 过期或权限变更)。

解决方案:

# 更新 API 凭据后强制续期
export Ali_Key="new_key"
export Ali_Secret="new_secret"
acme.sh --renew -d example.com --force

# 检查 account.conf 中的凭据是否已更新
grep Ali_ ~/.acme.sh/account.conf

10.4.3 续期后证书未更新到目标路径

问题acme.sh --list 显示证书已续期,但 Nginx 使用的证书文件未更新。

原因--install-cert--reloadcmd 执行失败(如 systemctl 权限问题)。

解决方案:

# 手动重新安装证书
acme.sh --install-cert -d example.com \
  --key-file       /etc/nginx/ssl/privkey.pem \
  --fullchain-file /etc/nginx/ssl/fullchain.pem \
  --reloadcmd      "systemctl reload nginx"

# 如果是非 root 用户的 systemctl 权限问题,配置 sudo
echo "your_user ALL=(ALL) NOPASSWD: /usr/bin/systemctl reload nginx" >> /etc/sudoers.d/acme-nginx

# 更新 reloadcmd 使用 sudo
acme.sh --install-cert -d example.com \
  --key-file       /etc/nginx/ssl/privkey.pem \
  --fullchain-file /etc/nginx/ssl/fullchain.pem \
  --reloadcmd      "sudo systemctl reload nginx"

10.5 特定平台问题

10.5.1 CentOS 7 CA 证书问题

问题:在 CentOS 7 上连接 CA 服务器时提示 SSL 证书验证失败。

# 更新系统 CA 证书包
yum update ca-certificates -y

# 如果无法更新,临时绕过(不推荐生产使用)
acme.sh --issue ... --insecure

10.5.2 Alpine Linux 安装问题

# Alpine 需要先安装依赖
apk update
apk add curl openssl bash

# 使用 bash 执行 acme.sh(Alpine 默认 /bin/sh 是 busybox)
bash -c "$(curl https://get.acme.sh)" -s email=your@email.com

10.5.3 Docker 容器内运行问题

# Docker 容器通常没有 cron,需要手动安装或使用外部调度
# 或者使用宿主机的 cron 通过 docker exec 执行
# 示例 crontab 条目:
# 0 2 * * * docker exec acme-container acme.sh --cron --home /acme.sh

10.5.4 阿里云 ECS 安全组问题

问题:阿里云 ECS 使用 Standalone 模式申请证书,CA 无法访问 80 端口。

解决方案

  1. 登录阿里云 ECS 控制台
  2. 找到对应实例 → 安全组 → 入站规则
  3. 添加规则:协议 TCP,端口 80,来源 0.0.0.0/0
  4. 或者改用 DNS-01 验证(推荐,不受安全组限制)

10.5.5 腾讯云 CVM 防火墙问题

类似阿里云,需要在腾讯云控制台的安全组中开放 80 端口,或使用 DNS 验证。


10.6 证书相关错误诊断

10.6.1 SSL 评级低

问题:SSL Labs 评级为 B 或以下。

常见原因及解决:

# 禁用不安全的 TLS 版本
ssl_protocols TLSv1.2 TLSv1.3;

# 禁用不安全的加密套件
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;

# 配置 HSTS
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

# 启用 OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4;

10.6.2 证书到期但未收到提醒邮件

解决方案:

# 检查注册邮箱
cat ~/.acme.sh/account.conf | grep ACCOUNT_EMAIL

# 更新邮箱
acme.sh --update-account -m new@email.com

# 手动检查证书到期时间
acme.sh --list
openssl x509 -enddate -noout -in ~/.acme.sh/example.com/fullchain.cer

10.7 常用诊断命令速查

# ============================
# 查看状态
# ============================
acme.sh --version                          # 查看版本
acme.sh --info                             # 查看全局配置
acme.sh --list                             # 列出所有证书
acme.sh --info -d example.com             # 查看特定域名信息

# ============================
# 证书操作
# ============================
acme.sh --renew -d example.com --force    # 强制续期
acme.sh --renew-all                        # 续期所有
acme.sh --cron --home ~/.acme.sh          # 手动触发 cron 检查
acme.sh --revoke -d example.com           # 吊销证书
acme.sh --remove -d example.com           # 从管理中删除

# ============================
# 系统维护
# ============================
acme.sh --upgrade                          # 更新 acme.sh
acme.sh --install-cronjob                  # 重新安装 cron
acme.sh --uninstall-cronjob                # 删除 cron

# ============================
# 调试
# ============================
acme.sh --issue --dns dns_cf -d example.com --debug    # 调试级别 1
acme.sh --issue --dns dns_cf -d example.com --debug 2  # 调试级别 2

# ============================
# 验证证书
# ============================
openssl x509 -in /path/to/cert.pem -noout -text          # 查看证书详情
openssl x509 -in /path/to/cert.pem -noout -dates          # 查看有效期
openssl s_client -connect example.com:443 -servername example.com  # 测试 SSL 握手

10.8 常见错误信息速查

错误信息 含义 解决方案
too many certificates already issued Let’s Encrypt 速率限制 等待一周或切换到 ZeroSSL
DNS problem: NXDOMAIN looking up TXT DNS TXT 记录不存在或未传播 增加 --dnssleep 或手动验证 DNS
Connection refused 无法连接 CA 服务器 检查网络、切换 CA
Invalid response from CA 无法访问验证 URL 检查 80 端口是否开放和 Web 服务器配置
key values mismatch 证书和私钥不匹配 重新 --install-cert
no matches for criteria API 操作无权限 检查 API Key 权限
Error: Please install curl first 缺少 curl apt/yum install curl
Permission denied 文件权限问题 检查目录权限或使用 root 运行

10.9 寻求社区帮助

当遇到无法自行解决的问题时,可以通过以下渠道获取帮助:

  1. GitHub Issueshttps://github.com/acmesh-official/acme.sh/issues
    • 搜索是否有已有的解答
    • 提交 issue 时请附上 --debug 2 的输出
  2. acme.sh Wikihttps://github.com/acmesh-official/acme.sh/wiki

  3. Let’s Encrypt 社区https://community.letsencrypt.org/

提交 Issue 时需要提供的信息:

# 收集诊断信息
echo "=== acme.sh version ==="
acme.sh --version

echo "=== OS info ==="
cat /etc/os-release

echo "=== curl version ==="
curl --version

echo "=== openssl version ==="
openssl version

echo "=== Debug output ==="
acme.sh --issue --dns dns_xx -d example.com --debug 2 2>&1 | tail -100

10.10 小结

本章汇总了 acme.sh 常见问题的诊断和解决方案:

  • 安装问题:中国大陆使用 Gitee 镜像,注意重新加载 Shell 配置
  • 申请失败:先检查网络连通性,HTTP-01 检查防火墙,DNS-01 增加传播等待时间
  • 速率限制:使用测试环境调试,或切换到 ZeroSSL
  • 自动续期失效:检查 cron 服务、重新安装 cron 任务
  • 证书链不完整:始终使用 fullchain.pem,而非 cert.pem
  • 权限问题:证书 644,私钥 600,reloadcmd 需要相应执行权限

通过系统性地使用 --debug 2 调试输出,配合本章提供的诊断命令,可以快速定位和解决绝大多数 acme.sh 使用问题。祝你的 HTTPS 之路顺利!