server_config: 系统级网络优化规范(KVM/LXC 差异 + qdisc 持久化 + sysctl.conf 覆盖坑)

- 新增 sysctl/99-zz-rrpp-network.{kvm,lxc}.conf 两套模板(99-zz- 前缀保证最后生效)
- 新增 systemd/rrpp-qdisc.service + scripts/rrpp-qdisc.sh(default_qdisc 只对新建网卡生效,需显式 replace)
- README §2.6:如实记录实测差异
  * KVM/完整VM:rmem/wmem、netdev_max_backlog、default_qdisc、qdisc 均可写
  * LXC/OpenVZ:上述项缺失或只读、eth0 为 noqueue、/usr/lib/sysctl.d 的 pid_max/fs.protected_* 报 permission denied(正常)
  * 坑:sysctl --system 会在 sysctl.d 之后加载 /etc/sysctl.conf,实测某节点旧文件把 tcp_mtu_probing 覆盖回 0
- 记录 UDP 策略:节点不部署 UDP 传输,UDP 需求统一走 UoT v2(§5.5)
- 更新 §9 服务表、§10 验证清单、§11 目录索引
This commit is contained in:
2026-09-20 21:50:13 +08:00
parent 9a64853db4
commit 375153b810
5 changed files with 207 additions and 2 deletions
+102 -2
View File
@@ -158,6 +158,93 @@ fail2ban-client status sshd # 确认 jail 在跑
> - 只加 fail2ban、**不动 sshd 认证方式**(root 登录等现状保留)。 > - 只加 fail2ban、**不动 sshd 认证方式**(root 登录等现状保留)。
> - 如需同时护 nginx CONNECT 的 401 爆破,可再加 nginx jail(凭据够强时可不做)。 > - 如需同时护 nginx CONNECT 的 401 爆破,可再加 nginx jail(凭据够强时可不做)。
### 2.6 系统级网络优化(KVM / LXC 差异)与 qdisc 持久化
> 模板:[sysctl/99-zz-rrpp-network.kvm.conf](sysctl/99-zz-rrpp-network.kvm.conf)(完整 VM,含 Azure 等)、
> [sysctl/99-zz-rrpp-network.lxc.conf](sysctl/99-zz-rrpp-network.lxc.conf)(容器)
> 落地位置统一为 `/etc/sysctl.d/99-zz-rrpp-network.conf`;
> qdisc 伴侣:[systemd/rrpp-qdisc.service](systemd/rrpp-qdisc.service) + [scripts/rrpp-qdisc.sh](scripts/rrpp-qdisc.sh)。
```bash
# KVM / 完整 VM
install -m 644 sysctl/99-zz-rrpp-network.kvm.conf /etc/sysctl.d/99-zz-rrpp-network.conf
# LXC / OpenVZ 容器
install -m 644 sysctl/99-zz-rrpp-network.lxc.conf /etc/sysctl.d/99-zz-rrpp-network.conf
# qdisc 持久化(仅完整 VM 有意义;容器内网卡是 noqueue,脚本会自动跳过)
install -m 755 scripts/rrpp-qdisc.sh /usr/local/sbin/rrpp-qdisc.sh
install -m 644 systemd/rrpp-qdisc.service /etc/systemd/system/
systemctl daemon-reload && systemctl enable --now rrpp-qdisc
sysctl --system
```
**为什么文件名是 `99-zz-`**:sysctl 按文件名字典序加载、**后者覆盖前者**。`99-zz-` 保证本文件排在最后,
避免被其它 `99-*.conf` 覆盖。
**⚠ 最容易踩的坑:`/etc/sysctl.conf`**。`sysctl --system` 会在**所有 sysctl.d 之后**再加载 `/etc/sysctl.conf`。
2026-09 实测:某节点(aq)存在 2022 年的一键优化版 `/etc/sysctl.conf`,把 `tcp_mtu_probing` 覆盖回 `0`,
导致 sysctl.d 里的设置完全不生效(现象:`sysctl -n` 与文件内容不一致)。
**处理**:该文件里凡是与本规范重叠的键,逐行注释掉(保留其非冲突的调优,如 conntrack、rps、swappiness),
或直接把本规范内容追加到该文件末尾。排查方法:
```bash
sysctl -p /etc/sysctl.d/99-zz-rrpp-network.conf # 显式加载后应看到期望值
sysctl --system 2>/dev/null | grep -n tcp_mtu_probing | tail -5 # 看谁在最后覆盖
```
**KVM / 完整 VM 可写(本规范设置项)**
| 项 | 值 | 作用 |
|---|---|---|
| `tcp_congestion_control` / `core.default_qdisc` | `bbr` / `fq` | BBR 需 fq 搭配,否则 bufferbloat |
| `tcp_mtu_probing` | 1 | PMTUD 黑洞缓解(见 2.4) |
| `tcp_fastopen` | 3 | 客户端+服务端 TFO,省一次 RTT |
| `tcp_slow_start_after_idle` | 0 | 空闲后不回退慢启动(长连接代理有益) |
| `tcp_tw_reuse` / `tcp_fin_timeout` | 2 / 15 | TIME-WAIT 复用与回收 |
| `tcp_keepalive_time/intvl/probes` | 300 / 30 / 5 | 及时清理死连接(默认 7200 过长) |
| `ip_local_port_range` | 10240 65000 | 出站端口范围,防高并发端口耗尽 |
| `core.somaxconn` / `tcp_max_syn_backlog` | 32768 | accept / 半连接队列 |
| `core.netdev_max_backlog` | 32768 | 网卡收包队列(默认 1000 易突发丢包) |
| `core.rmem_max` / `wmem_max` | 33554432 | socket 缓冲上限(默认 208KB 偏小) |
| `tcp_rmem` / `tcp_wmem` | 4K/128K/32M、4K/16K/32M | 自动调优范围 |
**LXC / OpenVZ 容器不可用(由宿主机控制,实测 2026-09)**
| 项 | 现象 |
|---|---|
| `core.rmem_max` / `core.wmem_max` | **不存在**或 `-r--r--r--` 只读 |
| `core.default_qdisc` | **不存在**(`sysctl` 报 cannot stat) |
| `core.netdev_max_backlog` | 缺失 |
| 默认路由网卡根 qdisc | `noqueue`,**无法设置 fq** |
| `/usr/lib/sysctl.d` 的 `kernel.pid_max`、`fs.protected_*` | `permission denied`——容器内属**正常现象**,与本文档无关 |
> 结论:容器节点只能调 **netns 级**项(拥塞算法、MTU 探测、TFO、TW 复用、keepalive、
> somaxconn、syn backlog、本地端口范围);socket 缓冲上限与 qdisc 需服务商在**宿主机**设置。
> 因此容器节点想进一步提升,应优先在**应用层/传输层**做(例如走 UoT 而不是直连 UDP)。
**qdisc 为什么必须单独用 systemd 单元**:`net.core.default_qdisc=fq` **只对新建网卡生效**;
已存在的网卡即使重启也可能仍是 `pfifo_fast` / `fq_codel`(实测:aq 为 `pfifo_fast`、us 为 `fq_codel`)。
`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 解封装。
**明确不采用的手段**:锐速/LotServer(闭源、绑定旧内核)、net-speeder(重复包、已废弃)、
`tcp_tw_recycle`(4.12 起内核已移除,开启会破坏 NAT 后客户端)、`tcp_notsent_lowat` 激进值
(可能压制高 BDP 吞吐)、`busy_poll`/`busy_read`(1 vCPU 机器上代价大于收益)、各类"一键优化脚本"
(多为本文档子集 + 心理安慰,且常与 sysctl.d 冲突)。
**落地状态(2026-09-20)**
| 节点 | 虚拟化 | 落地情况 |
|---|---|---|
| hk2 | LXC(Debian 12) | LXC 模板;`bbr` + `mtu_probing=1` + `fastopen=3` + 队列/端口项;缓冲与 qdisc 受宿主限制 |
| ru | LXC(Debian 13 cloud 内核) | 同上(`rmem_max`/`wmem_max` 只读) |
| us | KVM(Debian 12) | KVM 模板 + fq(原 `fq_codel`) |
| aq | KVM(Debian 11 cloud) | KVM 模板 + fq(原 `pfifo_fast`);并注释其 `/etc/sysctl.conf` 中 17 行冲突键(原 `tcp_mtu_probing=0`) |
| jp | Azure VM(Ubuntu 6.17) | KVM 模板(经 `sudo` 落地;原有 `99-tune.conf` 保留) |
--- ---
## 3. 伪装站点页面 ## 3. 伪装站点页面
@@ -486,6 +573,7 @@ mtg simple-run --prefer-ip=prefer-ipv4 0.0.0.0:<mtproto端口> <上面生成的s
| sing-box | [systemd/sing-box.service](systemd/sing-box.service) | | sing-box | [systemd/sing-box.service](systemd/sing-box.service) |
| mtg | [systemd/mtg.service](systemd/mtg.service) | | mtg | [systemd/mtg.service](systemd/mtg.service) |
| uot-relay | [uot-relay/uot-relay.service](uot-relay/uot-relay.service) | | uot-relay | [uot-relay/uot-relay.service](uot-relay/uot-relay.service) |
| rrpp-qdisc(fq 队列,见 2.6) | [systemd/rrpp-qdisc.service](systemd/rrpp-qdisc.service) |
```bash ```bash
cp systemd/*.service /etc/systemd/system/ cp systemd/*.service /etc/systemd/system/
@@ -514,6 +602,13 @@ systemctl start uot-relay # 5. UoT relay(须在 nginx 前可用
sysctl net.ipv4.tcp_congestion_control # => bbr sysctl net.ipv4.tcp_congestion_control # => bbr
sysctl net.ipv4.tcp_mtu_probing # => 1(PMTUD 黑洞缓解,见 2.4) sysctl net.ipv4.tcp_mtu_probing # => 1(PMTUD 黑洞缓解,见 2.4)
# 系统级网络优化(见 2.6):确认 sysctl.d 的值真的生效(注意 /etc/sysctl.conf 覆盖坑)
sysctl -n net.core.somaxconn net.ipv4.tcp_max_syn_backlog net.ipv4.tcp_fastopen \
net.ipv4.tcp_slow_start_after_idle net.ipv4.ip_local_port_range
# KVM/完整 VM 追加:net.core.netdev_max_backlog / rmem_max / wmem_max
tc qdisc show | grep -v noqueue # 期望默认路由网卡为 fq(容器内为 noqueue,属正常)
systemctl is-active rrpp-qdisc # 期望 active(容器内该单元会自行跳过)
# fail2ban # fail2ban
fail2ban-client status sshd # => jail 存在(见 2.5) fail2ban-client status sshd # => jail 存在(见 2.5)
@@ -548,6 +643,9 @@ curl -sk https://<节点域名>:<nginx端口>/ -o /dev/null -w '%{http_code}\n'
``` ```
server_config/ server_config/
├── README.md ← 本文档 ├── README.md ← 本文档
├── sysctl/
│ ├── 99-zz-rrpp-network.kvm.conf ← 系统级网络优化(KVM/完整 VM,见 §2.6)
│ └── 99-zz-rrpp-network.lxc.conf ← 系统级网络优化(LXC/OpenVZ 容器,见 §2.6)
├── nginx/ ├── nginx/
│ ├── nginx.conf ← 完整 nginx 配置(占位符版) │ ├── nginx.conf ← 完整 nginx 配置(占位符版)
│ ├── local_ip_rules.conf.example ← 本机 IP 规则文件示例(cron 自动生成,勿手改) │ ├── local_ip_rules.conf.example ← 本机 IP 规则文件示例(cron 自动生成,勿手改)
@@ -560,9 +658,11 @@ server_config/
├── systemd/ ├── systemd/
│ ├── nginx.service │ ├── nginx.service
│ ├── sing-box.service │ ├── sing-box.service
│ └── mtg.service │ ├── mtg.service
│ └── rrpp-qdisc.service ← 开机把默认网卡 qdisc 设为 fq(见 §2.6)
├── scripts/ ├── scripts/
│ └── sync-nginx-local-ips.sh ← 本机公网 IP 规则自动维护 │ ├── sync-nginx-local-ips.sh ← 本机公网 IP 规则自动维护
│ └── rrpp-qdisc.sh ← fq 队列设置脚本(rrpp-qdisc.service 调用)
├── cron/ ├── cron/
│ └── sync-nginx-local-ips ← cron 定义(每 5 分钟) │ └── sync-nginx-local-ips ← cron 定义(每 5 分钟)
├── rrpp-subscription/ ← RRPP 订阅后端(bj,见 §12) ├── rrpp-subscription/ ← RRPP 订阅后端(bj,见 §12)
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
# 把默认路由网卡的根 qdisc 设为 fq(BBR 的最佳搭档)。
# 背景:net.core.default_qdisc=fq 只对"新创建"的网卡生效,已存在的网卡
# 重启后仍可能是 pfifo_fast/fq_codel,故用本脚本显式设置。
# 仅在 KVM/裸机可用;LXC 容器内网卡为 noqueue,本脚本会自行跳过。
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 设置"
exit 0
fi
tc qdisc replace dev "$IFACE" root fq 2>/dev/null && echo "已设置 $IFACE root qdisc = fq" || echo "设置 $IFACE qdisc 失败(可忽略)"
@@ -0,0 +1,43 @@
# ============================================================
# RRPP 节点系统级网络优化(KVM / 完整虚拟机版,含 Azure 等)
# 部署位置:/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
# ============================================================
# --- 拥塞控制与队列(BBR 需配 fq,否则易 bufferbloat)---
net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc = fq
# --- 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
# --- 队列深度与缓冲(高并发 / 大 BDP)---
net.core.somaxconn = 32768
net.ipv4.tcp_max_syn_backlog = 32768
net.core.netdev_max_backlog = 32768
net.core.rmem_max = 33554432
net.core.wmem_max = 33554432
net.ipv4.tcp_rmem = 4096 131072 33554432
net.ipv4.tcp_wmem = 4096 16384 33554432
@@ -0,0 +1,37 @@
# ============================================================
# 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 级项。
# ============================================================
# --- 拥塞控制(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
+12
View File
@@ -0,0 +1,12 @@
[Unit]
Description=RRPP: set fq qdisc on default-route interface (BBR companion)
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/sbin/rrpp-qdisc.sh
[Install]
WantedBy=multi-user.target