6.3 KiB
6.3 KiB
甘草 SSL 连接错误修复指南
错误信息
甘草网关通信失败:通信失败:HTTP 200 curl#56 OpenSSL SSL_read: error:0A000126:SSL routines::unexpected eof while reading, errno 0
问题分析
这个错误表示:
- ✅ TCP 连接成功(HTTP 200)
- ✅ SSL 握手开始
- ❌ SSL 读取数据时连接意外断开
常见原因:
- TLS 版本不兼容(服务器要求 TLS 1.2+,客户端使用旧版本)
- SSL 加密套件不匹配
- HTTP 版本问题(HTTP/1.0 vs HTTP/1.1)
- OpenSSL 安全级别过高
- 服务器端提前关闭连接
已实施的修复
修改 GancaoOpenApiTransport.php
// 1. 改用 HTTP/1.1(原来是 HTTP/1.0)
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
// 2. 增加连接超时
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); // 从 5 秒增加到 10 秒
// 3. 完全禁用 SSL 验证
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // 从 2 改为 0
// 4. 强制使用 TLS 1.2
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
// 5. 降低 OpenSSL 安全级别
curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, 'DEFAULT@SECLEVEL=1');
// 6. 添加 TCP keepalive
curl_setopt($ch, CURLOPT_TCP_KEEPALIVE, 1);
curl_setopt($ch, CURLOPT_TCP_KEEPIDLE, 120);
curl_setopt($ch, CURLOPT_TCP_KEEPINTVL, 60);
测试步骤
步骤 1: 上传修复后的文件
scp server/app/common/service/gancao/GancaoOpenApiTransport.php user@server:/path/to/server/app/common/service/gancao/
scp test_gancao_ssl.php user@server:/path/to/
步骤 2: 运行 SSL 测试
ssh user@server
cd /path/to/your/project
php test_gancao_ssl.php
期望输出:
=== 甘草 SSL 连接测试 ===
网关地址: https://xxx.com
1. DNS 解析测试:
✓ xxx.com -> 1.2.3.4
2. TCP 连接测试:
✓ TCP 连接成功
3. SSL/TLS 支持检测:
- SSLv2: ✗ 不支持
- SSLv3: ✗ 不支持
- TLS 1.0: ✓ 支持
- TLS 1.1: ✓ 支持
- TLS 1.2: ✓ 支持
- TLS 1.3: ✓ 支持
4. cURL SSL 测试:
测试 HTTP/1.0 + TLS 1.2:
❌ 失败: [56] OpenSSL SSL_read...
测试 HTTP/1.1 + TLS 1.2:
✓ 成功 (HTTP 200)
测试 HTTP/1.1 + TLS 1.2 + SECLEVEL=1:
✓ 成功 (HTTP 200)
5. OpenSSL 版本信息:
版本: OpenSSL 1.1.1...
6. cURL 版本信息:
版本: 7.x.x
SSL 版本: OpenSSL/1.1.1...
7. 测试实际 API 调用 (MAKE_TOKEN):
✓ 成功获取 token (长度: 64)
步骤 3: 清除缓存并重启
cd server
php think clear
rm -rf runtime/cache/*
# 重启服务
sudo systemctl restart php-fpm
sudo systemctl restart nginx
步骤 4: 测试接口
# 查看日志
tail -f server/runtime/log/$(date +%Y%m%d).log | grep -i gancao
在另一个终端调用接口:
curl -X POST https://your-domain.com/api/tcm.prescriptionOrder/submitGancaoRecipel \
-H "Content-Type: application/json" \
-H "token: your_token" \
-d '{"id": 订单ID}'
如果仍然失败
方案 A: 检查 OpenSSL 版本
openssl version
要求: OpenSSL 1.0.2 或更高版本
如果版本过低,升级 OpenSSL:
# CentOS/RHEL
sudo yum update openssl
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install --only-upgrade openssl
# 重新编译 PHP(如果需要)
方案 B: 修改 OpenSSL 配置
编辑 /etc/ssl/openssl.cnf:
# 在文件开头添加
openssl_conf = openssl_init
[openssl_init]
ssl_conf = ssl_sect
[ssl_sect]
system_default = system_default_sect
[system_default_sect]
MinProtocol = TLSv1.2
CipherString = DEFAULT@SECLEVEL=1
重启服务:
sudo systemctl restart php-fpm
方案 C: 使用不同的 TLS 版本
如果 TLS 1.2 不工作,尝试其他版本。
修改 GancaoOpenApiTransport.php:
// 尝试 TLS 1.3
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_3);
// 或者让 cURL 自动选择
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_DEFAULT);
方案 D: 禁用 HTTP/2
如果使用了 HTTP/2,尝试禁用:
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
方案 E: 增加调试信息
临时添加详细的 cURL 调试:
// 在 GancaoOpenApiTransport.php 的 post 方法中添加
curl_setopt($ch, CURLOPT_VERBOSE, true);
$verbose = fopen('php://temp', 'w+');
curl_setopt($ch, CURLOPT_STDERR, $verbose);
// 在 curl_exec 之后添加
rewind($verbose);
$verboseLog = stream_get_contents($verbose);
\think\facade\Log::info('cURL verbose output', ['log' => $verboseLog]);
查看详细日志:
tail -f server/runtime/log/$(date +%Y%m%d).log
方案 F: 联系甘草技术支持
提供以下信息:
php test_gancao_ssl.php的完整输出openssl version输出php -v输出curl --version输出- 服务器操作系统版本
询问:
- 甘草网关支持的 TLS 版本
- 推荐的 SSL 加密套件
- 是否有特殊的 HTTP 头要求
- 是否有 IP 白名单限制
常见问题
Q1: 为什么 HTTP/1.0 会导致问题?
A: 某些现代服务器不再支持 HTTP/1.0,或者在 HTTP/1.0 下有不同的 SSL 处理逻辑。HTTP/1.1 是更标准的选择。
Q2: SECLEVEL=1 是什么?
A: OpenSSL 1.1.0+ 引入了安全级别概念:
- SECLEVEL=2(默认):要求 112 位安全性
- SECLEVEL=1:要求 80 位安全性(更宽松)
- SECLEVEL=0:允许所有加密套件(不推荐)
降低安全级别可以兼容更多服务器,但会降低安全性。
Q3: 为什么要禁用 SSL 验证?
A: 在开发/测试环境中,禁用 SSL 验证可以避免证书问题。生产环境建议启用验证。
Q4: TCP keepalive 有什么用?
A: 保持 TCP 连接活跃,防止长时间传输时连接被中断。
验证修复成功
修复成功的标志:
- ✅
php test_gancao_ssl.php显示 "✓ 成功获取 token" - ✅ 接口返回成功:
{ "code": 1, "msg": "甘草药方上传成功", "data": {...} } - ✅ 日志中没有 SSL 错误
- ✅ 数据库中订单已更新
总结
SSL 连接问题通常是由于:
- TLS 版本不匹配 → 使用 TLS 1.2
- HTTP 版本问题 → 使用 HTTP/1.1
- OpenSSL 安全级别过高 → 降低到 SECLEVEL=1
- 连接超时 → 增加超时时间
修复后应该能正常连接甘草 API。如果仍有问题,运行 test_gancao_ssl.php 并根据输出进一步诊断。