BadBoy0170/p2p-sec-mesh

GitHub: BadBoy0170/p2p-sec-mesh

一个零信任 P2P 安全网格系统,通过去中心化的 AI 威胁分析和节点共识投票实现自动化的恶意节点隔离,防止内网横向移动。

Stars: 0 | Forks: 0

# P2P 零信任安全网格 [![Go](https://img.shields.io/badge/Go-1.22-00ADD8?logo=go)](https://golang.org) [![Python](https://img.shields.io/badge/Python-3.11-3776AB?logo=python)](https://python.org) [![gRPC](https://img.shields.io/badge/gRPC-1.64-00897B?logo=grpc)](https://grpc.io) [![Docker](https://img.shields.io/badge/Docker-Compose-2496ED?logo=docker)](https://docker.com) ## 它解决的问题 在传统的企业网络中,防火墙的一次被突破就会给攻击者带来**自由的横向移动**权限。其他所有机器默认信任其相邻节点。 本项目消除了这一假设。每个节点**持续监控自身及其相邻节点**。当节点通过 CPU 飙升、蜜罐触发或可疑流量检测到入侵时,它会使用本地 LLM 对威胁进行评分,然后**通过加密方式向网格广播隔离投票**。节点验证签名并在几秒钟内切断连接,**无需任何中央权威**。 ## 架构 ``` ┌───────────────┐ │ Coordinator │ ← HTTP REST + Web Dashboard (port 8090) │ (Phonebook) │ Introduces nodes, serves topology UI. └──────┬────────┘ Steps back from security decisions. │ register ┌────────────┼────────────┐ │ │ │ ┌────▼────┐ ┌────▼────┐ ┌────▼────┐ │ Node A │ │ Node B │ │ Node C │ │ Go+AI │◄─┤ Go+AI ├─►│ Go+AI │ └─────────┘ └─────────┘ └─────────┘ │ │ │ └────────────┴────────────┘ Direct P2P gRPC (mTLS) ``` 每个节点运行两个进程(Sidecar 架构): | 进程 | 语言 | 职责 | |---------|----------|----------------| | **Peer 节点** | Go | 网络、蜜罐、遥测、Gossip、加密 | | **AI Sidecar** | Python | 通过 Ollama 进行 LLM 查询、威胁评分、Pydantic 响应验证 | ## 威胁生命周期(分步说明) ``` ┌─────────────────────┐ Attacker ──► port 2222 ──► Honeypot ──► │ TelemetryEvent │ │ (core.EventCh) │ └────────┬────────────┘ │ gRPC ┌────────▼────────────┐ │ Python AI Sidecar │ │ (Ollama LLM) │ │ threat_score: 8 │ ← fallback: rule-based └────────┬────────────┘ if Ollama unavailable │ > 7 threshold ┌────────▼────────────┐ │ Sign QuarantineVote│ │ (Ed25519) │ └────────┬────────────┘ │ broadcast ┌──────────────┴──────────────┐ ┌────▼────┐ ┌────▼────┐ │ Node A │ verify signature │ Node C │ │ sever ✓ │ │ sever ✓ │ └─────────┘ └─────────┘ │ ┌────────▼────────────┐ │ /api/report │ ← visible in dashboard │ AI Events feed │ └─────────────────────┘ ``` 1. **渗透** — 攻击者连接到端口 2222(模拟 SSH)上的蜜罐。 2. **遥测** — Go 层检测到未经授权的尝试,并将 `TelemetryEvent` 加入队列。 3. **推理** — Go sidecar 桥接层将其通过 gRPC 转发给 Python AI。 4. **分析** — Python 使用严格的仅限 JSON 的 system prompt 查询 Ollama (`dolphin-llama3`)。如果 Ollama 不可用,确定性的基于规则的备用方案会自动将 `HONEYPOT_TRIPPED` 评分设为 9/10。 5. **Gossip** — 如果 `threat_score > 7`,受入侵的节点会使用其 Ed25519 私钥签署 `QuarantineVote` 并将其广播给所有节点。 6. **共识** — 节点在计算票数之前先验证加密签名。自投票触发立即隔离;外部投票则需要获得绝对多数票 (> 50%)。 7. **自我修复** — 达成共识后,网格会切断与被隔离节点的所有 TCP 连接。健康节点之间保持连接。 8. **报告** — 决策(分数、方法 `ai`/`rule-based`、决策 `quarantine`/`monitor`)被推送到协调器的 `/api/report` 端点,并在 Web 仪表板中实时显示。 ## 技术栈 | 组件 | 技术 | 原因 | |-----------|-----------|-----| | **P2P 网络** | Go (Goroutines) | 数千个并发连接,<1ms 的 goroutine 生成 | | **AI 推理** | Python + Ollama | 原生 LLM 生态系统,易于进行 prompt 工程 | | **桥接协议** | gRPC (protobuf) | 类型安全,Go 和 Python 之间毫秒级的 IPC | | **传输安全** | mTLS(双向 TLS) | 客户端和服务器均验证身份 — 恶意节点在握手阶段即被拒绝 | | **身份/签名** | Ed25519 | 64 字节签名,验证速度快,不受时序攻击影响 | | **速率限制** | Token-Bucket (`x/time/rate`) | 防止 P2P 数据包泛洪导致的内存耗尽 | | **防注入** | Regex 清理 + 截断 | 在输入 LLM 前剔除注入关键词和控制字符 | | **容器化** | Docker Compose | 一条命令即可复现的 5 节点集群 | | **Web 仪表板** | vis.js + Vanilla JS | 实时拓扑图,在出现异常/隔离节点时带有动画发光效果 | ## 安全强化 ### mTLS(双向 TLS) 所有 P2P gRPC 连接都需要由项目的本地 CA 签名的证书。未提供有效证书的恶意容器会在握手层被**立即拒绝** — 应用程序代码永远看不到它的数据包。 ### Token-Bucket 速率限制 每个节点的传入 gRPC 端口运行着一个 `golang.org/x/time/rate` 限制器:每个源 IP 每秒 10 个请求。数据包泛洪在反序列化之前就会被丢弃,从而防止内存耗尽。 ### Ed25519 签名验证 每个 `QuarantineVote` 都使用发起节点的 Ed25519 私钥进行签名。接收节点在统计票数之前会验证签名。伪造的隔离投票 — 即使看起来合法 — 也会被**拒绝**。 ### Prompt 注入清理 Python sidecar 在将遥测数据嵌入到 LLM prompt 之前,会剔除注入关键词(`ignore`、`disregard`、`system prompt` 等)、控制字符以及反引号/大括号。数据包源 IP 中受攻击者控制的输入无法操纵 LLM 的输出。 ### 蜜罐架构 伪造的 SSH (2222) 和 HTTP (8888) 监听器接受连接,但**不提供任何数据**并立即关闭。任何连接都被视为严重入侵 — 这些端口没有任何合法用途。 ### 基于规则的备用方案 如果 AI sidecar 或 Ollama 无法访问,`HONEYPOT_TRIPPED` 事件仍会通过确定性规则触发隔离(评分 = 9/10)。系统绝不会默默地忽略入侵。 ## 项目结构 ``` p2p-sec-mesh/ ├── coordinator/ # HTTP REST peer registry + web dashboard (Go) │ ├── main.go # Registry, /api/topology, /api/report, HTTP handlers │ ├── index.html # Web dashboard (topology graph + AI events feed) │ ├── styles.css # Minimal system-font dark UI │ ├── js/ │ │ ├── app.js # Dashboard controller (polls topology + report API) │ │ ├── NetworkGraph.js # vis.js graph with animated pulse for anomaly nodes │ │ └── ApiService.js # Fetch wrapper │ └── Dockerfile │ ├── peer-node/ # P2P node (Go) │ ├── main.go # Entry point — wires all subsystems │ ├── node_keys.go # Ed25519 key generation │ ├── core/ │ │ ├── network.go # Coordinator registration, mTLS gRPC, heartbeat │ │ ├── gossip.go # Vote signing, signature verification, quarantine │ │ └── sidecar.go # Go→Python gRPC bridge, AI + rule-based fallback, report push │ ├── telemetry/ │ │ ├── monitor.go # CPU/RAM monitoring (gopsutil) │ │ └── honeypot.go # Fake SSH/HTTP listeners │ └── Dockerfile │ ├── analyzer/ # AI Sidecar (Python) │ ├── app.py # gRPC server (port 50052) │ ├── llm_client.py # Ollama integration + sanitization + Pydantic validation │ ├── stubs/ # Auto-generated gRPC Python stubs │ ├── requirements.txt │ └── Dockerfile │ ├── protos/ │ └── sidecar.proto # Shared message definitions │ ├── gen/go/ # Auto-generated Go gRPC stubs ├── generate_certs.sh # mTLS CA + certificate generation script ├── docker-compose.yml # 5-node cluster orchestration ├── run_self_healing_cluster.sh # 30-node local bash demo (no Docker) ├── go.mod # Go module └── go.work # Go workspace ``` ## 快速开始(Docker — 推荐) ### 前置条件 - 带有 Compose v2 的 Docker Desktop - `make`(macOS/Linux 上已预装) - 约 6 GB 可用内存(Ollama 运行 `dolphin-llama3` 约需 4 GB) ### 只需一条命令 — 就这么简单 ``` git clone https://github.com/BadBoy0170/p2p-sec-mesh cd p2p-sec-mesh make up ``` 这将启动: | 容器 | 角色 | |-----------|------| | `coordinator` | Peer 节点通讯录 + Web 仪表板 | | `ollama` | 本地 LLM 引擎 | | `ollama-init` | 一次性拉取模型 (`dolphin-llama3`),然后退出 | | `node-{a..e}-go` | 5 个 Go peer 节点 | | `node-{a..e}-ai` | 5 个 Python AI sidecar | ### 打开仪表板 ``` http://localhost:8090 ``` 拓扑图每 5 秒自动更新一次。侧边栏中的 **AI 事件**面板会实时显示每一次威胁检测。 ### 触发攻击 ``` # 攻击单个节点 make attack NODE=a # 同时攻击所有 5 个节点(压力测试 consensus voting) make attack-all ``` ### 查看日志 ``` make logs # all containers make logs-node NODE=a # just node-a ``` 预期序列: ``` node-a-go | [HONEYPOT] INTRUSION DETECTED on mock-SSH port 2222 from 172.20.0.1 node-a-ai | [LLM] Model returned threat_score=9 node-a-go | [SIDECAR] CRITICAL THREAT (9.0) — initiating self-quarantine broadcast node-a-go | [GOSSIP] Broadcasting quarantine vote for to 4 peer(s) node-b-go | [GOSSIP] Vote 1 for quarantine of (from ) node-b-go | [GOSSIP] QUARANTINING NODE — severing all connections ``` Node-a 被隔离。节点 B–E 保持连接。仪表板显示 node-a 呈现红色发光。 ### 检查网格状态 ``` make topology # current graph JSON make report # AI threat event log make status # container health ``` ### 停止并清理 ``` make down # stop containers make clean # also remove images + volumes ``` ### 所有 Makefile 目标 | 目标 | 描述 | |--------|-------------| | `make up` | 构建 + 启动一切 | | `make down` | 停止所有容器 | | `make restart` | 重新构建并重启 | | `make logs` | 流式传输所有日志 | | `make logs-node NODE=b` | 特定节点的日志 | | `make attack NODE=a` | 触发 node-a 上的蜜罐 | | `make attack-all` | 同时攻击所有 5 个节点 | | `make topology` | 打印当前网格拓扑 JSON | | `make report` | 打印 AI 威胁事件日志 | | `make status` | 显示容器健康状态 | | `make clean` | 移除容器、镜像、数据卷 | ## 快速开始(本地 — 无 Docker) ### 前置条件 - Go 1.22+ - Python 3.11+ - 本地运行 [Ollama](https://ollama.com) 并拉取了 `dolphin-llama3` ``` ollama pull dolphin-llama3 ``` ### 运行 30 节点模拟 ``` chmod +x run_self_healing_cluster.sh ./run_self_healing_cluster.sh ``` 打开 `http://localhost:8090`。该脚本会启动 30 个节点,攻击 node-14,等待其被隔离,然后自动启动一个替代副本。 ### 手动设置 ``` # Terminal 1 — Coordinator go run ./coordinator # Terminal 2 — AI Sidecar cd analyzer && python -m venv venv && source venv/bin/activate pip install -r requirements.txt SIDECAR_PORT=50051 OLLAMA_URL=http://localhost:11434 python app.py # Terminal 3+ — Peer 节点(使用不同端口重复操作) NODE_ID=node-a P2P_PORT=9001 LOCAL_MODE=true \ HONEYPOT_SSH_PORT=2222 SIDECAR_ADDR=localhost:50051 \ go run ./peer-node ``` ## 配置参考 | 环境变量 | 默认值 | 描述 | |---------------------|---------|-------------| | `COORDINATOR_URL` | `http://localhost:8090` | Coordinator REST 端点 | | `COORDINATOR_PORT` | `8090` | Coordinator 监听端口 | | `P2P_PORT` | `9000` | 节点的 P2P gRPC 监听端口 | | `NODE_HOSTNAME` | `localhost` | 向节点广播的主机名 | | `NODE_ID` | — | 友好名称(用于日志记录 + 仪表板) | | `SIDECAR_ADDR` | `localhost:50052` | Python AI sidecar gRPC 地址 | | `SIDECAR_PORT` | `50052` | AI sidecar 监听端口 | | `LOCAL_MODE` | `false` | 跳过 mTLS(用于没有证书的本地开发) | | `CERT_FILE` | `certs/peer.pem` | mTLS 证书 | | `KEY_FILE` | `certs/peer.key` | mTLS 私钥 | | `CA_FILE` | `certs/ca.pem` | 证书颁发机构 (CA) 证书 | | `HONEYPOT_SSH_PORT` | `2222` | 模拟 SSH 蜜罐端口 | | `HONEYPOT_HTTP_PORT` | `8888` | 模拟 HTTP 蜜罐端口 | | `OLLAMA_URL` | `http://localhost:11434` | Ollama API 端点 | | `OLLAMA_MODEL` | `dolphin-llama3` | 用于威胁分析的 LLM 模型 | ## API 参考 | 端点 | 方法 | 描述 | |----------|--------|-------------| | `/` | GET | Web 仪表板 | | `/healthz` | GET | 健康检查 (`ok`) | | `/register` | POST | 节点自注册 | | `/peers` | GET | 所有活跃的节点 | | `/api/telemetry` | POST | 节点状态推送(状态、CPU、RAM、节点列表) | | `/api/topology` | GET | 仪表板当前图状态 | | `/api/report` | GET | AI/规则事件日志 (JSON) | | `/api/report/submit` | POST | 节点在此处推送威胁决策 | ## 设计决策与权衡 ### PKI 架构 本项目使用**每节点 PKI (F-01)**。每个节点都会收到包含自己 SAN(Subject Alternative Name)的唯一证书。这可防止受入侵的节点在 TLS 层伪装成另一个节点。 ### 为什么选择 Ed25519 而不是 RSA/ECDSA? 密钥更小(32 字节对 256 字节 RSA),签名速度比 ECDSA-256 快约 3 倍,并且由于采用恒定时间设计,可抵御时序攻击。 ### 为什么多数共识而不是一致投票? 已经失去连接的隔离节点无法投票。要求一致会导致死锁。绝对多数票 (> 50%) 确保了即使在某些节点无法访问时也能保持活跃性。 ### 为什么需要基于规则的备用方案? LLM 可能无法使用(冷启动、网络问题)。`HONEYPOT_TRIPPED` 的误报率为零 — 连接到蜜罐端口没有任何正当理由。该备用方案确保了网格在没有 AI 的情况下也能做出响应。 ## 已实施的安全增强功能 - ~~将共享的 `peer.pem` 替换为每节点证书(每个容器具有唯一的 SAN)。~~ **(F-01: 每节点 PKI 已实施)** - ~~通过适当的 PKI(例如 Vault、cert-manager)添加证书轮换。~~ - ~~使用已签名/已验证的协调器响应来防止 MITM 节点注入。~~ **(F-03: 已签名的协调器响应 + TOFU 绑定已实施)** - ~~添加信誉评分,对长期建立的节点的投票赋予更高权重。~~ **(GAP-08 / F-05: 信誉加权共识已实施)** - ~~实施投票重放预防(nonce 或单调时间戳计数器)。~~ **(GAP-01 / GAP-12: 时间戳过期和轮转哈希桶已实施)** - ~~在重启后持久化 Ed25519 节点身份。~~ **(GAP-06 / F-04: 持久化节点身份已实施)** - **(F-10: 分布式审计日志)**:现在,每个 Gossip 事件都会被签名并记录在每个节点的只附加(append-only) `audit.log` 中,以供取证。
标签:AI风险缓解, Go语言, P2P网络, Python工具, 安全防护, 微隔离, 日志审计, 流量监控, 版权保护, 程序破解, 自定义脚本, 逆向工具, 零信任网络