Sing-box Hysteria2 协议端口跳跃配置与排错全记录

目錄

1. 核心概念

为什么要开启端口跳跃?

  • 对抗 QoS:运营商常针对单一 UDP 高频端口(如 443)进行限速或断流。
  • 原理:客户端在指定端口范围(如 50000-65535)内自动切换连接,服务端通过 iptables 将这些流量统一转发到真实的监听端口。
  • 适用场景:国内网络环境较差、经常断流的用户。

2. 服务端配置 (VPS)

2.1 开启系统内核转发

为了让 iptables 能够转发流量,必须开启 IP Forwarding。

检查是否开启:

cat /proc/sys/net/ipv4/ip_forward
# 输出 1 代表已开启,0 代表未开启

开启方法 (Debian/Ubuntu):

echo "net.ipv4.ip_forward=1" | sudo tee /etc/sysctl.d/99-forwarding.conf
sudo sysctl --system

2.2 配置 iptables 端口转发 (NAT)

目标:将 5000065535 端口的 UDP 流量,重定向到 Sing-box 实际监听的端口 59743

正确的命令 (REDIRECT 模式):

iptables -t nat -A PREROUTING -p udp --dport 50000:65535 -j REDIRECT --to-port 59743

(注意:REDIRECT 适用于本机转发,无需指定公网 IP)

持久化规则 (推荐 UFW 用户):

编辑 /etc/ufw/before.rules,在 *filter 之前添加:

*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -p udp --dport 50000:65535 -j REDIRECT --to-port 59743
COMMIT

2.3 Sing-box 服务端配置 (config.json)

服务端不需要配置端口跳跃范围,只需监听目标端口。

{
  "inbounds": [
    {
      "type": "hysteria2",
      "tag": "hy2-in",
      "listen": "::",
      "listen_port": 59743, // 必须与 iptables 转发的目标端口一致
      "users": [
        {
          "name": "myuser",
          "password": "mypassword"
        }
      ],
      "tls": {
        "enabled": true,
        "alpn": ["h3"],
        "certificate_path": "/path/to/cert.crt",
        "key_path": "/path/to/private.key"
      }
    }
  ]
}

3. 客户端配置 (Sing-box Outbound)

客户端需要显式指定跳跃范围。

{
  "type": "hysteria2",
  "tag": "proxy",
  "server": "1.2.3.4",     // 你的 VPS IP
  "server_port": 59743,    // 填写真实监听端口(有些客户端要求填这个)
  "server_ports": "50000-65535", // 核心配置:指定跳跃范围
  "hop_interval": "30s",   // 跳跃间隔,建议 30s
  "password": "mypassword",
  "tls": {
    "enabled": true,
    "server_name": "yourdomain.com"
  }
}

4. 排错过程记录 (Troubleshooting)

问题描述

配置后无法连接,或 iptables 规则混乱,导致流量并未到达 Sing-box 容器。

4.1 检查 iptables 状态

执行命令查看 NAT 表:

iptables -t nat -L PREROUTING -n --line-numbers

发现的错误状态:

num  target    prot opt source       destination
1    1PANEL... all  --  0.0.0.0/0    0.0.0.0/0
2    REDIRECT  udp  --  0.0.0.0/0    0.0.0.0/0    udp dpts:50000:65535 redir ports 59767  <-- 错误端口
3    DOCKER    all  --  0.0.0.0/0    0.0.0.0/0
4    REDIRECT  udp  --  0.0.0.0/0    0.0.0.0/0    udp dpts:50000:65535 redir ports 59743  <-- 正确但被拦截

原因分析:

  1. 规则顺序错误:iptables 从上往下执行,流量先匹配到了第 2 条(转发到错误的 59767)。
  2. 端口不一致:配置和规则中混用了 5976759743
  3. 规则冗余:存在多条重复或冲突的规则。

4.2 修正步骤

  1. 删除指向错误端口 (59767) 的规则:

    iptables -t nat -D PREROUTING -p udp --dport 50000:65535 -j REDIRECT --to-port 59767

    (需执行多次,直到无该规则)

  2. 删除冗余的正确规则(保留一条在 Docker 链之前的):

    假设 59743 的规则出现在了 DOCKER 链之后(如第 4 行),需要删除它,确保只保留位于顶部的有效规则。

    iptables -t nat -D PREROUTING 4

4.3 最终验证

再次检查:

iptables -t nat -L PREROUTING -n --line-numbers

完美状态:

num  target    prot opt source       destination
1    1PANEL... all  --  ...
2    REDIRECT  udp  --  ... udp dpts:50000:65535 redir ports 59743
3    DOCKER    all  --  ...
  • 解释:流量进入 -> 命中第 2 条(重定向到 59743) -> 命中第 3 条(DOCKER 链负责将 59743 传入容器)。

5. 避坑指南

  1. 端口一致性iptables--to-port 必须严格等于 Sing-box config.json 中的 listen_port
  2. 规则顺序REDIRECT 规则最好放在 DOCKER 链之前,否则可能因 Docker 的 NAT 逻辑导致转发失效。
  3. 规则保存:修改完 iptables 后,重启会丢失。请务必使用 netfilter-persistent save 或通过 UFW 配置文件持久化。
  4. 端口范围:推荐使用 50000-65535,避开 Linux 默认的临时端口范围(通常到 60999),但在入站转发场景下,即便重叠问题也不大。

評論