Files
Hermes 88f2ff44aa fix(detect): never bind USB gadget iface as proxy egress
设备把自己当 USB 网卡挂给上游主机时会出现 usb0(驱动 configfs-gadget.g1,
IP 192.168.68.1)。该链路只通向 PC,被当成出口后所有出站都 context
deadline exceeded,客户端看到 socks connect failed rep=0x01。

误选原因:score_iface_as_cellular 给 usb0 与真出口 wwan0 都打 175 分。
usb0 靠名称命中 patterns 里的 usb(+80)与非默认路由(+40);wwan0 的
bam-dmux 驱动不在白名单里,白丢 +100。detect_cellular_iface 用 -gt 比较,
list_ifaces 按名排序让 usb0 先入选,平分下无法被顶替。

改动:
- lib.sh 新增 iface_is_usb_gadget(),按驱动名与 gadget 总线路径识别,
  并并入 is_virtual_or_skip_iface(usb0 评分 175 -> 0)
- 驱动白名单补 bam-dmux/bam_dmux/qcom-ipa/ipa_wan;名称权重 80 -> 40,
  确保驱动证据始终压过名称猜测
- 新增 detect_cellular_iface_via_mm(),把 ModemManager bearer 的
  interface: 作为第 0 步权威来源
- detect_cellular_iface / resolve_cellular 全链路拒绝 gadget 网卡,
  取不到真出口时按 REQUIRE_CELLULAR_IFACE 直接失败而不是绑错
- generate/install/upgrade/watch/detect/verify 各入口独立设闸,
  verify.sh 发现出口是 gadget 时直接 exit 4 并给出修复命令
- 默认 CELLULAR_IFACE_PATTERNS 去掉 usb/enx;upgrade.sh 与根 install.sh
  就地迁移已有 settings.conf,旧机器升级即修复
- 新增 tests/detect-gadget.sh:18 条离线断言,无需真机
2026-08-23 18:39:34 +08:00

6.3 KiB
Raw Permalink Blame History

cellular-proxy

轻量 「走代理 = 走数据流量」(无 frp512MB 友好)。

语义

