如何解决Composer TLS握手失败问题?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1036个文字,预计阅读时间需要5分钟。
Composer 安装或更新时出现 SSL handshake failed 或报错 cURL error 35、SSL connect error,基本原因是本地 TLS 环境与 Packagist/Repo 服务器不兼容,不是 Composer 本身 bug,也不需要直接关闭 SSL 验证。
为什么 Composer 会 SSL 握手失败
根本原因通常是 OpenSSL 版本过旧(如系统自带的 OpenSSL 1.0.x)、CA 证书陈旧、或中间网络设备(公司代理、防火墙、DNS 污染)篡改了 TLS 握手流程。Packagist 自 2023 年起强制要求 TLS 1.2+ 和现代密码套件,老系统(如 CentOS 7 默认 OpenSSL 1.0.2k)无法协商成功。
- 常见错误信息:
cURL error 35: SSL connect error、SSL handshake failed、Peer certificate cannot be authenticated - 不是所有 HTTPS 网站都出问题,只影响
https://packagist.org及镜像(如阿里云、腾讯云镜像),说明问题出在服务端 TLS 配置升级后客户端不匹配 -
composer diagnose会明确提示curl: (35) SSL connect error,这是第一排查线索
检查并升级本地 OpenSSL 和 cURL
Composer 依赖 PHP 的 cURL 扩展,而 cURL 又依赖底层 OpenSSL。必须确认三者版本协同支持 TLS 1.2+:
- 运行
openssl version:低于OpenSSL 1.1.1建议升级(1.0.2 已停止维护,不支持 TLS 1.3 且部分密码套件被禁用) - 运行
php -i | grep -i "curl version\|openssl version":确认 PHP 加载的 cURL 是否绑定新版 OpenSSL - Ubuntu/Debian 用户可执行
sudo apt update && sudo apt install openssl libcurl4-openssl-dev;CentOS/RHEL 7+ 建议启用epel后安装openssl11并重新编译 PHP,或改用remi源的 PHP 包 - Windows 用户若用 XAMPP/MAMP,请确认其内置 PHP 是否链接到较新 OpenSSL —— 直接下载官方
php.netZIP 包通常更可靠
临时绕过但不推荐的应急操作
仅限调试或内网离线环境,**生产环境禁止使用**:
- 禁用 CA 校验(危险):
composer config -g secure-http false+composer config -g github-protocols https,但这会让所有 HTTPS 请求跳过证书验证,易受中间人攻击 - 指定 CA bundle 路径(推荐优先尝试):
composer config -g cafile /etc/ssl/certs/ca-certificates.crt(Linux)或composer config -g cafile "C:\xampp\apache\conf\ssl.crt\ca-bundle.crt"(Windows),路径需真实存在且含最新根证书 - 换国内镜像源本身不解决握手问题,但部分镜像(如华为云)对老客户端兼容性略好:
composer config -g repo.packagist composer https://repo.huaweicloud.com/php;仍失败说明是本地 TLS 根因未解
PHP 配置和代理干扰排查
某些企业环境会静默注入代理或修改 TLS 参数,导致握手异常:
- 检查
php.ini中是否设置了openssl.cafile或curl.cainfo指向一个损坏/过期的证书文件 —— 注释掉这两行再试 - 确认没设置全局 HTTP 代理:
echo $HTTP_PROXY $HTTPS_PROXY(Linux/macOS)或set HTTP_PROXY(Windows),有则unset HTTP_PROXY HTTPS_PROXY - 如果必须走代理,确保代理支持 CONNECT 隧道且未降级 TLS 版本;可临时用
curl -v https://packagist.org/packages.json复现并观察握手细节 - Docker 环境下,宿主机证书更新后需重建 PHP 镜像,或挂载最新
ca-certificates.crt到容器内
真正稳定的解法永远是让本地 OpenSSL/cURL 支持现代 TLS 协议,而不是调低服务端安全水位。很多“加一行 config 就好了”的方案,三个月后可能又因镜像升级 TLS 配置而失效。
本文共计1036个文字,预计阅读时间需要5分钟。
Composer 安装或更新时出现 SSL handshake failed 或报错 cURL error 35、SSL connect error,基本原因是本地 TLS 环境与 Packagist/Repo 服务器不兼容,不是 Composer 本身 bug,也不需要直接关闭 SSL 验证。
为什么 Composer 会 SSL 握手失败
根本原因通常是 OpenSSL 版本过旧(如系统自带的 OpenSSL 1.0.x)、CA 证书陈旧、或中间网络设备(公司代理、防火墙、DNS 污染)篡改了 TLS 握手流程。Packagist 自 2023 年起强制要求 TLS 1.2+ 和现代密码套件,老系统(如 CentOS 7 默认 OpenSSL 1.0.2k)无法协商成功。
- 常见错误信息:
cURL error 35: SSL connect error、SSL handshake failed、Peer certificate cannot be authenticated - 不是所有 HTTPS 网站都出问题,只影响
https://packagist.org及镜像(如阿里云、腾讯云镜像),说明问题出在服务端 TLS 配置升级后客户端不匹配 -
composer diagnose会明确提示curl: (35) SSL connect error,这是第一排查线索
检查并升级本地 OpenSSL 和 cURL
Composer 依赖 PHP 的 cURL 扩展,而 cURL 又依赖底层 OpenSSL。必须确认三者版本协同支持 TLS 1.2+:
- 运行
openssl version:低于OpenSSL 1.1.1建议升级(1.0.2 已停止维护,不支持 TLS 1.3 且部分密码套件被禁用) - 运行
php -i | grep -i "curl version\|openssl version":确认 PHP 加载的 cURL 是否绑定新版 OpenSSL - Ubuntu/Debian 用户可执行
sudo apt update && sudo apt install openssl libcurl4-openssl-dev;CentOS/RHEL 7+ 建议启用epel后安装openssl11并重新编译 PHP,或改用remi源的 PHP 包 - Windows 用户若用 XAMPP/MAMP,请确认其内置 PHP 是否链接到较新 OpenSSL —— 直接下载官方
php.netZIP 包通常更可靠
临时绕过但不推荐的应急操作
仅限调试或内网离线环境,**生产环境禁止使用**:
- 禁用 CA 校验(危险):
composer config -g secure-http false+composer config -g github-protocols https,但这会让所有 HTTPS 请求跳过证书验证,易受中间人攻击 - 指定 CA bundle 路径(推荐优先尝试):
composer config -g cafile /etc/ssl/certs/ca-certificates.crt(Linux)或composer config -g cafile "C:\xampp\apache\conf\ssl.crt\ca-bundle.crt"(Windows),路径需真实存在且含最新根证书 - 换国内镜像源本身不解决握手问题,但部分镜像(如华为云)对老客户端兼容性略好:
composer config -g repo.packagist composer https://repo.huaweicloud.com/php;仍失败说明是本地 TLS 根因未解
PHP 配置和代理干扰排查
某些企业环境会静默注入代理或修改 TLS 参数,导致握手异常:
- 检查
php.ini中是否设置了openssl.cafile或curl.cainfo指向一个损坏/过期的证书文件 —— 注释掉这两行再试 - 确认没设置全局 HTTP 代理:
echo $HTTP_PROXY $HTTPS_PROXY(Linux/macOS)或set HTTP_PROXY(Windows),有则unset HTTP_PROXY HTTPS_PROXY - 如果必须走代理,确保代理支持 CONNECT 隧道且未降级 TLS 版本;可临时用
curl -v https://packagist.org/packages.json复现并观察握手细节 - Docker 环境下,宿主机证书更新后需重建 PHP 镜像,或挂载最新
ca-certificates.crt到容器内
真正稳定的解法永远是让本地 OpenSSL/cURL 支持现代 TLS 协议,而不是调低服务端安全水位。很多“加一行 config 就好了”的方案,三个月后可能又因镜像升级 TLS 配置而失效。

