53caaf54f0
- CLAUDE.md 重写:去掉 EC2/marzban 部署、架构、cutover/rollback 命令、自动部署 CD; 改为自有 VPS 自建方向(RackNerd Debian 12、ssh racknerd 免密、512MB→SQLite)、 补 server/ Go 后端与多数据库(DB_DRIVER)说明;保留设计 token 单源段 - 删 docs/回滚手册.md(EC2 edge 切换/回滚,脚本已删) - 删 docs/备份与灾备.md(EC2 MySQL/marzban xtrabackup→S3,backup 栈已删) - app/kernel/poc/README.md:REALITY 参数来源由 EC2 改为自建节点(single-node) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
132 lines
4.3 KiB
Markdown
132 lines
4.3 KiB
Markdown
# Pangolin 桌面端 PoC M1 — 接线指南
|
||
|
||
**任务**: tsk_SLCsjNgtmng3 · M1 首发打通(macOS TUN + REALITY)
|
||
|
||
## 前置条件
|
||
|
||
### 1. 下载 sing-box 二进制
|
||
|
||
```bash
|
||
# macOS Apple Silicon
|
||
cd app/kernel
|
||
./fetch-desktop-bin.sh darwin arm64
|
||
|
||
# macOS Intel
|
||
./fetch-desktop-bin.sh darwin amd64
|
||
```
|
||
|
||
产物: `app/kernel/dist/desktop/darwin-arm64/sing-box`
|
||
|
||
### 2. 配置 TUN 提权(macOS PoC)
|
||
|
||
sing-box TUN 模式需要创建 `utun` 接口,必须有 root 权限。PoC 阶段使用 `sudo`:
|
||
|
||
```bash
|
||
# 方式 A: sudoers 免密白名单(推荐,避免每次输密码)
|
||
SINGBOX_PATH="$(pwd)/app/kernel/dist/desktop/darwin-arm64/sing-box"
|
||
echo "$(whoami) ALL=(root) NOPASSWD: ${SINGBOX_PATH}" | sudo tee /etc/sudoers.d/pangolin-singbox
|
||
sudo chmod 440 /etc/sudoers.d/pangolin-singbox
|
||
|
||
# 方式 B: 用 setuid(不推荐用于正式版)
|
||
sudo chown root "${SINGBOX_PATH}"
|
||
sudo chmod u+s "${SINGBOX_PATH}"
|
||
```
|
||
|
||
> **正式版说明**: macOS 正式版应使用 SMJobBless 注册特权 Helper Daemon,
|
||
> 并完成 Apple 公证 (notarization)。此 PoC 路径记录在 BACKLOG-11D-HELPER。
|
||
|
||
### 3. 获取 REALITY 服务端参数
|
||
|
||
从自建节点(`deploy/single-node`)拿 REALITY 公钥/short_id 和节点 UUID:
|
||
|
||
```bash
|
||
# 节点上由 single-node/deploy.sh 生成的 REALITY 参数:
|
||
ssh <node> "grep -E 'REALITY_PBK|REALITY_SHORT_ID' /etc/pangolin/reality.env"
|
||
# 节点 UUID:见 single-node 的 seed,或控制面 nodes 表
|
||
```
|
||
|
||
### 4. 渲染 PoC 配置
|
||
|
||
```bash
|
||
export SERVER_HOST="<节点公网IP>" # 自建节点公网 IP
|
||
export SERVER_PORT="11443" # REALITY 端口
|
||
export REALITY_UUID="your-uuid-here"
|
||
export REALITY_PUBLIC_KEY="your-x25519-public-key"
|
||
export REALITY_SHORT_ID="your-short-id"
|
||
export REALITY_SNI="www.apple.com"
|
||
|
||
./app/kernel/poc/gen-poc-config.sh --out /tmp/pangolin-poc-config.json
|
||
```
|
||
|
||
## 验收测试
|
||
|
||
### M1 验收步骤
|
||
|
||
```bash
|
||
# 1. 设置二进制路径
|
||
export PANGOLIN_SINGBOX_BIN="$(pwd)/app/kernel/dist/desktop/darwin-arm64/sing-box"
|
||
|
||
# 2. 用渲染后的 config 启动(PoC 会自动 sudo)
|
||
sudo "${PANGOLIN_SINGBOX_BIN}" run -c /tmp/pangolin-poc-config.json &
|
||
KERNEL_PID=$!
|
||
|
||
# 3. 等待就绪(Clash API)
|
||
sleep 3
|
||
|
||
# 4. 验证出口 IP
|
||
curl -s https://ifconfig.me # 应显示节点 IP(18.136.60.128 或接近)
|
||
|
||
# 5. DNS 泄露检测
|
||
dig @8.8.8.8 google.com # 通过 VPN 解析
|
||
dig google.com # 应走 sing-box DNS(不泄露本地 ISP)
|
||
|
||
# 6. 流量统计(Clash API)
|
||
CLASH_PORT="$(cat /tmp/pangolin-poc-config.json | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['experimental']['clash_api']['external_controller'].split(':')[1])")"
|
||
CLASH_SECRET="$(cat /tmp/pangolin-poc-config.json | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['experimental']['clash_api']['secret'])")"
|
||
|
||
curl -s -H "Authorization: Bearer ${CLASH_SECRET}" "http://127.0.0.1:${CLASH_PORT}/connections"
|
||
|
||
# 7. 停止(还原路由/DNS)
|
||
kill "${KERNEL_PID}"
|
||
sleep 2
|
||
|
||
# 8. 验证还原
|
||
netstat -rn | grep utun # 不应出现 pangolin TUN 条目
|
||
scutil --dns | head -20 # DNS 应回到系统默认
|
||
```
|
||
|
||
### Dart 集成测试
|
||
|
||
```bash
|
||
cd client
|
||
flutter test test/bridge/kernel_process_test.dart -v
|
||
```
|
||
|
||
## 架构说明
|
||
|
||
```
|
||
DesktopVpnBridge.start(configJson)
|
||
│
|
||
├─ _injectClashApi() 注入随机端口+secret 到 experimental.clash_api
|
||
├─ _writeConfig() 写 ~/Library/Application Support/com.pangolin.vpn/kernel/
|
||
│
|
||
└─ DesktopKernelProcess.spawn(configPath)
|
||
│
|
||
├─ _resolveBinaryPath() PANGOLIN_SINGBOX_BIN / 开发目录 / /usr/local/bin
|
||
├─ Process.start(['sudo', binPath, 'run', '-c', configPath])
|
||
├─ _waitForClashApi() 轮询 GET /connections 直到就绪(20s 超时)
|
||
├─ _startStatsPoll() 每秒轮询 /connections → VpnStatsEvent
|
||
└─ emit VpnStatus.on
|
||
```
|
||
|
||
## 已知限制(PoC 阶段)
|
||
|
||
| 限制 | 原因 | 正式版方案 |
|
||
|------|------|------------|
|
||
| sudo 提权 | TUN 需 root | SMJobBless Helper + 公证 (BACKLOG-11D-HELPER) |
|
||
| 单 REALITY outbound | 节点选优未实现 | URLTest 多节点 (11G) |
|
||
| 统计用 /connections 轮询 | SSE 流实现更复杂 | /traffic SSE 订阅 |
|
||
| Windows Wintun 未测 | 主验收平台 macOS | M1 验收后补 |
|
||
| 无 kill-switch | strict_route 做基础保护 | 11G |
|
||
| Android/iOS | 归 11E/11F | NEPacket/VpnService |
|