飞牛中启用限速脚本后访问速度异常

飞牛中启用限速脚本后访问速度异常

改进脚本如下:

#!/bin/bash

# ============================================
# 飞牛 (fnOS) 上行带宽限速脚本
# 用法:./fn_speedlimit.sh {start|stop|status|restart}
# ============================================

# ===== 用户配置区域 =====
INTERFACE="enp1s0"            # 修改为你的网卡名,用 ip link show 查看
LIMIT_RATE="4mbit"         # 限速值,如 5mbit / 10mbit / 100mbit
EXCLUDE_PORTS="22,443,5666,7000,8080" # 排除的端口,逗号分隔,无则留空 ""
# =========================

IPMARK="100"
TC_CLSID="1:${IPMARK}"

start_limit() {
    echo "正在为网卡 $INTERFACE 设置上行限速: $LIMIT_RATE ..."
    
    # 清除旧的 tc 规则
    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 handle $IPMARK fw flowid $TC_CLSID
#    tc filter add dev $INTERFACE parent 1: protocol ip prio 1 u32 match ip mark $IPMARK 0xffffffff flowid $TC_CLSID

    # === 清理并重建 iptables 链 ===
    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

    # ===== 1. 处理局域网访问(其他设备访问飞牛本机服务) =====
    # 飞牛作为服务端,响应数据包的源端口就是服务端口(如 5666, 12825)
    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 tcp --sport $PORT -j RETURN
            
            iptables -t mangle -A FN_SPEED_LIMIT -p udp --sport $PORT -j MARK --set-mark $IPMARK
            iptables -t mangle -A FN_SPEED_LIMIT -p udp --sport $PORT -j RETURN
            echo "已添加【局域网访问】排除端口: $PORT (源端口匹配)"
        fi
    done

    # ===== 2. 处理 frpc 远程隧道(飞牛主动连接 frps 服务端) =====
    # 注意:这里需要手动填写您的 frps 服务端端口,例如 7000
    FRPS_PORT="7000"   # 请修改为您 frpc.ini 中的 server_port
    iptables -t mangle -A FN_SPEED_LIMIT -p tcp --dport $FRPS_PORT -j MARK --set-mark $IPMARK
    iptables -t mangle -A FN_SPEED_LIMIT -p tcp --dport $FRPS_PORT -j RETURN
    iptables -t mangle -A FN_SPEED_LIMIT -p udp --dport $FRPS_PORT -j MARK --set-mark $IPMARK
    iptables -t mangle -A FN_SPEED_LIMIT -p udp --dport $FRPS_PORT -j RETURN
    echo "已添加【frpc远程隧道】排除端口: $FRPS_PORT (目的端口匹配)"

    # ===== 3. 所有未被排除的流量,统一打上 0 标记,进入限速类 =====
    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

已经彻底解决访问速率异常问题。

增加系统重启后自动启动功能: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

创建服务

systemctl enable fn-speedlimit
systemctl start fn-speedlimit

创建定时任务 crontab -e,增加以下两行:

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
SHELL=/bin/bash
#定时开启限速
30 22 * * * /usr/local/bin/fn_speedlimit.sh start
#定时停止限速 
30 18 * * * /usr/local/bin/fn_speedlimit.sh stop