我如何识别下载流量并设置标记,以便我可以使用 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