Gogs 1 hete
szülő
commit
4883711dc5
5 módosított fájl, 131 hozzáadás és 19 törlés
  1. 12 0
      README.md
  2. 5 7
      config.json
  3. 4 11
      scripts/benchmark_local.py
  4. 1 1
      scripts/install.sh
  5. 109 0
      scripts/start_only_udp.sh

+ 12 - 0
README.md

@@ -324,3 +324,15 @@ sudo /home/mynetspeeder/scripts/start-transparent.sh --enable-udp --capture-uid
 - `socks_port` 大于 `0`:`start-transparent.sh` 会自动一并启动
 - 适合让 `sing-box` 把指定 UDP/QUIC 流量显式交给 `mynetspeeder`
 - 不需要额外手动执行单独脚本
+
+如果你只想启用 UDP 的 SOCKS 加速,不接管任何 TCP 透明流量,可以直接启动专用脚本:
+
+```bash
+sudo /home/mynetspeeder/scripts/start_only_udp.sh /home/mynetspeeder/config.json
+```
+
+说明:
+
+- 不会创建任何 `iptables` / `ip6tables` 透明劫持规则
+- TCP 保持直连
+- UDP 需要由你的客户端显式走本机 SOCKS5,再通过 `UDP ASSOCIATE` 使用项目加速

+ 5 - 7
config.json

@@ -1,9 +1,9 @@
 {
   "strategy": "top3",
-  "redundancy": 3,
-  "direct_redundancy": 3,
-  "direct_max_redundancy": 3,
-  "direct_redundancy_v4": 3,
+  "redundancy": 1,
+  "direct_redundancy": 1,
+  "direct_max_redundancy": 2,
+  "direct_redundancy_v4": 2,
   "direct_redundancy_v6": 2,
   "direct_ipv6_enabled": true,
   "direct_open_timeout": 6.0,
@@ -18,13 +18,11 @@
   "probe_interval": 3,
   "relay_reconnect_delay": 1,
   "relay_reconnect_max_delay": 10,
-  "udp_always_broadcast": false,
+  "udp_always_broadcast": true,
   "udp_copy_interval_ms": 0,
   "udp_failover_idle_ms": 1200,
   "socks_host": "127.0.0.1",
   "socks_port": 19180,
   "relays": [
-    {"name": "hk1", "host": "23.95.134.159", "port": 9009, "token": "130", "weight": 100},
-    {"name": "hk2", "host": "23.238.9.140", "port": 9009, "token": "130", "weight": 100}
   ]
 }

+ 4 - 11
scripts/benchmark_local.py

@@ -682,15 +682,6 @@ async def amain(args) -> int:
     if args.child_http:
         return await child_http_mode(args.child_http, args.child_timeout)
 
-    if args.mode in ("tcp", "all"):
-        _host, _port, _path, is_https = parse_url(args.http_url)
-        if is_https:
-            print("TCP 测试已跳过:transparent TCP 基线不支持使用 https:// 目标做有效对比")
-            print("建议改用可快速返回的 http:// 目标,例如:")
-            print("  --http-url http://connectivitycheck.gstatic.com/generate_204")
-            if args.mode == "tcp":
-                return 0
-
     config = Config.load(args.config) if args.config and Path(args.config).exists() else None
     proxy: tuple[str, int] | None = None
     if config is not None and config.socks_port > 0:
@@ -705,13 +696,15 @@ async def amain(args) -> int:
     print(f"  SOCKS: {proxy[0]}:{proxy[1]}" if proxy else "  SOCKS: 未配置或未启动")
     print(f"  Transparent 排除用户: {args.runtime_user}")
     print("  说明: TCP 比较的是“直连基线 vs transparent_edge 实际链路”,UDP 比较的是“直连 vs socks_edge 实际链路”")
+    if args.http_url.startswith("https://"):
+        print("  提示: 当前 TCP 目标是 HTTPS,更适合做“网页体验参考”;如果要看透明首包纯开销,仍建议使用 http:// 目标")
     print("")
 
     tcp_pct = None
     udp_pct = None
     script_path = Path(__file__).resolve()
 
