多机联合增强转发流量

Gogs 32d065139f 继续2 преди 2 седмици
scripts 00dacea0e1 tcp和udp分开 преди 2 седмици
.gitignore fa156cc5c0 继续修改hk1掉线和UDP优化 преди 2 седмици
README.md 1829c35aab 修改UDP子节点错误问题 преди 2 седмици
__init__.py c958afbf24 基础功能,主机和子节点可用 преди 3 седмици
__main__.py c958afbf24 基础功能,主机和子节点可用 преди 3 седмици
cli.py 00dacea0e1 tcp和udp分开 преди 2 седмици
config.json 1829c35aab 修改UDP子节点错误问题 преди 2 седмици
config.jsonbak a004bd9cdf 解决启动退出ssh问题 преди 3 седмици
config.py 1829c35aab 修改UDP子节点错误问题 преди 2 седмици
demo-config copy.json 66db438889 更新 преди 3 седмици
protocol.py c958afbf24 基础功能,主机和子节点可用 преди 3 седмици
relay_client.py 1829c35aab 修改UDP子节点错误问题 преди 2 седмици
relay_server.py 32d065139f 继续2 преди 2 седмици
scheduler.py f1e95aae71 更新日志问题 преди 2 седмици
socks_edge.py 32d065139f 继续2 преди 2 седмици
transparent_edge.py 1829c35aab 修改UDP子节点错误问题 преди 2 седмици

README.md

mynetspeeder

mynetspeeder 用于给当前主机上的 direct 出站做透明加速,并支持可选的 UDP 并行竞速。

当前结论

  • 现在项目的推荐组合是:TCP 走透明接管UDP 走显式 SOCKS5 UDP ASSOCIATE
  • 只要 config.jsonsocks_port > 0start-transparent.sh 就会启动 socks 入口
  • 此时即使传了 --enable-udp,脚本也会关闭 UDP 透明接管,改为仅保留 TCP 透明接管
  • 所以上一次配置里如果同时出现 socks_port > 0 和“UDP 透明”描述,那是文档/配置语义混杂,不是当前实际生效路径

对应脚本行为可直接概括为:

  • TCP:继续通过 iptables/ip6tables nat OUTPUT -> REDIRECT -> edge
  • UDP:若 socks_port > 0,优先走 socks 显式入口;不再做透明 UDP 重定向
  • UDP:只有在 socks_port == 0 且显式加 --enable-udp 时,才走透明 UDP

现在有哪些模式

  • relay:子节点 VPS 中继
  • edge:主 VPS 透明接管 direct 出站
  • socks:显式 UDP 入口,给需要手动交付 UDP/QUIC 的应用使用
  • probe:查看子节点探测与在线状态
  • summary:汇总日志里的 TCP / UDP 胜率

典型场景

  • 你本机继续通过 sing-boxhy2 19887/19888 入站使用外网
  • sing-boxdirect 出站不需要改动
  • mynetspeeder 在系统层接管这些 direct 流量
  • 主 VPS 直连、子节点 relay、以及可选的 UDP 并行路径都会参与竞速

架构流程图

推荐组合:TCP 透明 + UDP SOCKS

flowchart LR
    A[应用 / sing-box] -->|TCP 出站| B[系统 nat OUTPUT REDIRECT]
    B --> C[Transparent Edge :19080]
    C --> D1[Direct TCP 副本 1..N]
    C --> D2[Relay TCP 路径 1..N]
    D1 --> E[TCP winner]
    D2 --> E
    E --> F[目标站点]

    A -->|UDP / QUIC| G[SOCKS5 UDP ASSOCIATE :19180]
    G --> H1[Direct UDP 副本 1..N]
    G --> H2[Relay UDP 路径 1..N]
    H1 --> I[UDP winner]
    H2 --> I
    I --> F

备用组合:TCP 透明 + UDP 透明

flowchart LR
    A[应用 / sing-box] -->|TCP 出站| B[系统 nat OUTPUT REDIRECT]
    A -->|UDP 出站| B
    B --> C[Transparent Edge :19080]
    C --> D1[Direct TCP 副本 1..N]
    C --> D2[Relay TCP 路径 1..N]
    C --> D3[Direct UDP 副本 1..N]
    C --> D4[Relay UDP 路径 1..N]
    D1 --> E1[TCP winner]
    D2 --> E1
    D3 --> E2[UDP winner]
    D4 --> E2
    E1 --> F[目标站点]
    E2 --> F

配置文件

示例 /home/mynetspeeder/config.json

