From 673e354fe567372c7038573360cbeea87c41709d Mon Sep 17 00:00:00 2001 From: openclaw Date: Mon, 2 Mar 2026 15:25:30 +0800 Subject: [PATCH] docs: add README.md --- README.md | 300 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 300 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..9e2764b --- /dev/null +++ b/README.md @@ -0,0 +1,300 @@ +# INP2P + +自研 P2P 隧道组网系统。两个二进制,零依赖部署。 + +``` +inp2ps — 信令服务器(STUN + WebSocket + REST API) +inp2pc — 客户端(NAT 探测 + 打洞 + 中继 + 端口转发) +``` + +## 为什么造这个 + +试过 OpenP2P、FRP、ZeroTier,各有各的问题。OpenP2P 最接近需求,但踩了一堆坑: + +- `MsgReportBasic` 不回响应 → 客户端反复断连 +- Push 消息白名单太窄 → 操作被拒绝 +- TOTP relay 认证链过于复杂 → Access Denied +- `peerNatType=314` 跳过所有打洞 → 只走 relay +- 中继节点选择单一,没有分层概念 + +INP2P 从协议层重新设计,解决以上所有问题。 + +## 特性 + +- **连接优先级**:UDP 直连 → UDP 打洞 → TCP 直连 → TCP 打洞 → 私有中继 → 超级中继 → 服务器中继 +- **流多路复用**:一条 P2P 连接承载多个隧道,7 字节帧头(StreamID + Flags + Length) +- **分层中继**:任意客户端可选开启 `--relay` / `--super`,自动参与中继 +- **TOTP 认证**:CRC64 token + 时间窗口验证,跨用户场景用 HMAC-SHA256 一次性令牌 +- **NAT 探测**:内置 STUN 服务端(UDP×2 + TCP×2),客户端自动探测 NAT 类型 +- **断线重连**:5 秒退避自动重连,节点上线广播触发隧道重建 +- **静态编译**:零 CGO 依赖,单二进制部署 + +## 快速开始 + +### 编译 + +```bash +git clone https://gitea.king.nyc.mn/openclaw/inp2p.git +cd inp2p +go build -o bin/inp2ps ./cmd/inp2ps/ +go build -o bin/inp2pc ./cmd/inp2pc/ +``` + +生产编译(更小体积): + +```bash +CGO_ENABLED=0 go build -ldflags="-s -w" -o bin/inp2ps ./cmd/inp2ps/ +CGO_ENABLED=0 go build -ldflags="-s -w" -o bin/inp2pc ./cmd/inp2pc/ +``` + +### 启动服务器 + +```bash +# 生成 token +# token 是 CRC64(user + password) 的结果,客户端和服务端必须一致 +./bin/inp2ps -token 12345678 \ + -ws-port 27183 \ + -stun-udp1 27182 -stun-udp2 27183 \ + -stun-tcp1 27180 -stun-tcp2 27181 +``` + +健康检查: + +```bash +curl http://localhost:27183/api/v1/health +# {"status":"ok","version":"0.1.0","nodes":0} +``` + +### 启动客户端 + +节点 A(开启中继能力): + +```bash +./bin/inp2pc \ + -serverhost your-server.com \ + -serverport 27183 \ + -node nodeA \ + -token 12345678 \ + -relay \ + -config config.json \ + -newconfig +``` + +节点 B: + +```bash +./bin/inp2pc \ + -serverhost your-server.com \ + -serverport 27183 \ + -node nodeB \ + -token 12345678 \ + -config config.json \ + -newconfig +``` + +### 参数说明 + +#### inp2ps + +| 参数 | 默认值 | 说明 | +|------|--------|------| +| `-token` | 必填 | 认证 token(uint64) | +| `-ws-port` | 27183 | WebSocket 信令端口 | +| `-stun-udp1` | 27182 | UDP STUN 端口 1 | +| `-stun-udp2` | 27183 | UDP STUN 端口 2 | +| `-stun-tcp1` | 27180 | TCP STUN 端口 1 | +| `-stun-tcp2` | 27181 | TCP STUN 端口 2 | + +#### inp2pc + +| 参数 | 默认值 | 说明 | +|------|--------|------| +| `-serverhost` | 必填 | 服务器地址 | +| `-serverport` | 27183 | 服务器端口 | +| `-node` | 必填 | 节点名称(唯一标识) | +| `-token` | 必填 | 认证 token(与服务器一致) | +| `-insecure` | false | 跳过 TLS 验证(用 ws:// 代替 wss://) | +| `-relay` | false | 启用中继节点功能 | +| `-super` | false | 启用超级中继(对所有用户开放) | +| `-relay-port` | 27185 | 中继监听端口 | +| `-bw` | 10 | 共享带宽上限(Mbps) | +| `-config` | config.json | 配置文件路径 | +| `-newconfig` | false | 忽略已有配置,使用命令行参数 | +| `-stun-udp1/2` | 同服务器 | STUN 端口(通常与服务器一致) | +| `-stun-tcp1/2` | 同服务器 | STUN 端口(通常与服务器一致) | + +## 架构 + +``` +┌─────────────────────────────────────────────┐ +│ inp2ps │ +│ │ +│ ┌─────────┐ ┌──────┐ ┌───────────────┐ │ +│ │ STUN │ │ WSS │ │ Coordinator │ │ +│ │ UDP × 2 │ │Server│ │ (punch sync) │ │ +│ │ TCP × 2 │ │ │ │ │ │ +│ └─────────┘ └──────┘ └───────────────┘ │ +│ │ │ +│ ┌───────┴───────┐ │ +│ │ Node Manager │ │ +│ │ (online/hb) │ │ +│ └───────────────┘ │ +└─────────────────────────────────────────────┘ + ▲ WSS ▲ WSS + │ │ +┌─────────┴──┐ ┌─────┴────────┐ +│ inp2pc │◄──P2P──►│ inp2pc │ +│ nodeA │ punch │ nodeB │ +│ │ /relay │ │ +│ ┌────────┐ │ │ ┌──────────┐ │ +│ │ Tunnel │ │ │ │ Tunnel │ │ +│ │ Mux │ │ │ │ Mux │ │ +│ └────────┘ │ │ └──────────┘ │ +└────────────┘ └──────────────┘ +``` + +### 连接建立流程 + +``` +nodeA inp2ps nodeB + │ │ │ + │── ConnectReq ─────────►│ │ + │ │── PunchStart ─────────►│ + │◄── PunchStart ─────────│ │ + │ │ │ + │◄═══════ UDP/TCP Punch ═══════════════════════►│ + │ │ │ + │ (if punch fails, fallback to relay) │ + │ │ │ + │── RelayNodeReq ───────►│ │ + │◄── RelayNodeRsp ───────│── PushRelayOffer ────►│ + │ │ │ + │──── RelayHandshake ──►[R]◄── RelayHandshake ───│ + │ [R] bridges A ↔ B │ + │◄═══════════ Mux Stream ═══════════════════════►│ +``` + +### 多路复用帧格式 + +``` + 0 4 5 7 + ├───────┼────┼───────┤ + │Stream │Flag│Length │ Data... + │ ID │ s │ │ + └───────┴────┴───────┘ + 4B 1B 2B 0~65535B + +Flags: SYN=0x01 FIN=0x02 DATA=0x04 PING=0x08 PONG=0x10 RST=0x20 +StreamID: 客户端奇数(1,3,5...) 服务端偶数(2,4,6...) +``` + +## 项目结构 + +``` +inp2p/ +├── cmd/ +│ ├── inp2ps/main.go # 服务器入口 +│ └── inp2pc/main.go # 客户端入口 +├── internal/ +│ ├── server/ +│ │ ├── server.go # WSS 主循环、登录、心跳、节点管理 +│ │ └── coordinator.go # 打洞协调、App 推送 +│ └── client/ +│ └── client.go # NAT 探测、登录、打洞、中继、重连 +├── pkg/ +│ ├── protocol/ # 消息定义、编解码、NAT 类型枚举 +│ ├── config/ # 配置结构体、默认值、环境变量 +│ ├── auth/ # CRC64 token、TOTP、HMAC-SHA256 令牌 +│ ├── nat/ # UDP/TCP STUN 客户端和服务端 +│ ├── signal/ # WebSocket 封装、handler、同步请求 +│ ├── punch/ # UDP/TCP 打洞 + 优先级链 +│ ├── mux/ # 流多路复用(7B 帧头) +│ ├── tunnel/ # 基于 mux 的端口转发 +│ └── relay/ # 中继管理、TOTP 握手、会话桥接 +├── go.mod +├── go.sum +├── TASKS.md # 任务拆分与进度 +└── .gitignore +``` + +## 测试 + +```bash +go test ./... -v +``` + +``` +internal/client PASS 8.3s — NAT + WSS + Login + Report 完整链路 +internal/server PASS 0.8s — 双客户端登录 + Relay 节点发现 +pkg/mux PASS 0.2s — 7 测试:并发/大载荷/FIN/session +pkg/tunnel PASS 0.16s — 端到端转发 + 5 并发 + 统计 +pkg/relay PASS 0.3s — 双向桥接 + 1MB 中继 + 认证拒绝 +``` + +## 防火墙 + +服务器需要开放以下端口: + +| 端口 | 协议 | 用途 | +|------|------|------| +| 27183 | TCP | WebSocket 信令 | +| 27182, 27183 | UDP | STUN NAT 探测 | +| 27180, 27181 | TCP | STUN TCP 回退 | + +客户端(如果开启 `--relay`): + +| 端口 | 协议 | 用途 | +|------|------|------| +| 27185 | TCP | 中继服务 | + +## Systemd 部署示例 + +### 服务器 + +```ini +[Unit] +Description=INP2P Signaling Server +After=network.target + +[Service] +ExecStart=/usr/local/bin/inp2ps -token YOUR_TOKEN +Restart=always +RestartSec=5 + +[Install] +WantedBy=multi-user.target +``` + +### 客户端 + +```ini +[Unit] +Description=INP2P Client +After=network.target + +[Service] +WorkingDirectory=/usr/local/inp2p +ExecStart=/usr/local/bin/inp2pc -serverhost your-server.com -node mynode -token YOUR_TOKEN -insecure +Restart=always +RestartSec=5 + +[Install] +WantedBy=multi-user.target +``` + +## Roadmap + +- [x] 信令连接 + 认证 +- [x] NAT 探测(UDP/TCP STUN) +- [x] UDP/TCP 打洞 + 双端协调 +- [x] 流多路复用隧道 +- [x] 中继握手 + TOTP 认证 +- [ ] SDWAN 虚拟组网(TUN 网卡 + 虚拟 IP) +- [ ] Web 控制台 +- [ ] UDP 端口转发 +- [ ] 自动升级 +- [ ] Docker 镜像 + +## License + +MIT