如何使用 iptables 识别下载流量

如何使用 iptables 识别下载流量

我如何识别下载流量并设置标记,以便我可以使用 fwmark 通过另一个链接路由这些数据包?

答案1

iptables模块connbytes、connlimit 和 length 可用于识别下载。以下设置使用:

#Mark downloads
$IPT -t mangle -N BULKCONN   
#Small packet is probably interactive or flow control
$IPT -t mangle -A BULKCONN -m length --length 0:500 -j RETURN
#Small packet connections: multi purpose (don't harm since not maxed out)
$IPT -t mangle -A BULKCONN -m connbytes --connbytes 0:250 --connbytes-dir both --connbytes-mode avgpkt -j RETURN

#After one megabyte a connection is considered a download
$IPT -t mangle -A BULKCONN -m connbytes --connbytes 1048576: --connbytes-dir both --connbytes-mode bytes -j MARK --set-mark 6
$IPT -t mangle -A BULKCONN -j RETURN

$IPT -t mangle -A PREROUTING -i eth1 -j BULKCONN

我使用排队规则来对下载和其他流量进行优先排序。

关于通过另一个链接发送:我还没准备好回答这个问题,但是可以使用 iproute2 来完成(假设您指的是另一个 IP 链接)。但是它只能在下游工作,因为您无法控制上游流量到达您的位置。

答案2

我受到 @Ganwell 解决方案的启发,并设法在添加分类流量整形的基础上解决了这个问题tc。我在个人 wiki 中发布了关于此解决方案的博文:https://giki.wiki/@nubela/Software-Engineering/Per-Connection-Throttling

下面是我使用实际的 shell 脚本对此问题的解决方案:

#!/bin/sh

dev=eth0
ip_port=3002
rate_limit=512kbit
rate_ceil=1024kbit
htb_class=10
max_byte=10485760

if [ "$(id -u)" != "0" ]; then
    echo "This script must be run as root" 1>&2
    exit 1
fi

if [ "$1" = "enable" ]; then
    echo "enabling rate limits"
    tc qdisc del dev $dev root > /dev/null 2>&1
    tc qdisc add dev $dev root handle 1: htb

    tc class add dev $dev parent 1: classid 1:$htb_class htb rate $rate_limit ceil $rate_ceil
    tc filter add dev $dev parent 1: prio 0 protocol ip handle $htb_class fw flowid 1:$htb_class

    #iptables -t mangle -A OUTPUT -p tcp --sport $ip_port -j MARK --set-mark $htb_class

    # small packet is probably interactive or flow control
    iptables -t mangle -A OUTPUT -p tcp --sport $ip_port -m length --length 0:500 -j RETURN

    # small packet connections: multi purpose (don't harm since not maxed out)
    iptables -t mangle -A OUTPUT -p tcp --sport $ip_port -m connbytes --connbytes 0:250 --connbytes-dir both --connbytes-mode avgpkt -j RETURN

    #after 10 megabyte a connection is considered a download
    iptables -t mangle -A OUTPUT -p tcp --sport $ip_port -m connbytes --connbytes $max_byte: --connbytes-dir both --connbytes-mode bytes -j MARK --set-mark $htb_class
    iptables -t mangle -A OUTPUT -j RETURN

elif [ "$1" = "disable" ]; then
    echo "disabling rate limits"
    tc qdisc del dev $dev root > /dev/null 2>&1

    iptables -t mangle -F
    iptables -t mangle -X

elif [ "$1" = "show" ]; then
    tc qdisc show dev $dev
    tc class show dev $dev
    tc filter show dev $dev
    iptables -t mangle -vnL INPUT
    iptables -t mangle -vnL OUTPUT
else
    echo "invalid arg $1"
fi

相关内容