{
  "strategy": "top3",
  "redundancy": 3,
  "direct_redundancy": 2,
  "direct_max_redundancy": 3,
  "direct_redundancy_v6": 3,
  "tcp_warmup_initial_bytes": 131072,
  "tcp_warmup_bytes": 1048576,
  "tcp_loser_grace_ms": 1500,
  "probe_interval": 15,
  "udp_redundancy": 1,
  "udp_direct_redundancy": 2,
  "udp_always_broadcast": true,
  "udp_copy_interval_ms": 8,
  "socks_host": "127.0.0.1",
  "socks_port": 19180,
  "relays": [
    {"name": "hk1", "host": "1.2.3.4", "port": 9009, "token": "demo", "weight": 100},
    {"name": "jp1", "host": "5.6.7.8", "port": 9009, "token": "demo", "weight": 95}
  ]
}

warmup 说明

  • tcp_warmup_initial_bytes:启动时的较小起步值
  • tcp_warmup_bytes:稳定后允许抬升到的上限值
  • 系统会根据目标、地址族和历史胜率,把 warmup 从起步值逐步抬高到上限
  • 起步阶段更偏向快速首开,稳定后更偏向吞吐和抗抖动

透明 TCP

透明 TCP 会对每条连接同时拉起:

  • 当前主机直连路径
  • 若干在线 relay 路径
  • 多个 direct 冗余副本(由 direct_redundancy / direct_max_redundancy 控制)

行为规则:

  • tcp_warmup_initial_bytestcp_warmup_bytes 之间,上行数据会更积极地发给所有候选路径
  • 谁先回下行数据,谁成为 winner
  • loser 会再保留 tcp_loser_grace_ms 毫秒后关闭
  • 某目标或某地址族如果长期更偏向 relay,主节点会自动把 direct 冗余再提一档

透明 UDP

透明 UDP 采用并行竞速架构,需要通过 --enable-udp 显式开启。

但要注意一个优先级规则:

  • config.jsonsocks_port > 0start-transparent.sh 会输出 udp transparent capture disabled: socks5 is enabled, UDP will use socks only
  • 也就是说,--enable-udp 在这种情况下不会真正打开 UDP 透明接管
  • 因此“开启了 socks 的配置”与“UDP 透明接管”在同一次启动里默认不是并行共存关系,而是前者覆盖后者

当前实现方式:

  • 系统 UDP 包先进入 edge 的 UDP listener
  • 每个 (source, target) 流会同时建立本机 direct UDP 路径和在线 relay UDP 路径
  • udp_redundancy 控制同一包的额外重复次数
  • udp_direct_redundancy / _v4 / _v6 控制 direct UDP 并发副本数
  • udp_always_broadcast=true 时,即使已有 winner,后续包仍持续并发发送
  • 首个有效下行回复会成为 winner,后续重复包按 winner 规则收敛

适合场景:

  • 视频 / 直播 / 游戏里需要 QUIC/UDP 的流量
  • 希望和 TCP 一样走多路径并行竞速的场景

显式 SOCKS5 UDP 入口

socks 命令用于显式交付 UDP/QUIC,不是普通 TCP CONNECT 代理。

当前行为:

  • 支持 UDP ASSOCIATE
  • TCP CONNECT 目前是禁用的
  • 适合让支持手动代理配置的应用,把 UDP 流量显式交给 mynetspeeder

如果 config.json 里设置了 socks_port > 0start-transparent.sh 会自动把它一起拉起来;此时若同时开启 --enable-udp,脚本会优先让 UDP 走 SOCKS 显式入口,并关闭 UDP 透明重定向。

哪种组合效能最好

结论先说:

  • 默认最优组合TCP 透明接管 + UDP SOCKS 显式入口
  • 仅在应用根本无法配置 SOCKS UDP 时,才退回 TCP 透明接管 + UDP 透明接管

原因如下:

  • TCP 天然适合透明接管:系统层无感接入,不需要改应用配置,且本项目的 TCP warmup、direct 冗余、relay 竞速都已经围绕透明模式做了完整优化
  • UDP/QUIC 更适合显式 SOCKS:应用主动把目标地址和 UDP 数据交给 socks,路径更直接,状态更清晰,避免透明重定向场景里对 SO_ORIGINAL_DST、conntrack、自环规避、NAT 回包等额外依赖
  • UDP 对时延抖动和状态保持更敏感,显式入口通常比透明重定向更稳定,尤其在 QUIC、游戏、实时音视频这类长流场景
  • 当前项目里 socks UDP 并不是“单路径代理”,它内部同样会做 direct UDP + relay UDP 并行竞速,所以不会损失 UDP 加速能力
  • 透明 UDP 的主要优势是“应用零改动”,不是“性能一定更高”;在可控环境下,它更多是兼容方案而不是首选方案