流量 出口
不走 本代理 系统默认(通常 WiFi
本代理 一律数据网卡(自动探测并 bind

★ 一条命令(安装 / 升级通用)

curl -fsSL 'https://gitea.chickliu.fun/Hermes/cellular-proxy/raw/branch/main/install.sh' | sudo bash
机器状态 行为
未安装 全量安装:探测网卡 → 下 sing-box → 启动 → 验证
已安装 增量升级:保留密钥/网卡/账密,更新 UI/scripts,默认不重下二进制

不需要记 --upgrade / --install同一条命令反复执行即可

可选覆盖(首次安装常用):

curl -fsSL 'https://gitea.chickliu.fun/Hermes/cellular-proxy/raw/branch/main/install.sh' | sudo bash -s -- \
  --iface wwan0 \
  --secret '面板密钥' \
  --user proxy \
  --pass '代理密码'
选项 说明
(无参数) 自动:未装→安装,已装→升级
--force-install 已装也强制全量安装
--force-binary 升级时强制重下 sing-box
--ui-only 只更新 9090 面板
--rebind 升级时重新探测数据网卡
--verify 升级后做出口验证(升级默认跳过)
--iface 强制指定数据网卡
--secret 面板密钥(默认随机;升级不改已有)
--user / --pass 代理鉴权
--port / --panel-port 默认 7890 / 9090
--memory MemoryMax MB,默认 96
--skip-start / --skip-verify 跳过启动或验证

已装后的快捷方式

装过一次后也可用:

sudo cpxy upgrade              # 等同再跑上面那条 curl(增量)
sudo cpxy upgrade --ui-only
sudo cpxy upgrade --force-binary
sudo cpxy upgrade --verify
保留 默认跳过 会更新
settings.conf / PANEL_SECRET / 代理账密 重下 sing-box(已存在则复用) UI 面板
CELLULAR_IFACE 绑定 重新探测网卡 scripts / cpxy / systemd
端口与 MemoryMax 出口公网验证 重生 config.json 并 restart

常用运维:

cpxy verify
cpxy rebind
cpxy status | logs
cpxy auth --user u --pass p
cpxy auth --show | --clear
cpxy watch status   # WWAN 自动监控
cpxy watch once     # 手动跑一轮检查

重拨 / rep=0x01 自愈

层级 做法
绑定(推荐) 默认 BIND_SOURCE_IP=false:只 bind_interface=wwanX不 pin 私网源 IP,重拨换地址通常不用 regenerate
监控 cellular-proxy-watchip monitor + ModemManager 重拨/重注册日志 + 60s 轮询;网卡改名/掉线/stale pin 或 MM 抖动后自动等数据面再 generate
MM 标准(省流量) 默认 WATCH_MM_EVENTS=true:只读本机 journalctl -u ModemManager不做公网探针;命中 registration/packet service 等状态变化后 settle→等 IPv4→restart
兜底 timer 每 2 分钟 oneshot 再检查一次
手动 cpxy rebind && cpxy verify

关监控:ENABLE_CELLULAR_WATCH=falsecpxy upgrade,或 cpxy watch stop
若必须 pin 源 IPBIND_SOURCE_IP=true(依赖 watch 同步,否则会再次 stale)。

  • 代理:LAN-IP:7890HTTP + SOCKS5
  • 面板:http://LAN-IP:9090/ui/(密钥在安装结束输出 / settings.conf
  • UI 可直接配置代理账号密码(管理 API 默认 9091,与面板 secret 相同)

自动探测逻辑(摘要)

顺序如下,前一步命中即返回:

  1. ModemManager bearermmcli -b 报的 interface:)—— 最权威,优先采用
  2. 驱动像蜂窝/USB 拨号:qmi_wwancdc_mbimcdc_etherrndis_hostbam-dmuxrmnet* 等(+100
  3. 名称含 wwan / wwp / ppp / rmnet / ccmni …(+40,弱启发式)
  4. 不是 系统默认路由网卡(默认通常是 WiFi)
  5. 多默认路由时取次要默认口
  6. 回退:任意非默认且有 IPv4 的物理网卡

探测失败会直接报错并提示用 --iface

绝不绑定 USB gadget 网卡

设备把自己当 USB 网卡挂给上游主机时会出现 usb0 / rndis0(驱动 configfs-gadgetg_ether 等)。那是「本机 → PC」的下行链路,一旦被当成代理出口,所有出站都会 context deadline exceededSOCKS5 客户端看到的就是 socks connect failed rep=0x01

因此:

  • iface_is_usb_gadget() 按驱动名与 gadget 总线路径识别这类接口,打分阶段直接跳过;
  • 默认探测关键词不再包含 usb / enx,升级时会自动从已有 settings.conf 里剔除;
  • 即使手工把 CELLULAR_IFACE=usb0 写进配置或用 --iface usb0detect / generate / install / upgrade / watch 都会拒绝并改用 ModemManager 的结果;
  • 真正的 USB 上行模组(rndis_hostcdc_*qmi_wwan)是 host 侧驱动,不受影响。

回归测试(不需要真机,纯离线,覆盖 18 条断言):

bash tests/detect-gadget.sh

手动安装

git clone https://gitea.chickliu.fun/Hermes/cellular-proxy.git
cd cellular-proxy
sudo ./scripts/install.sh   # 同样会自动探测并绑定

资源

  • 单进程 sing-box
  • 中文静态面板(animal-island-ui 视觉 token,单文件无 React
  • 默认 MemoryMax=96MB

二进制从哪里下?

优先 Gitea Release 预置包(一键安装默认走 Gitea,无需访问 GitHub):

https://gitea.chickliu.fun/Hermes/cellular-proxy/releases/download/bin-v1.11.7/sing-box-1.11.7-linux-amd64.tar.gz
https://gitea.chickliu.fun/Hermes/cellular-proxy/releases/download/bin-v1.11.7/sing-box-1.11.7-linux-arm64.tar.gz
https://gitea.chickliu.fun/Hermes/cellular-proxy/releases/download/bin-v1.11.7/sing-box-1.11.7-linux-armv7.tar.gz

下载顺序:Gitea 整包Gitea 分片合并(兜底)GitHub 代理(https://git.86482425.xyz)直连 GitHub

代理账号密码

方式 命令 / 入口
UI http://LAN-IP:9090/ui/ → 面板 secret → 代理账号密码
CLI sudo cpxy auth --user u --pass p
安装时 --user / --pass

管理 APIPOST http://LAN-IP:9091/proxy-authHeader Authorization: Bearer $PANEL_SECRET