docs: add README.md

This commit is contained in:
2026-03-02 15:25:30 +08:00
parent 85c094a095
commit 673e354fe5

300
README.md Normal file
View File

@@ -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` | 必填 | 认证 tokenuint64 |
| `-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