建议按场景选择:

  • 你的应用或 sing-box 能明确把 UDP/QUIC 指到 127.0.0.1:19180:优先选 TCP 透明 + UDP SOCKS
  • 应用完全不能单独配置 UDP 代理:选 TCP 透明 + UDP 透明
  • 如果 UDP 目标以短包、低时延、长时间会话为主:更建议 UDP SOCKS
  • 如果只是想“全局无感接管所有协议”:才考虑透明 UDP,但要接受稳定性和可维护性略差一些

启动方式

1. 子节点 VPS

python3 -m mynetspeeder relay --listen-port 9009 --token demo

2. 当前主 VPS

准备配置:

cp /home/mynetspeeder/demo-config.json /home/mynetspeeder/config.json

启动透明接管:

sudo /home/mynetspeeder/scripts/start-transparent.sh --kernel auto --capture-uid <sing-box运行UID> /home/mynetspeeder/config.json

如果要同时开启透明 UDP:

sudo /home/mynetspeeder/scripts/start-transparent.sh --enable-udp --capture-uid <sing-box运行UID> /home/mynetspeeder/config.json

注意:如果 socks_port 已开启,脚本会把 UDP 优先交给 SOCKS 显式入口,而不是再做透明 UDP 重定向;此时实际生效的是 TCP 透明 + UDP SOCKS

不指定 --capture-uid 时,会接管所有用户发起的流量:

sudo /home/mynetspeeder/scripts/start-transparent.sh /home/mynetspeeder/config.json

停止透明接管:

sudo /home/mynetspeeder/scripts/stop-transparent.sh

查看节点状态:

python3 -m mynetspeeder probe --config /home/mynetspeeder/config.json --once

汇总日志胜率:

python3 -m mynetspeeder summary --log-file /var/log/mynetspeeder-edge.log

安装子节点

把项目目录复制到子节点后:

sudo /home/mynetspeeder/scripts/install.sh /opt/mynetspeeder

安装完成后可直接用:

mynetspeeder --help

启动 relay:

sudo /opt/mynetspeeder/scripts/start-relay.sh 你的token

停止 relay:

sudo /opt/mynetspeeder/scripts/stop-relay.sh

内核模式

--kernel auto|20|24 会影响透明模式下的建连策略:

  • auto:自动判断
  • 20:更保守
  • 24:更积极,通常会更短的 direct / relay 建连超时,并启用更激进的 happy eyeballs 参数

手动指定示例:

sudo /home/mynetspeeder/scripts/start-transparent.sh --kernel 24 --capture-uid $(id -u singbox) /home/mynetspeeder/config.json

一键脚本做了什么

start-transparent.sh 会自动:

  • 创建运行用户 mynetspeeder
  • 以该用户启动 edge
  • 只接管指定 UID 的 TCP 出站,避免影响整机连接
  • 自动排除:
    • 127.0.0.0/8
    • 169.254.0.0/16
    • 所有 relay IP
    • mynetspeeder 自己发起的连接
  • --enable-udp 时额外启用 UDP 透明接管,并放行 ESTABLISHED,RELATED 回包

当前限制

  • 透明 TCP / UDP 都是基于系统层重定向实现,规则范围较大
  • UDP 自环通过 listener 侧过滤和脚本规则一起规避,但仍建议先从小流量场景验证
  • socks 模式目前只做 UDP 显式入口,不提供 TCP CONNECT

配置建议

推荐使用下面这类思路:

  • 保留 socks_port: 19180
  • 平时只把 TCP 交给 start-transparent.sh
  • 需要 UDP/QUIC 加速的应用,显式配置到本机 SOCKS5 UDP 入口
  • 不要把“已开启 socks_port”的配置再理解成“UDP 透明也同时生效”

如果你要强制使用透明 UDP:

  • socks_port 设为 0
  • 再使用 --enable-udp 启动
  • 这时实际才是 TCP 透明 + UDP 透明

运行状态

当前版本已支持:

  • singbox 用户的透明 TCP 接管
  • IPv4 / IPv6 透明监听
  • 可选透明 UDP 并行竞速
  • 可选显式 SOCKS5 UDP 入口
  • 无 relay 时自动只走本机 direct