SSL握手超时是PHP cURL与仓库建立TLS连接失败所致,主因包括网络拦截、代理干扰、CA证书过旧或OpenSSL配置异常;应优先更新系统CA证书、显式配置php.ini中openssl.cafile路径,并用curl -v验证底层HTTPS连通性。

Composer install/update 卡在 SSL handshake timeout 是什么问题
这不是 Composer 本身的问题,而是 PHP 的 cURL 扩展在发起 HTTPS 请求时,与 packagist.org 或其他仓库建立 TLS 连接失败——常见于网络策略拦截、代理干扰、系统 CA 证书过旧或 OpenSSL 配置异常。超时前通常看不到具体错误,只显示 Failed to decode response: file_get_contents(): SSL operation failed 或直接卡住不动。
检查并修复系统级 SSL 根证书(Linux/macOS)
Composer 依赖 PHP 底层的 OpenSSL,而 OpenSSL 又依赖系统 CA 证书包。很多 Docker 容器、精简版 Linux 发行版(如 Alpine)或老旧 macOS 系统缺少更新的根证书,导致无法验证 Let’s Encrypt 新签发的证书(例如 packagist.org 自 2023 年起已切换至 ISRG Root X1)。
- Ubuntu/Debian:运行
sudo apt update && sudo apt install -y ca-certificates - Alpine:运行
apk add --no-cache ca-certificates,再执行update-ca-certificates - macOS(Homebrew PHP):确保
openssl@3已安装,并用brew link --force openssl@3覆盖系统链接;然后检查php -r "print_r(openssl_get_cert_locations());"中capath指向的目录是否包含有效证书文件
临时绕过 SSL 验证(仅限调试,勿用于生产)
不是推荐方案,但能快速确认是否为证书问题。注意:禁用校验会暴露凭证和包内容,且 Composer 2.5+ 默认拒绝该操作。
- 强制启用(不推荐):
composer config -g secure-http false,再加composer config -g disable-tls true - 更安全的调试方式:用
curl -v https://packagist.org/packages.json直接测试底层 HTTPS 是否通,比 Composer 更早暴露 SSL 错误细节 - 若 curl 也失败,说明问题在系统层;若 curl 成功而 Composer 失败,大概率是 PHP 的
openssl.cafile或openssl.capath配置未生效
PHP 配置中显式指定 CA 文件路径
当系统证书路径不被 PHP 自动识别时,需手动绑定。找到你的 php.ini,添加或修改:
openssl.cafile=/etc/ssl/certs/ca-certificates.crt ; 或 macOS Homebrew:openssl.cafile=/opt/homebrew/etc/openssl@3/cert.pem
改完后重启 PHP-FPM 或 CLI 环境,再运行 php -i | grep cafile 确认生效。如果仍无效,检查该路径下文件是否存在且非空——有些镜像里 /etc/ssl/certs/ca-certificates.crt 是个空文件或软链接断裂。
最常被忽略的一点:Docker 构建中 COPY 了自定义 ca-certificates.crt,但没运行 update-ca-certificates,或者 PHP 容器启动时覆盖了该文件。SSL 握手超时背后往往不是网络慢,而是“根本连不上”。


















