前段时间对网卡做了上行限制,导致本地打开飞牛后台也很慢。因为在系统中部署了PCDN,所以需要有针对性的将PCDN上行按时段限制,同时不影响其它进程。
于是先按进程名程建立上行限速规则,但过于复杂,效果并不好。遂决定按端口限速,即将所有端口限速但排除常用的端口,比如飞牛的5666、ssh的22端口。
先新建脚本nano /usr/local/bin/fn_speedlimit.sh
#!/bin/bash
# ============================================
# 飞牛 (fnOS) 上行带宽限速脚本
# 用法:./fn_speedlimit.sh {start|stop|status|restart}
# ============================================
# ===== 用户配置区域 =====
INTERFACE="eth0" # 修改为你的网卡名,用 ip link show 查看
LIMIT_RATE="10mbit" # 限速值,如 5mbit / 10mbit / 100mbit
EXCLUDE_PORTS="22,443,8080" # 排除的端口,逗号分隔,无则留空 ""
# =========================
IPMARK="100"
TC_CLSID="1:${IPMARK}"
start_limit() {
echo "正在为网卡 $INTERFACE 设置上行限速: $LIMIT_RATE ..."
tc qdisc del dev $INTERFACE root 2>/dev/null
tc qdisc add dev $INTERFACE root handle 1: htb default 20
tc class add dev $INTERFACE parent 1: classid 1:1 htb rate $LIMIT_RATE
tc class add dev $INTERFACE parent 1:1 classid 1:20 htb rate $LIMIT_RATE
tc class add dev $INTERFACE parent 1:1 classid $TC_CLSID htb rate 10000mbit
tc filter add dev $INTERFACE parent 1: protocol ip prio 1 u32 match ip mark $IPMARK 0xffffffff flowid $TC_CLSID
iptables -t mangle -D OUTPUT -j FN_SPEED_LIMIT 2>/dev/null
iptables -t mangle -F FN_SPEED_LIMIT 2>/dev/null
iptables -t mangle -X FN_SPEED_LIMIT 2>/dev/null
iptables -t mangle -N FN_SPEED_LIMIT
iptables -t mangle -A OUTPUT -j FN_SPEED_LIMIT
IFS=',' read -ra PORTS <<< "$EXCLUDE_PORTS"
for PORT in "${PORTS[@]}"; do
if [[ -n "$PORT" ]]; then
iptables -t mangle -A FN_SPEED_LIMIT -p tcp --sport $PORT -j MARK --set-mark $IPMARK
iptables -t mangle -A FN_SPEED_LIMIT -p udp --sport $PORT -j MARK --set-mark $IPMARK
echo "已添加排除端口: $PORT"
fi
done
iptables -t mangle -A FN_SPEED_LIMIT -j MARK --set-mark 0
echo "限速规则已生效。"
}
stop_limit() {
echo "正在停止所有限速规则..."
tc qdisc del dev $INTERFACE root 2>/dev/null
iptables -t mangle -D OUTPUT -j FN_SPEED_LIMIT 2>/dev/null
iptables -t mangle -F FN_SPEED_LIMIT 2>/dev/null
iptables -t mangle -X FN_SPEED_LIMIT 2>/dev/null
echo "限速规则已清除。"
}
status_check() {
echo "========== 限速状态检查 =========="
if tc qdisc show dev $INTERFACE | grep -q "htb 1:"; then
echo -e "[状态] 限速: 已启用"
echo "当前限速设置:"
tc class show dev $INTERFACE | grep "htb rate"
else
echo "[状态] 限速: 已停止"
fi
echo "排除端口: $EXCLUDE_PORTS"
echo "================================="
}
case "$1" in
start)
start_limit
;;
stop)
stop_limit
;;
status)
status_check
;;
restart)
stop_limit
start_limit
;;
*)
echo "使用方法: $0 {start|stop|status|restart}"
exit 1
;;
esac保存后chmod +x /usr/local/bin/fn_speedlimit.sh赋予权限。
测试脚本:/usr/local/bin/fn_speedlimit.sh start
然后检查状态:/usr/local/bin/fn_speedlimit.sh status
预期结果:应该显示“限速: 已启用”。
增加系统重启后自动启动功能:nano /etc/systemd/system/fn-speedlimit.service
[Unit]
Description=FN OS Bandwidth Limiter
After=network.target
Wants=network.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/fn_speedlimit.sh start
ExecStop=/usr/local/bin/fn_speedlimit.sh stop
StandardOutput=journal
[Install]
WantedBy=multi-user.target然后添加定时任务: crontab -e
#定时开启限速
30 22 * * * /usr/local/bin/fn_speedlimit.sh start
#定时停止限速
30 18 * * * /usr/local/bin/fn_speedlimit.sh stop按以上格式,自定义时间;如需要设定不同限速值,可以新建另一个脚本定义好上行限值,同样添加到定时任务中即可,会自动按时间切换规则。