Apache服务器cURL请求出现OpenSSL SSL_read错误排查问询
Apache环境下cURL获取ZIP文件时频繁出现SSL解密错误的排查与解决
我在Apache服务器上运行以下PHP代码获取多个ZIP文件,代码在本地Symfony服务器上运行正常,但在生产环境中频繁出现SSL解密错误,仅偶尔能成功。
$ch = curl_init("https://opendata-rncs.inpi.fr/services/diffusion/document/get?listeIdFichier=" . $listFilesId); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); $headers = array( "Cookie: " . $token, 'login: xxxxxxxxxx', 'password: '. $this->tokenApiInpi, "Content-Type: application/json", ); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0); $raw_file_data = curl_exec($ch); if(curl_errno($ch)) { echo 'error:' . curl_error($ch); } curl_close($ch);
报错信息
OpenSSL SSL_read: error:1408F119:SSL routines:ssl3_get_record:decryption failed or bad record mac, errno 0
环境信息
OpenSSL 1.1.1f 31 Mar 2020
cURL Information => 7.68.0
curl_getInfo返回结果
array:37 [ "url" => "https://opendata-rncs.inpi.fr/services/diffusion/document/get?listeIdFichier=229514679,230627776,222612310,233647858" "content_type" => "application/zip" "http_code" => 200 "header_size" => 705 "request_size" => 291 "filetime" => -1 "ssl_verify_result" => 0 "redirect_count" => 0 "total_time" => 0.462636 "namelookup_time" => 0.003911 "connect_time" => 0.008549 "pretransfer_time" => 0.038412 "size_upload" => 0.0 "size_download" => 703824.0 "speed_download" => 1523428.0 "speed_upload" => 0.0 "download_content_length" => 5362987.0 "upload_content_length" => -1.0 "starttransfer_time" => 0.430148 "redirect_time" => 0.0 "redirect_url" => "" "primary_ip" => "81.252.220.78" "certinfo" => [] "primary_port" => 443 "local_ip" => "10.1.2.7" "local_port" => 53494 "http_version" => 2 "protocol" => 2 "ssl_verifyresult" => 0 "scheme" => "HTTPS" "appconnect_time_us" => 38371 "connect_time_us" => 8549 "namelookup_time_us" => 3911 "pretransfer_time_us" => 38412 "redirect_time_us" => 0 "starttransfer_time_us" => 430148 "total_time_us" => 462636 ]
可能原因及解决办法
原因分析
- HTTP/2协议兼容性问题:从curl_getInfo结果看当前使用HTTP/2,部分服务器或中间件(如反向代理)在HTTP/2下的SSL传输可能存在不稳定情况,导致解密校验失败。
- 加密套件匹配问题:虽然OpenSSL 1.1.1f版本稳定,但目标服务器可能对某些加密套件支持不佳,生产环境的加密套件配置与本地存在差异。
- 网络波动影响:生产环境网络链路可能存在丢包、延迟波动,导致SSL记录完整性校验失败。
- 废弃选项干扰:
CURLOPT_BINARYTRANSFER在PHP 5.1.3+已被废弃,继续使用可能引发潜在的二进制数据传输异常。
解决步骤
- 强制使用HTTP/1.1:添加以下代码禁用HTTP/2,避免协议层面的兼容性问题:
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); - 调整加密套件配置:添加以下代码降低SSL安全级别,兼容目标服务器的加密配置:
curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, 'DEFAULT@SECLEVEL=1'); - 添加重试机制:针对SSL相关错误进行自动重试,示例代码如下(限制重试次数为3次):
$maxRetries = 3; $retryCount = 0; $raw_file_data = false; while ($retryCount < $maxRetries && !$raw_file_data) { $ch = curl_init("https://opendata-rncs.inpi.fr/services/diffusion/document/get?listeIdFichier=" . $listFilesId); // 配置其他cURL选项... $raw_file_data = curl_exec($ch); if(curl_errno($ch)) { $error = curl_error($ch); if(strpos($error, 'SSL') !== false) { $retryCount++; usleep(100000); // 间隔100毫秒重试 } else { break; } } curl_close($ch); } - 移除废弃选项:删除
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);,CURLOPT_RETURNTRANSFER已足够处理二进制数据。 - 设置超时参数:添加超时设置避免因网络延迟导致的异常:
curl_setopt($ch, CURLOPT_TIMEOUT, 30); // 总超时30秒 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); // 连接超时10秒 - 检查反向代理配置:如果生产环境使用Nginx等反向代理,检查代理的SSL配置,确保代理与后端服务器的SSL传输稳定,可尝试禁用代理的HTTP/2或调整缓存设置。
内容的提问来源于stack exchange,提问作者Cantinou
相关产品推荐
相关产品推荐

