# PRD 问题处理 — 服务监测模块 SSH 连接测试失败

## 问题信息

| 项目 | 内容 |
|------|------|
| 模块 | 服务监测模块 |
| 功能 | 远程目标 SSH 连接测试 |
| 发现时间 | 2026-07-20 |
| 严重程度 | 中（影响功能可用性，用户体验差） |
| 状态 | 已定位，待修复 |

## 现象

用户在服务监测平台新建 5 网段远程目标服务器（如 192.168.5.44），填写主机地址、端口、用户名、密码后，点击"测试连接"按钮，提示"SSH 连接失败"。

错误信息笼统，无法判断是网络问题、认证问题还是其他原因。

## 影响

1. **功能不可用**：无法验证远程服务器连通性，无法正常使用远程巡检功能
2. **用户体验差**：错误提示不清晰，用户无法自行排查问题
3. **运维困难**：无法区分网络/认证/依赖等不同类型的问题

## 根因分析

### 直接原因

服务器 5.60 上未安装 `paramiko` Python 包。

### 技术细节

1. `SSHExecutor._get_ssh()` 方法中 `import paramiko` 是懒加载，在运行时导入
2. 当 paramiko 未安装时，`import paramiko` 抛出 `ModuleNotFoundError`
3. 该异常被 `test_connection()` 的 `except Exception as e` 捕获
4. 捕获后只返回 `{"success": False, "message": str(e)}`，但 `str(e)` 被转换为"SSH 连接失败"
5. 用户看到的是笼统的"SSH 连接失败"，无法得知是依赖缺失

### 代码路径

```
前端 targets.html
  ↓ testConn() POST /api/service-monitor/targets/test
  
routes.py api_test_connection()
  ↓ target_service.test_connection(request_json)
  
target_service.py test_connection()
  ↓ SSHExecutor(run_id="test", host, port, username, password)
  ↓ exe.test_connection()
  
executor.py SSHExecutor.test_connection()
  ↓ self._exec("echo OK", timeout=10)
  ↓ self._get_ssh()
  ↓ import paramiko  ← ModuleNotFoundError (未安装)
  
异常向上传播
  ↓ ConnectionError("SSH 连接失败: ...")
  
返回 {"success": false, "message": "SSH 连接失败"}
```

### 为什么 paramiko 未安装

部署脚本 `deploy/upload_to_server.py` 只上传文件和重启服务，未检查服务器端 Python 依赖。

`requirements.txt` 虽然列出了 `paramiko` 和 `cryptography`，但服务器上没有执行 `pip install -r requirements.txt`。

## 解决方案

### 临时修复（已执行）

1. 在服务器 5.60 上手动安装 paramiko：
   ```bash
   pip3 install --break-system-packages paramiko
   ```
2. 重启服务

### 长期修复（代码改进）

1. **增强错误分类**：`test_connection()` 区分不同错误类型，返回详细错误信息
2. **前端显示详细错误**：测试连接结果显示具体错误原因
3. **部署脚本增加依赖检查**：上传前检查 paramiko/cryptography，未安装则自动安装
4. **输出 PRD 文档**：记录问题和修复计划

## 验证

### 修复前

- 测试连接返回"SSH 连接失败"，无具体信息
- 无法判断问题类型

### 修复后

- paramiko 未安装 → "paramiko 未安装，请在服务器执行 pip install paramiko"
- 认证失败 → "认证失败：用户名或密码错误"
- 连接超时 → "连接超时：目标不可达或端口未开放"
- 连接被拒绝 → "连接被拒绝：目标端口未开放或 SSH 服务未运行"
- 连接成功 → "连接成功"

## 元信息

- 记录人：Claude Code
- 责任人：czj
- 日志可定位：是（paramiko 导入失败会抛异常）
- 是否已解决：待代码修复