-    if args.mode in ("tcp", "all") and args.http_url.startswith("http://"):
+    if args.mode in ("tcp", "all"):
         tcp_pct = await bench_tcp_transparent(args, script_path)
         print("")
     if args.mode in ("udp", "all"):
@@ -738,7 +731,7 @@ def build_parser() -> argparse.ArgumentParser:
     parser.add_argument("--config", default="/home/mynetspeeder/config.json", help="配置文件路径")
     parser.add_argument("--proxy-host", default="", help="SOCKS5 地址,默认读取 config.json")
     parser.add_argument("--proxy-port", type=int, default=0, help="SOCKS5 端口,默认读取 config.json")
-    parser.add_argument("--http-url", default="http://connectivitycheck.gstatic.com/generate_204", help="TCP/透明链路测试 URL,建议使用 http://")
+    parser.add_argument("--http-url", default="https://spectrum.ieee.org/", help="TCP/透明链路测试 URL,可用 https:// 做网页体验参考")
     parser.add_argument("--dns-server", default="8.8.8.8:53", help="UDP/SOCKS 链路 DNS 目标,格式 host:port")
     parser.add_argument("--mode", choices=("tcp", "udp", "all"), default="all", help="只测 TCP、只测 UDP 或都测")
     parser.add_argument("--count", type=int, default=4, help="每类测试样本数,默认 4")

+ 1 - 1
scripts/install.sh

@@ -35,7 +35,7 @@ exec "$PYTHON_BIN" -m "$PACKAGE_NAME" "\$@"
 EOF
 chmod +x "$BIN_PATH"
 
-chmod +x "$PREFIX/scripts/start-transparent.sh" "$PREFIX/scripts/stop-transparent.sh" "$PREFIX/scripts/install.sh"
+chmod +x "$PREFIX/scripts/start-transparent.sh" "$PREFIX/scripts/stop-transparent.sh" "$PREFIX/scripts/install.sh" "$PREFIX/scripts/start_only_udp.sh"
 [[ -f "$PREFIX/scripts/start-relay.sh" ]] && chmod +x "$PREFIX/scripts/start-relay.sh"
 [[ -f "$PREFIX/scripts/stop-relay.sh" ]] && chmod +x "$PREFIX/scripts/stop-relay.sh"
 

+ 109 - 0
scripts/start_only_udp.sh

