分享一个基于 nftables 的限速脚本

nfl.sh

#!/bin/bash
set -euo pipefail

_nfl() {
    local cur prev words cword
    _init_completion || return
    if [ "$cword" = 1 ]; then
        COMPREPLY=($(compgen -W 'download upload' -- "$cur"))
    elif [ "$cword" = 2 ]; then
        _available_interfaces
    fi
}
main() {
    local hook ifname interface limit cmds
    case "${1:-}" in
        download)
            hook='input'
            ifname='iifname'
            ;;
        upload)
            hook='output'
            ifname='oifname'
            ;;
        '')
            sudo nft 'add table inet nfl; list table inet nfl'
            return
            ;;
        *)
            exit 1
            ;;
    esac
    if [[ "$2" =~ ^[[:digit:]] ]]; then
        interface=$(ip route list | sed -nE '/^default via \S+ dev (\S+).*$/{s//\1/p;q}')
        limit="$2"
    else
        interface="$2"
        limit="$3"
    fi
    cmds="add table inet nfl; add chain inet nfl ${interface}_$hook { type filter hook $hook priority filter; }"
    if [ "$limit" != 0 ]; then
        cmds="$cmds; flush chain inet nfl ${interface}_$hook; add rule inet nfl ${interface}_$hook $ifname ${interface} meta l4proto { tcp, udp } limit rate over $limit mbytes/second burst 1 mbytes drop"
    else
        cmds="$cmds; delete chain inet nfl ${interface}_$hook"
    fi
    sudo nft "$cmds"
}
main "$@"

用法:

# limit download speed of the default interface to 1MiB
nfl download 1
# change download speed of the default interface to 3MiB
nfl download 3
# remove download speed limitation of the default interface
nfl download 0
# limit upload speed of wlp0s20f3 to 3MiB
nfl upload wlp0s20f3 3
# remove upload speed limitation of wlp0s20f3
nfl upload wlp0s20f3 0
# show content of the nfl table
nfl