BadBoy0170/p2p-sec-mesh
GitHub: BadBoy0170/p2p-sec-mesh
一个零信任 P2P 安全网格系统,通过去中心化的 AI 威胁分析和节点共识投票实现自动化的恶意节点隔离,防止内网横向移动。
Stars: 0 | Forks: 0
# P2P 零信任安全网格
[](https://golang.org)
[](https://python.org)
[](https://grpc.io)
[](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工具, 安全防护, 微隔离, 日志审计, 流量监控, 版权保护, 程序破解, 自定义脚本, 逆向工具, 零信任网络