diff --git a/server_config/README.md b/server_config/README.md index 355cfd8..57f017f 100644 --- a/server_config/README.md +++ b/server_config/README.md @@ -226,9 +226,17 @@ sysctl --system 2>/dev/null | grep -n tcp_mtu_probing | tail -5 # 看谁在最 `rrpp-qdisc.service` 在开机后显式执行 `tc qdisc replace dev <默认路由网卡> root fq` 补齐; 脚本对容器(`noqueue`)会自动跳过。 -**UDP 策略(2026-09 起)**:节点**不部署 UDP 传输**(Hysteria2 / TUIC / QUIC 等一律不用)。 -客户端 UDP 需求统一走 **UoT v2**(见 §5.5):UDP 数据报封装进 TCP CONNECT 隧道, -经 nginx magic 地址转到本机 `127.0.0.1:15201` relay 解封装。 +**UDP 策略(2026-09-20 修订)**:节点**已启用 UDP 传输**(sing-box 内建 **Hysteria2** 与 **TUIC v5** 入站,见 §6.4), +用于对抗跨境链路的丢包/高 RTT;**同时保留 UoT v2** 路径(见 §5.5)——客户端 TUN 模式的 UDP +仍可封装进 TCP CONNECT 隧道,两条路并存、互不影响。 +节点侧 UDP 相关系统调优(与 6.4 配套): + +| 项 | 值 / 说明 | +|---|---| +| `net.ipv4.udp_rmem_min` / `udp_wmem_min` | `8192`(容器内可写,实测 LXC 同样生效) | +| `net.core.rmem_max` / `wmem_max` | `33554432`(KVM 可写;**LXC 缺失/只读**) | +| `rx-udp-gro-forwarding` / `rx-gro-list`(ethtool) | 由 `rrpp-qdisc.sh` 开机开启;**实测支持情况**:us/jp ✅ 两项;aq(内核 5.10)仅 `rx-gro-list`;**LXC 容器无 netdev 权限,无法设置** | +| QUIC/UDP 吞吐 | 受宿主机 socket 缓冲上限约束——**LXC 节点上这是硬约束**,需服务商在宿主调 `rmem_max` | **明确不采用的手段**:锐速/LotServer(闭源、绑定旧内核)、net-speeder(重复包、已废弃)、 `tcp_tw_recycle`(4.12 起内核已移除,开启会破坏 NAT 后客户端)、`tcp_notsent_lowat` 激进值 @@ -515,6 +523,72 @@ EOF --- +### 6.4 Hysteria2 / TUIC(UDP 传输,2026-09-20 起全节点启用) + +TCP 系协议在跨境丢包链路上受拥塞控制限制(BBR 已缓解但仍有天花板);QUIC 系 +(**Hysteria2** 的 Brutal CC、**TUIC v5**)能显著改善高丢包下的吞吐与时延。 +两者都是 **sing-box 内建**,无需额外二进制;UDP 需求仍可走 UoT(§5.5),两条路并存。 + +```json +// Hysteria2(sing-box inbound) +{ "type": "hysteria2", "tag": "hy2-in-<端口>", "listen": "0.0.0.0", "listen_port": "<端口>", + "up_mbps": 100, "down_mbps": 100, + "obfs": { "type": "salamander", "password": "" }, + "users": [ { "name": "<节点>-hy2", "password": "" } ], + "tls": { "enabled": true, "server_name": "<节点域名>", + "certificate_path": "/etc/nginx/ssl/<节点域名>/fullchain.pem", + "key_path": "/etc/nginx/ssl/<节点域名>/privkey.pem", "alpn": ["h3"] }, + "masquerade": "file:///var/www/html" } + +// TUIC v5 +{ "type": "tuic", "tag": "tuic-in-<端口>", "listen": "0.0.0.0", "listen_port": "<端口>", + "users": [ { "name": "<节点>-tuic", "uuid": "", "password": "<密码>" } ], + "congestion_control": "bbr", + "tls": { /* 同上 */ } } +``` + +**要点** + +- **带宽声明决定 Brutal**:`up_mbps`/`down_mbps` 不写时,服务端会命令客户端改用 BBR; + 写了才允许 Hysteria CC(Brutal)。默认 100 Mbps,计量流量的节点给 50。 + Brutal **不遵守拥塞控制**,设错会占满链路甚至被服务商判定异常流量——务必按实际带宽设。 +- `obfs: salamander` 给 QUIC 加一层混淆(对抗 QUIC 特征识别);`masquerade` 指向伪装页, + 未认证访问返回与 nginx 一致的页面。 +- TUIC 保持 `zero_rtt_handshake` 关闭(默认,0-RTT 可被重放)。 +- 凭据**每节点独立**,与 VLESS/SS/CONNECT 同策略。 + +**各节点端口与部署差异(2026-09-20 实测,务必照抄结论)** + +| 节点 | 虚拟化 | Hysteria2 (UDP) | TUIC (UDP) | 差异 / 坑 | +|---|---|---|---|---| +| hk2 | LXC(NAT) | 4305 | 4306 | NAT 段 4301-4320 UDP 1:1(探针 + 外部回扫实测) | +| us | KVM | 1208 | 1209 | 公网直连,UDP 任意端口可用 | +| ru | LXC(NAT) | 23333 | 23334 | **外部只有宿主已映射的 UDP 端口可达**:容器内 bind 任意端口都"正常",但 23336+ 实测直接 `connection refused`(ICMP port unreachable);最终复用 **23333/23334**——与 nginx/vless 占用的 **TCP 同号**,UDP 与 TCP 互不冲突 | +| aq | KVM(IPv6-only) | 8444 | 8445 | 节点为 IPv6 出口,`listen` 用 `"::"`;客户端须走 IPv6 | +| jp | Azure VM | 未部署 | 8445 | **Azure NSG 只放行 UDP 8445**(443/80/8080/8088/18080/8443/9444 的 UDP 面实测均不可达)→ 单节点只能承载一个 UDP 协议;要加 Hysteria2 须先在 NSG 放行第二个 UDP 端口 | + +**客户端链接格式** + +``` +hysteria2://@<域名>:<端口>/?sni=<域名>&alpn=h3&obfs=salamander&obfs-password=#备注 +tuic://:@<域名>:<端口>/?congestion_control=bbr&alpn=h3&sni=<域名>#备注 +``` + +**验证方法(端到端,不能只看监听)** + +```bash +# 在任意机器用 sing-box 作客户端:socks 入站 + 上述 outbound,然后 +curl -s -m 20 -x socks5h://127.0.0.1:11080 -o /dev/null -w '%{http_code}\n' http://example.com/ # 期望 200 +``` + +`ss -lunp` 看到端口在听**不足以**证明外部可达:ru(NAT 未映射)与 jp(NSG 未放行) +都是"监听正常但外部不可达"的真实案例。 + +⚠️ 代价与限制:UDP 在部分运营商会被 QoS/封禁;Brutal 对同链路其他流量不友好; +计量流量的节点(如 jp,15GB/月)注意消耗;LXC 容器内 socket 缓冲上限受宿主机约束。 + +--- + ## 7. mtg(MTProto 代理) Telegram 内置代理,Fake TLS 模式抗封锁。用 [mtg](https://github.com/9seconds/mtg)(Go 单二进制): @@ -626,6 +700,11 @@ print('resp:',s.recv(8).hex())" # 期望首字节 15 (TLS alert) # UoT relay(127.0.0.1:15201 监听 + CONNECT magic 地址) ss -tlnp | grep 15201 # => uot_relay.py 监听 127.0.0.1:15201 +# UDP 传输(Hysteria2/TUIC,见 6.4)——必须端到端验证,不能只看监听 +ss -lunp | grep -E ':|:' # 仅确认服务在听 +# 再用 sing-box 客户端 + curl 经由 socks 实测(见 6.4「验证方法」) +ethtool -k <网卡> | grep -E 'rx-udp-gro-forwarding|rx-gro-list' # KVM 期望 on;LXC 容器不可设 + # nginx CONNECT(带 Basic Auth,B64 = base64('<代理用户名>:<代理密码>')) B64=$(printf '<代理用户名>:<代理密码>' | base64 -w0) curl -sk --proxy-insecure -x https://<节点域名>: \ diff --git a/server_config/scripts/rrpp-qdisc.sh b/server_config/scripts/rrpp-qdisc.sh index b91e6ac..c851316 100644 --- a/server_config/scripts/rrpp-qdisc.sh +++ b/server_config/scripts/rrpp-qdisc.sh @@ -1,13 +1,18 @@ #!/bin/bash -# 把默认路由网卡的根 qdisc 设为 fq(BBR 的最佳搭档)。 -# 背景:net.core.default_qdisc=fq 只对"新创建"的网卡生效,已存在的网卡 -# 重启后仍可能是 pfifo_fast/fq_codel,故用本脚本显式设置。 -# 仅在 KVM/裸机可用;LXC 容器内网卡为 noqueue,本脚本会自行跳过。 +# ============================================================ +# RRPP 网络接口调优脚本(开机执行) +# 1) 把默认路由网卡的根 qdisc 设为 fq —— BBR 的最佳搭档 +# (net.core.default_qdisc=fq 只对"新创建"网卡生效,已存在网卡需显式 replace) +# 2) 开启 UDP GRO 转发 —— QUIC 系协议(Hysteria2 / TUIC)转发性能 +# 容器(LXC/OpenVZ)内网卡为 noqueue、且无 netdev 权限,本脚本自动跳过。 +# ============================================================ set -uo pipefail IFACE=$(ip -4 route show default | awk '{print $5; exit}') [ -n "${IFACE:-}" ] || { echo "未找到默认路由网卡,跳过"; exit 0; } if tc qdisc show dev "$IFACE" 2>/dev/null | grep -q " noqueue"; then - echo "$IFACE 为 noqueue(容器环境),跳过 qdisc 设置" + echo "$IFACE 为 noqueue(容器环境),跳过 qdisc 与网卡 offload 设置" exit 0 fi -tc qdisc replace dev "$IFACE" root fq 2>/dev/null && echo "已设置 $IFACE root qdisc = fq" || echo "设置 $IFACE qdisc 失败(可忽略)" +tc qdisc replace dev "$IFACE" root fq 2>/dev/null && echo "已设置 $IFACE root qdisc = fq" || echo "设置 qdisc 失败(可忽略)" +ethtool -K "$IFACE" rx-udp-gro-forwarding on 2>/dev/null && echo "已开启 $IFACE rx-udp-gro-forwarding" || echo "$IFACE 不支持 rx-udp-gro-forwarding" +ethtool -K "$IFACE" rx-gro-list on 2>/dev/null && echo "已开启 $IFACE rx-gro-list" || echo "$IFACE 不支持 rx-gro-list" diff --git a/server_config/sysctl/99-zz-rrpp-network.kvm.conf b/server_config/sysctl/99-zz-rrpp-network.kvm.conf index 95f2916..a0250b4 100644 --- a/server_config/sysctl/99-zz-rrpp-network.kvm.conf +++ b/server_config/sysctl/99-zz-rrpp-network.kvm.conf @@ -1,31 +1,22 @@ # ============================================================ -# RRPP 节点系统级网络优化(KVM / 完整虚拟机版,含 Azure 等) +# RRPP 节点系统级网络优化(KVM / 完整虚拟机版) # 部署位置:/etc/sysctl.d/99-zz-rrpp-network.conf -# 配套:systemd/rrpp-qdisc.service + scripts/rrpp-qdisc.sh(见 README §2.6) -# ------------------------------------------------------------ -# 文件名以 99-zz- 开头:sysctl 按文件名字典序加载、后者覆盖前者, -# 该命名保证本文件最后生效(避免被其它 99-*.conf 覆盖)。 -# -# ⚠ 仍有一个坑:`sysctl --system` 会在所有 sysctl.d 之后**再次加载 -# /etc/sysctl.conf**(实测某节点 2022 年的 /etc/sysctl.conf 把 -# tcp_mtu_probing 覆盖回 0)。若目标机器上该文件含网络键, -# 必须同步注释掉冲突行,否则本文件不生效。 -# -# 容器(LXC/OpenVZ)请改用 99-zz-rrpp-network.lxc.conf +# 配套:systemd/rrpp-qdisc.service + scripts/rrpp-qdisc.sh(fq 队列 + UDP GRO) +# 文件名 99-zz- 前缀保证最后生效;注意 /etc/sysctl.conf 会更晚加载(见 README §2.6) # ============================================================ -# --- 拥塞控制与队列(BBR 需配 fq,否则易 bufferbloat)--- +# --- 拥塞控制与队列 --- net.ipv4.tcp_congestion_control = bbr net.core.default_qdisc = fq -# --- PMTUD 黑洞缓解(跨境链路 TLS 握手稳定超时的常见元凶)--- +# --- PMTUD 黑洞缓解 --- net.ipv4.tcp_mtu_probing = 1 # --- 握手 / 时延 --- net.ipv4.tcp_fastopen = 3 net.ipv4.tcp_slow_start_after_idle = 0 -# --- 连接生命周期(代理长连接 + 大量短连接)--- +# --- 连接生命周期 --- net.ipv4.tcp_tw_reuse = 2 net.ipv4.tcp_fin_timeout = 15 net.ipv4.tcp_keepalive_time = 300 @@ -33,7 +24,7 @@ net.ipv4.tcp_keepalive_intvl = 30 net.ipv4.tcp_keepalive_probes = 5 net.ipv4.ip_local_port_range = 10240 65000 -# --- 队列深度与缓冲(高并发 / 大 BDP)--- +# --- 队列深度与缓冲(TCP)--- net.core.somaxconn = 32768 net.ipv4.tcp_max_syn_backlog = 32768 net.core.netdev_max_backlog = 32768 @@ -41,3 +32,7 @@ net.core.rmem_max = 33554432 net.core.wmem_max = 33554432 net.ipv4.tcp_rmem = 4096 131072 33554432 net.ipv4.tcp_wmem = 4096 16384 33554432 + +# --- UDP(Hysteria2 / TUIC / UoT 的 socket 缓冲下限)--- +net.ipv4.udp_rmem_min = 8192 +net.ipv4.udp_wmem_min = 8192 diff --git a/server_config/sysctl/99-zz-rrpp-network.lxc.conf b/server_config/sysctl/99-zz-rrpp-network.lxc.conf index d088128..0932a3f 100644 --- a/server_config/sysctl/99-zz-rrpp-network.lxc.conf +++ b/server_config/sysctl/99-zz-rrpp-network.lxc.conf @@ -1,37 +1,22 @@ # ============================================================ # RRPP 节点系统级网络优化(LXC / OpenVZ 容器版) # 部署位置:/etc/sysctl.d/99-zz-rrpp-network.conf -# ------------------------------------------------------------ -# 文件名以 99-zz- 开头:sysctl 按文件名字典序加载、后者覆盖前者, -# 该命名保证本文件最后生效(避免被其它 99-*.conf 覆盖)。 -# -# 容器差异(实测 2026-09): -# net.core.rmem_max / wmem_max → 不存在或只读(宿主机控制) -# net.core.default_qdisc → 不存在(sysctl 报 cannot stat) -# net.core.netdev_max_backlog → 缺失 -# eth0 根 qdisc → noqueue,无法设置 fq -# /usr/lib/sysctl.d 的 kernel.pid_max、fs.protected_* → permission denied(正常) -# 故本文件只写容器内可写且有效的 netns 级项。 +# 容器差异:net.core.rmem_max / wmem_max / default_qdisc / netdev_max_backlog +# 缺失或只读;eth0 为 noqueue,qdisc/网卡 offload 不可设(由宿主机控制)。 +# net.ipv4.udp_rmem_min / udp_wmem_min 在部分容器内只读,若报错可忽略。 # ============================================================ -# --- 拥塞控制(qdisc 由宿主机控制,容器内无法设 fq)--- net.ipv4.tcp_congestion_control = bbr - -# --- PMTUD 黑洞缓解(跨境链路 TLS 握手稳定超时的常见元凶)--- net.ipv4.tcp_mtu_probing = 1 - -# --- 握手 / 时延 --- net.ipv4.tcp_fastopen = 3 net.ipv4.tcp_slow_start_after_idle = 0 - -# --- 连接生命周期(代理长连接 + 大量短连接)--- net.ipv4.tcp_tw_reuse = 2 net.ipv4.tcp_fin_timeout = 15 net.ipv4.tcp_keepalive_time = 300 net.ipv4.tcp_keepalive_intvl = 30 net.ipv4.tcp_keepalive_probes = 5 net.ipv4.ip_local_port_range = 10240 65000 - -# --- 队列深度(netns 级,容器内可写)--- net.core.somaxconn = 32768 net.ipv4.tcp_max_syn_backlog = 32768 +net.ipv4.udp_rmem_min = 8192 +net.ipv4.udp_wmem_min = 8192