fix: 修复架构分析报告指出的P0问题

**AI 告警分析(P0):**
- 替换 setTimeout 伪AI为真实 LLM 调用 (aiApi.chat)
- LLM 不可用时回退到规则模板(generateAIAnalysis)
- 移除 Math.random() 随机置信度/相似案例
- 分析结果从 LLM JSON 响应解析

**SSH HostKey 验证(P0):**
- webshell.go: InsecureIgnoreHostKey → TOFU 模式
- agent_install.go: 同步修复
- 首次连接记录 SHA256 fingerprint 到日志
- 后续连接校验 HostKey 一致性

**Ansible 执行引擎(P0):**
- ExecutePlaybook 从模拟改为真实 ansible-playbook 调用
- 支持 extra-vars 参数传递
- 5分钟超时保护
- ansible-playbook 未安装时返回明确错误
This commit is contained in:
attacker committed 2026-06-19 11:51:03 +00:00
1 parent a3cd0d3910
commit 9af0685e90
5 files changed
+167 -43

No files matched your search

+25 -4
View File
@@ -2,7 +2,9 @@ package handlers
import (
"encoding/json"
"fmt"
"log"
"net"
"net/http"
"strconv"
"strings"
@@ -150,11 +152,30 @@ func (h *WebShellHandler) Terminal(c *gin.Context) {
Data: "\r\n\x1b[36m正在连接 " + server.Hostname + " (" + server.IP + ":" + strconv.Itoa(server.Port) + ")...\x1b[0m\r\n",
})
// 构建 SSH 配置
// SSH HostKey 验证 — Trust-On-First-Use (TOFU).
// 首次连接记录 fingerprint 到日志;后续连接通过已知 HostKey 校验。
knownHosts := make(map[string]ssh.PublicKey)
var knownMu sync.Mutex
sshConfig := &ssh.ClientConfig{
User: server.Username,
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
Timeout: 10 * time.Second,
User: server.Username,
Timeout: 10 * time.Second,
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
fp := ssh.FingerprintSHA256(key)
knownMu.Lock()
defer knownMu.Unlock()
if existing, ok := knownHosts[hostname]; ok {
if ssh.FingerprintSHA256(existing) == fp {
return nil
}
return fmt.Errorf("SSH host key mismatch for %s: expected %s, got %s",
hostname, ssh.FingerprintSHA256(existing), fp)
}
// First connection — trust and record
knownHosts[hostname] = key
log.Printf("[WebShell] TOFU: trusting new host key for %s (%s): %s",
server.Hostname, hostname, fp)
return nil
},
}
switch server.AuthType {