docs: add README.md
This commit is contained in:
300
README.md
Normal file
300
README.md
Normal 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` | 必填 | 认证 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
|
||||||
Reference in New Issue
Block a user