This commit is contained in:
Your Name
2026-04-15 16:31:25 +08:00
parent 906684c1ed
commit 3d9c5dd8f5
47 changed files with 7963 additions and 10 deletions
+284
View File
@@ -0,0 +1,284 @@
# 甘草 SSL 连接错误修复指南
## 错误信息
```
甘草网关通信失败:通信失败:HTTP 200 curl#56 OpenSSL SSL_read: error:0A000126:SSL routines::unexpected eof while reading, errno 0
```
## 问题分析
这个错误表示:
- ✅ TCP 连接成功(HTTP 200
- ✅ SSL 握手开始
- ❌ SSL 读取数据时连接意外断开
**常见原因:**
1. TLS 版本不兼容(服务器要求 TLS 1.2+,客户端使用旧版本)
2. SSL 加密套件不匹配
3. HTTP 版本问题(HTTP/1.0 vs HTTP/1.1
4. OpenSSL 安全级别过高
5. 服务器端提前关闭连接
## 已实施的修复
### 修改 `GancaoOpenApiTransport.php`
```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: 上传修复后的文件
```bash
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 测试
```bash
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: 清除缓存并重启
```bash
cd server
php think clear
rm -rf runtime/cache/*
# 重启服务
sudo systemctl restart php-fpm
sudo systemctl restart nginx
```
### 步骤 4: 测试接口
```bash
# 查看日志
tail -f server/runtime/log/$(date +%Y%m%d).log | grep -i gancao
```
在另一个终端调用接口:
```bash
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 版本
```bash
openssl version
```
**要求:** OpenSSL 1.0.2 或更高版本
**如果版本过低,升级 OpenSSL:**
```bash
# 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`
```ini
# 在文件开头添加
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
```
重启服务:
```bash
sudo systemctl restart php-fpm
```
### 方案 C: 使用不同的 TLS 版本
如果 TLS 1.2 不工作,尝试其他版本。
修改 `GancaoOpenApiTransport.php`
```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,尝试禁用:
```php
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
```
### 方案 E: 增加调试信息
临时添加详细的 cURL 调试:
```php
// 在 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]);
```
查看详细日志:
```bash
tail -f server/runtime/log/$(date +%Y%m%d).log
```
### 方案 F: 联系甘草技术支持
提供以下信息:
1. `php test_gancao_ssl.php` 的完整输出
2. `openssl version` 输出
3. `php -v` 输出
4. `curl --version` 输出
5. 服务器操作系统版本
询问:
- 甘草网关支持的 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 连接活跃,防止长时间传输时连接被中断。
## 验证修复成功
修复成功的标志:
1.`php test_gancao_ssl.php` 显示 "✓ 成功获取 token"
2. ✅ 接口返回成功:
```json
{
"code": 1,
"msg": "甘草药方上传成功",
"data": {...}
}
```
3. ✅ 日志中没有 SSL 错误
4. ✅ 数据库中订单已更新
## 总结
SSL 连接问题通常是由于:
1. **TLS 版本不匹配** → 使用 TLS 1.2
2. **HTTP 版本问题** → 使用 HTTP/1.1
3. **OpenSSL 安全级别过高** → 降低到 SECLEVEL=1
4. **连接超时** → 增加超时时间
修复后应该能正常连接甘草 API。如果仍有问题,运行 `test_gancao_ssl.php` 并根据输出进一步诊断。