@@ -0,0 +1,109 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+usage() {
+  cat <<'EOF'
+Usage: start_only_udp.sh [config_path]
+
+Options via env:
+  MYNETSPEEDER_SOCKS_HOST   SOCKS 监听地址,默认读取配置或 127.0.0.1
+  MYNETSPEEDER_SOCKS_PORT   SOCKS 监听端口,默认读取配置或 19180
+  MYNETSPEEDER_USER         运行用户,默认 mynetspeeder
+  MYNETSPEEDER_LOG_MAX_MB    单个日志最大大小,默认 50
+  MYNETSPEEDER_LOG_BACKUPS   日志轮转保留份数,默认 3
+EOF
+}
+
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+ROOT_DIR="$(dirname "$SCRIPT_DIR")"
+PACKAGE_PARENT="$(dirname "$ROOT_DIR")"
+PACKAGE_NAME="$(basename "$ROOT_DIR")"
+
+CONFIG_PATH="${1:-$ROOT_DIR/config.json}"
+RUNTIME_USER="${MYNETSPEEDER_USER:-mynetspeeder}"
+PID_FILE="/var/run/mynetspeeder-socks.pid"
+LOG_FILE="/var/log/mynetspeeder-socks.log"
+LOG_MAX_MB="${MYNETSPEEDER_LOG_MAX_MB:-50}"
+LOG_BACKUPS="${MYNETSPEEDER_LOG_BACKUPS:-3}"
+
+if [[ $EUID -ne 0 ]]; then
+  echo "need root"
+  exit 1
+fi
+
+if [[ ! -f "$CONFIG_PATH" ]]; then
+  echo "config not found: $CONFIG_PATH"
+  exit 1
+fi
+
+SOCKS_HOST_FROM_CONFIG=$(python3 - <<'PY' "$CONFIG_PATH"
+import json, sys
+cfg = json.load(open(sys.argv[1]))
+print(cfg.get("socks_host", "127.0.0.1"))
+PY
+)
+SOCKS_PORT_FROM_CONFIG=$(python3 - <<'PY' "$CONFIG_PATH"
+import json, sys
+cfg = json.load(open(sys.argv[1]))
+port = int(cfg.get("socks_port", 19180) or 19180)
+print(port if port > 0 else 19180)
+PY
+)
+SOCKS_HOST="${MYNETSPEEDER_SOCKS_HOST:-$SOCKS_HOST_FROM_CONFIG}"
+SOCKS_PORT="${MYNETSPEEDER_SOCKS_PORT:-$SOCKS_PORT_FROM_CONFIG}"
+
+if ! [[ "$SOCKS_PORT" =~ ^[0-9]+$ ]]; then
+  echo "socks port must be numeric"
+  exit 1
+fi
+
+id -u "$RUNTIME_USER" >/dev/null 2>&1 || useradd --system --no-create-home --shell /usr/sbin/nologin "$RUNTIME_USER"
+mkdir -p /var/log
+touch "$LOG_FILE"
+chown "$RUNTIME_USER":"$RUNTIME_USER" "$LOG_FILE"
+if ! [[ "$LOG_MAX_MB" =~ ^[0-9]+$ ]] || ! [[ "$LOG_BACKUPS" =~ ^[0-9]+$ ]]; then
+  echo "log limits must be numeric"
+  exit 1
+fi
+LOG_MAX_BYTES=$((LOG_MAX_MB * 1024 * 1024))
+
+wait_for_listen() {
+  local host="$1"
+  local port="$2"
+  local log_file="$3"
+  local log_pattern="$4"
+  local label="$5"
+  local timeout_sec="${6:-10}"
+  local deadline=$((SECONDS + timeout_sec))
+  local pattern
+  pattern="${host//./\\.}:${port}( |$)"
+  while (( SECONDS < deadline )); do
+    if ss -H -lntp 2>/dev/null | grep -qE "$pattern"; then
+      return 0
+    fi
+    if [[ -f "$log_file" ]] && grep -qE "$log_pattern" "$log_file" 2>/dev/null; then
+      return 0
+    fi
+    sleep 0.2
+  done
+  echo "$label failed to listen"
+  return 1
+}
+
+pkill -f 'python3 -m mynetspeeder socks' || true
+
+runuser -u "$RUNTIME_USER" -- bash -lc "export PYTHONUNBUFFERED=1; export PYTHONPATH=${PACKAGE_PARENT}; cd ${PACKAGE_PARENT} && exec nohup python3 -m ${PACKAGE_NAME} socks --listen-host ${SOCKS_HOST} --listen-port ${SOCKS_PORT} --config ${CONFIG_PATH} 2>&1 | python3 ${ROOT_DIR}/scripts/rotate-log.py ${LOG_FILE} ${LOG_MAX_BYTES} ${LOG_BACKUPS}" &
+SOCKS_PID=$!
+echo "$SOCKS_PID" > "$PID_FILE"
+
+if ! wait_for_listen "$SOCKS_HOST" "$SOCKS_PORT" "$LOG_FILE" "socks5 listening on" "socks" 15; then
+  tail -n 50 "$LOG_FILE" || true
+  exit 1
+fi
+
+echo "mynetspeeder udp+socks mode started on ${SOCKS_HOST}:${SOCKS_PORT}"
+echo "tcp: direct"
+echo "udp: use socks5 udp associate for project acceleration"
+echo "pid file: $PID_FILE"
+echo "log file: $LOG_FILE"
+echo "log max: ${LOG_MAX_MB}MB x ${LOG_BACKUPS}"