结论
先说结论:acme.sh
安装或申请证书超时的问题,通常是由于 curl
默认使用的 HTTP/2 协议在特定网络环境中兼容性不佳所致。通过简单地将协议强制降级到 HTTP/1.1,可以有效且稳定地解决这一问题
acme.sh 简介
SSL 证书已成为现代网站的基石,而免费的 Let's Encrypt 证书因其便捷性广受欢迎。acme.sh
作为一款强大的自动化工具,可以帮助我们简化证书的申请、安装与续期流程。然而,在实际使用中,尤其是在某些特定的云服务器环境(如阿里云),我们可能会遇到安装或申请证书时频繁出现超时(timeout)的问题。
acme.sh
是一个完全用 Shell 脚本编写的 ACME 协议客户端。它实现了对 Let's Encrypt 等 CA 服务的支持,可以自动执行以下操作:
-
申请 SSL/TLS 证书
-
自动续期证书
-
部署证书到各种服务器(如 Nginx、Apache)
这款工具的优势在于其轻量级、无需依赖其他高级编程语言环境,并且能通过 cronjob 自动处理证书续期,大大降低了运维负担。
问题:安装和申请证书时超时
在通过官方脚本安装 acme.sh
或使用其 --issue
命令申请证书时,可能会遇到类似如下的命令超时错误:
bash
# 安装 acme.sh
curl [https://get.acme.sh](https://get.acme.sh) | sh -s email=example@example.com
# 申请证书
/root/.acme.sh/acme.sh --issue -d you.domain.com --webroot /usr/share/nginx/html
执行上述命令时,可能会在下载或与 ACME 服务器通信时出现长时间等待并最终报告超时。
原因分析:HTTP/2 协议兼容性问题
经过深入研究,我发现此问题的根源在于 curl
工具的默认行为。在现代操作系统中,curl
在进行 HTTPS 请求时,会优先尝试使用 HTTP/2 协议。
然而,在某些网络环境中,特别是当服务器到 ACME 服务提供商(如 Let's Encrypt)之间的网络链路不稳定,或者存在中间网络设备对 HTTP/2 协议支持不佳时,连接的建立和数据传输会变得异常困难,最终导致通信中断并触发超时。
解决方案:强制降级至 HTTP/1.1
针对上述问题,最有效的解决方案是强制 curl
在与 acme.sh
官方服务器通信时使用 HTTP/1.1 协议。HTTP/1.1 作为更成熟、更稳定的协议,其兼容性在大多数网络环境中都有保障。
我们可以通过两种方式实现协议降级:
1. 临时解决方案:在 curl
命令中添加 --http1.1
参数
在安装和申请证书的 curl
命令中,直接加入 --http1.1
参数,强制指定使用 HTTP/1.1 协议。
bash
# 安装 acme.sh,并配置邮箱
curl --http1.1 https://get.acme.sh | sh -s email=example@example.com
# 申请证书
# acme.sh 内部也会调用 curl,可以先设置环境变量
export CURL_OPTIONS="--http1.1"
/root/.acme.sh/acme.sh --issue -d you.domain.com --webroot /usr/share/nginx/html
2. 永久解决方案:设置环境变量
acme.sh
工具内部在调用 curl
时会读取 CURL_OPTIONS
环境变量。因此,我们可以通过在系统配置文件(如 ~/.bashrc
或 /etc/profile
)中设置该环境变量,来永久性地解决此问题。
bash
# 在配置文件中添加此行,并执行 source 命令使其生效
export CURL_OPTIONS="--http1.1"
为了更清晰地展示问题与解决方案的逻辑,我绘制了以下流程图: