|
1 | | -# anp-proxy |
2 | | -A reverse proxy service for the ANP protocol |
| 1 | +# ANP Proxy |
| 2 | + |
| 3 | +Agent Network Proxy (ANP) - 高性能 HTTP over WebSocket 隧道,用于私有网络服务的安全对外暴露。 |
| 4 | + |
| 5 | +## 特性 |
| 6 | + |
| 7 | +- 🚀 **高性能异步架构** - 基于 asyncio 的纯异步实现 |
| 8 | +- 🔒 **安全可靠** - WSS (TLS) + 双向认证 + CRC 校验 |
| 9 | +- 📦 **二进制协议** - 自定义 ANPX 协议,支持大文件分片传输 |
| 10 | +- 🔧 **框架无关** - 支持任意 ASGI 应用 (FastAPI, Django, Flask 等) |
| 11 | +- 🔄 **自动重连** - 断线自动重连,指数退避策略 |
| 12 | +- 📊 **监控友好** - 详细的日志和统计信息 |
| 13 | +- ⚙️ **易于配置** - TOML 配置文件 + 命令行参数 |
| 14 | + |
| 15 | +## 架构概览 |
| 16 | + |
| 17 | +``` |
| 18 | +┌────────────┐ WSS (TLS) ┌──────────────┐ |
| 19 | +│ Client │ ─HTTP→ ┌──────────────┐ ─────→ │ Receiver & │ |
| 20 | +│ 外部调用者 │ │ Gateway │ │ Internal App│ |
| 21 | +└────────────┘ ←HTTP─ └──────────────┘ ←───── │ (FastAPI …) │ |
| 22 | + ↑ ↓ └──────────────┘ |
| 23 | + Request 包装 Response 包装 |
| 24 | +``` |
| 25 | + |
| 26 | +## 快速开始 |
| 27 | + |
| 28 | +### 安装 |
| 29 | + |
| 30 | +```bash |
| 31 | +# 使用 UV 安装 (推荐) |
| 32 | +uv add anp-proxy |
| 33 | + |
| 34 | +# 或使用 pip |
| 35 | +pip install anp-proxy |
| 36 | +``` |
| 37 | + |
| 38 | +### 基本使用 |
| 39 | + |
| 40 | +#### 1. 开发模式 (Gateway + Receiver 一体) |
| 41 | + |
| 42 | +```bash |
| 43 | +# 启动一体化代理,服务本地 FastAPI 应用 |
| 44 | +anp-proxy --mode both --local-app "myapp:app" --gateway-port 8080 |
| 45 | +``` |
| 46 | + |
| 47 | +#### 2. 生产模式 - Gateway (公网部署) |
| 48 | + |
| 49 | +```bash |
| 50 | +# 在公网服务器启动 Gateway |
| 51 | +anp-proxy --mode gateway --gateway-host 0.0.0.0 --gateway-port 80 --wss-port 443 |
| 52 | +``` |
| 53 | + |
| 54 | +#### 3. 生产模式 - Receiver (私网部署) |
| 55 | + |
| 56 | +```bash |
| 57 | +# 在私网启动 Receiver,连接到公网 Gateway |
| 58 | +anp-proxy --mode receiver --gateway-url "wss://your-gateway.com:443" --local-app "myapp:app" |
| 59 | +``` |
| 60 | + |
| 61 | +### 配置文件 |
| 62 | + |
| 63 | +创建 `config.toml`: |
| 64 | + |
| 65 | +```toml |
| 66 | +mode = "both" # gateway, receiver, both |
| 67 | + |
| 68 | +[gateway] |
| 69 | +host = "0.0.0.0" |
| 70 | +port = 8080 |
| 71 | +wss_port = 8765 |
| 72 | + |
| 73 | +[receiver] |
| 74 | +gateway_url = "wss://localhost:8765" |
| 75 | +local_app_module = "myapp:app" |
| 76 | + |
| 77 | +[logging] |
| 78 | +level = "INFO" |
| 79 | +``` |
| 80 | + |
| 81 | +使用配置文件: |
| 82 | + |
| 83 | +```bash |
| 84 | +anp-proxy --config config.toml |
| 85 | +``` |
| 86 | + |
| 87 | +## 详细配置 |
| 88 | + |
| 89 | +### Gateway 配置 |
| 90 | + |
| 91 | +```toml |
| 92 | +[gateway] |
| 93 | +# HTTP 服务器设置 |
| 94 | +host = "0.0.0.0" |
| 95 | +port = 8080 |
| 96 | + |
| 97 | +# WebSocket 服务器设置 |
| 98 | +wss_host = "0.0.0.0" |
| 99 | +wss_port = 8765 |
| 100 | + |
| 101 | +# 连接设置 |
| 102 | +max_connections = 100 |
| 103 | +timeout = 30.0 |
| 104 | +chunk_size = 65536 # 64KB |
| 105 | + |
| 106 | +[gateway.tls] |
| 107 | +enabled = true |
| 108 | +cert_file = "server.crt" |
| 109 | +key_file = "server.key" |
| 110 | +verify_mode = "required" |
| 111 | + |
| 112 | +[gateway.auth] |
| 113 | +enabled = true |
| 114 | +shared_secret = "your-secret-key" |
| 115 | +token_expiry = 3600 |
| 116 | +``` |
| 117 | + |
| 118 | +### Receiver 配置 |
| 119 | + |
| 120 | +```toml |
| 121 | +[receiver] |
| 122 | +# Gateway 连接 |
| 123 | +gateway_url = "wss://gateway.example.com:8765" |
| 124 | + |
| 125 | +# 本地应用设置 |
| 126 | +local_app_module = "myapp:app" # ASGI 应用 |
| 127 | + |
| 128 | +# 重连设置 |
| 129 | +reconnect_enabled = true |
| 130 | +reconnect_delay = 5.0 |
| 131 | +max_reconnect_attempts = 10 |
| 132 | + |
| 133 | +[receiver.tls] |
| 134 | +enabled = true |
| 135 | +ca_file = "ca.crt" |
| 136 | +verify_mode = "required" |
| 137 | + |
| 138 | +[receiver.auth] |
| 139 | +enabled = true |
| 140 | +shared_secret = "your-secret-key" |
| 141 | +``` |
| 142 | + |
| 143 | +## Python API |
| 144 | + |
| 145 | +### 编程方式使用 |
| 146 | + |
| 147 | +```python |
| 148 | +import asyncio |
| 149 | +from anp_proxy import ANPProxy, ANPConfig |
| 150 | + |
| 151 | +# 创建配置 |
| 152 | +config = ANPConfig(mode="both") |
| 153 | +config.gateway.port = 8080 |
| 154 | +config.receiver.local_app_module = "myapp:app" |
| 155 | + |
| 156 | +# 创建并运行代理 |
| 157 | +async def main(): |
| 158 | + proxy = ANPProxy(config) |
| 159 | + |
| 160 | + if config.mode == "gateway": |
| 161 | + gateway = proxy.create_gateway_server() |
| 162 | + await gateway.run() |
| 163 | + elif config.mode == "receiver": |
| 164 | + receiver = proxy.create_receiver_client() |
| 165 | + await receiver.run() |
| 166 | + |
| 167 | +asyncio.run(main()) |
| 168 | +``` |
| 169 | + |
| 170 | +### 集成到现有应用 |
| 171 | + |
| 172 | +```python |
| 173 | +from fastapi import FastAPI |
| 174 | +from anp_proxy import ReceiverClient, ReceiverConfig |
| 175 | + |
| 176 | +app = FastAPI() |
| 177 | + |
| 178 | +@app.get("/") |
| 179 | +async def root(): |
| 180 | + return {"message": "Hello World"} |
| 181 | + |
| 182 | +# 创建 ANP Receiver |
| 183 | +config = ReceiverConfig(gateway_url="wss://gateway.example.com:8765") |
| 184 | +receiver = ReceiverClient(config, app) |
| 185 | + |
| 186 | +# 启动 receiver (在后台任务中) |
| 187 | +import asyncio |
| 188 | +asyncio.create_task(receiver.run()) |
| 189 | +``` |
| 190 | + |
| 191 | +## ANPX 协议 |
| 192 | + |
| 193 | +ANP Proxy 使用自定义的 ANPX 二进制协议,支持: |
| 194 | + |
| 195 | +- **固定 24B 头部** - 魔数、版本、类型、标志、长度、CRC 校验 |
| 196 | +- **TLV 扩展体** - 灵活的标签-长度-值格式 |
| 197 | +- **分片传输** - 支持大文件和流式内容 |
| 198 | +- **端到端校验** - CRC-32 双层校验保证数据完整性 |
| 199 | + |
| 200 | +详细协议规范请参考 [docs/proxy-protocol.md](docs/proxy-protocol.md) |
| 201 | + |
| 202 | +## 监控和运维 |
| 203 | + |
| 204 | +### 健康检查 |
| 205 | + |
| 206 | +```bash |
| 207 | +# 检查 Gateway 状态 |
| 208 | +curl http://localhost:8080/health |
| 209 | + |
| 210 | +# 获取统计信息 |
| 211 | +curl http://localhost:8080/stats |
| 212 | +``` |
| 213 | + |
| 214 | +### 日志配置 |
| 215 | + |
| 216 | +```toml |
| 217 | +[logging] |
| 218 | +level = "INFO" # DEBUG, INFO, WARNING, ERROR |
| 219 | +format = "%(asctime)s [%(levelname)s] %(name)s: %(message)s" |
| 220 | +file = "anp-proxy.log" |
| 221 | +max_size = "10MB" |
| 222 | +backup_count = 5 |
| 223 | +``` |
| 224 | + |
| 225 | +### 性能调优 |
| 226 | + |
| 227 | +```toml |
| 228 | +[gateway] |
| 229 | +chunk_size = 131072 # 128KB,适合大文件传输 |
| 230 | +max_connections = 1000 # 最大连接数 |
| 231 | +timeout = 60.0 # 超时时间 |
| 232 | + |
| 233 | +[receiver] |
| 234 | +chunk_size = 131072 |
| 235 | +reconnect_delay = 2.0 # 重连延迟 |
| 236 | +``` |
| 237 | + |
| 238 | +## 部署示例 |
| 239 | + |
| 240 | +### Docker 部署 |
| 241 | + |
| 242 | +```dockerfile |
| 243 | +FROM python:3.11-slim |
| 244 | + |
| 245 | +WORKDIR /app |
| 246 | +COPY requirements.txt . |
| 247 | +RUN pip install -r requirements.txt |
| 248 | + |
| 249 | +COPY . . |
| 250 | +EXPOSE 8080 8765 |
| 251 | + |
| 252 | +CMD ["anp-proxy", "--config", "config.toml"] |
| 253 | +``` |
| 254 | + |
| 255 | +### Systemd 服务 |
| 256 | + |
| 257 | +```ini |
| 258 | +[Unit] |
| 259 | +Description=ANP Proxy Gateway |
| 260 | +After=network.target |
| 261 | + |
| 262 | +[Service] |
| 263 | +Type=exec |
| 264 | +User=anp-proxy |
| 265 | +WorkingDirectory=/opt/anp-proxy |
| 266 | +ExecStart=/opt/anp-proxy/venv/bin/anp-proxy --config config.toml |
| 267 | +Restart=always |
| 268 | +RestartSec=10 |
| 269 | + |
| 270 | +[Install] |
| 271 | +WantedBy=multi-user.target |
| 272 | +``` |
| 273 | + |
| 274 | +## 故障排除 |
| 275 | + |
| 276 | +### 常见问题 |
| 277 | + |
| 278 | +1. **连接失败** |
| 279 | + - 检查防火墙设置 |
| 280 | + - 验证 WebSocket URL 是否正确 |
| 281 | + - 确认 TLS 证书配置 |
| 282 | + |
| 283 | +2. **认证失败** |
| 284 | + - 检查 shared_secret 是否一致 |
| 285 | + - 验证时间同步 (重要) |
| 286 | + |
| 287 | +3. **性能问题** |
| 288 | + - 调整 chunk_size |
| 289 | + - 增加 max_connections |
| 290 | + - 检查网络延迟 |
| 291 | + |
| 292 | +### 调试模式 |
| 293 | + |
| 294 | +```bash |
| 295 | +anp-proxy --debug --log-level DEBUG |
| 296 | +``` |
| 297 | + |
| 298 | +## 许可证 |
| 299 | + |
| 300 | +MIT License - 详见 [LICENSE](LICENSE) 文件 |
| 301 | + |
| 302 | +## 贡献 |
| 303 | + |
| 304 | +欢迎提交 Issue 和 Pull Request! |
| 305 | + |
| 306 | +## 支持 |
| 307 | + |
| 308 | +- 📖 [文档](docs/) |
| 309 | +- 🐛 [Issue Tracker](https://github.com/your-org/anp-proxy/issues) |
| 310 | +- 💬 [讨论区](https://github.com/your-org/anp-proxy/discussions) |
0 commit comments