通过端口限速,给 Snell 限流
由于云服务商给的 VPS 速度太优秀了,看流媒体时会自动播放最高质量的内容,VPS 流量很快就会被用完,因此不得不做一下限速、让流媒体不要直接拉到画质天花板。
我部署在服务器上的代理工具是 Snell,但它并不支持通过配置文件指定网络带宽。替代方案是用 tc 来限制出网卡(egress)方向,实现对 Snell 端口的限速。
限速目标
这台 VPS 只给了每月 150G 的配额,我预期用 100G 来看流媒体,50G 日常使用。我常看的流媒体是 Apple TV,查了下 15Mbps 这个速率是刚好足够观看 4k 画质的。
流量估算
- 15Mbps ≈ 1.875MB/s ≈ 6.59GB/小时
- 100GB ÷ 6.59GB/小时 ≈ 15.2 小时
满打满算的情况下,100G 够看 15 小时的 Apple TV,我觉得完全没问题,我一个月可能都看不了 15 小时电视。
限速脚本
VPS 上已经有一个跑着的 snell 服务了,换个端口号单独写一个配置文件,然后再开一个服务,对这个服务所使用的端口号进行限制即可,之后在 Surge 客户端中添加为一个新的服务器。
这里我已经创建好了新的服务,端口号用 12345,服务名为 snell-stream。
创建并编辑限速脚本:
nano /usr/local/bin/snell-tc.sh
写入内容:
#!/bin/bash
IFACE=eth0 # 替换成实际网卡名,用 ip a 查看
PORT=12345 # 替换成实际 snell 端口
### 清理旧规则(可选,重复执行脚本时先清空)
tc qdisc del dev $IFACE root 2>/dev/null
tc qdisc del dev $IFACE ingress 2>/dev/null
ip link del ifb0 2>/dev/null
### 下行限速:server 发出的流量 (sport = PORT,TCP/UDP 都覆盖) 限 15Mbps
tc qdisc add dev $IFACE root handle 1: htb default 30
tc class add dev $IFACE parent 1: classid 1:1 htb rate 1000mbit
tc class add dev $IFACE parent 1:1 classid 1:10 htb rate 15mbit ceil 15mbit
tc class add dev $IFACE parent 1:1 classid 1:30 htb rate 1000mbit ceil 1000mbit
tc qdisc add dev $IFACE parent 1:10 handle 10: sfq perturb 10
tc filter add dev $IFACE protocol ip parent 1: prio 1 u32 \
match ip sport $PORT 0xffff flowid 1:10
echo "限速已生效: $IFACE 端口 $PORT 下行15Mbps (TCP+UDP)"
如果哪天需要更换成其他速率比如 10Mbps,只要改动其中的这一行:
tc class add dev $IFACE parent 1:1 classid 1:10 htb rate 10mbit ceil 10mbit
以及这一行:
echo "限速已生效: $IFACE 端口 $PORT 下行10Mbps (TCP+UDP)"
给脚本赋予执行权限:
chmod +x /usr/local/bin/snell-tc.sh
使用 systemd 进行管理
创建并编辑 service 文件:
nano /etc/systemd/system/snell-tc.service
写入内容:
[Unit]
Description=Snell port rate limit
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/snell-tc.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
启用并立即运行:
systemctl daemon-reload
systemctl enable --now snell-tc.service
之后如果修改了脚本,重启一下服务即可:
systemctl restart snell-tc.service
验证
Surge 客户端
在 Apple TV app 中播放起来,然后到 Surge 的 工具—实时统计—策略 中检查对应策略的当前速度和最高速度,网络状况好的时候当前速度和最高速度都是 1.9MB/s,但最高不会超过这个速度。
也可以直接在 工具 中开启实时浮窗,这个更直观一些。
服务器端
通过 nethogs 工具可以直观看到每个进程的实时网络速率,通过 PID 来识别 snell 进程。
首先找到已经做了限速的 snell 服务的端口号:
systemctl status snell-stream.service
● snell-stream.service - Snell Proxy Service
Loaded: loaded (/etc/systemd/system/snell-stream.service; enabled; preset: enabled)
Active: active (running) since Thu 2026-08-06 07:39:39 IST; 1 day 4h ago
Invocation: 4716628ad98a4171868175db130df941
Main PID: 11756 (snell-server)
Tasks: 2 (limit: 506)
Memory: 7.1M (peak: 17.8M)
CPU: 4.785s
CGroup: /system.slice/snell-stream.service
└─11756 /usr/local/bin/snell-server -c /etc/snell/snell-stream.conf
然后使用 nethogs 检查进程的实时速率:
nethogs eth0

可以看到这里面有两个 snell 在跑,而 PID 为 11756 的 snell 进程正是刚刚做了限制的那个,现在还没有达到 1.9 MB/s 的上限,预期不会超过上限值。