该脚本试图限制2000端口的传入速率,当使用iptables标记INPUT数据包不起作用,但OUTPUT工作正常。
我在机器10.0.1.54上使用nc -kl 2000 ,在另一台机器上使用iperf -c 10.0.1.54 -p 2000 -t 10来testing它。
为什么OUTPUT工作,但不是INPUT ?
dev=enp3s0 ip_addr=10.0.1.54 ip_port=2000 rate_limit=20kbit htb_class=10 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_limit tc filter add dev $dev parent 1: prio 0 protocol ip handle $htb_class fw flowid 1:$htb_class # marking the INPUT chain does dot work as expected #iptables -t mangle -A INPUT -d $ip_addr -p tcp --dport $ip_port -j MARK --set-mark $htb_class # marking the OUTPUT chain works fine iptables -t mangle -A OUTPUT -s $ip_addr -p tcp --sport $ip_port -j MARK --set-mark $htb_class elif [ "$1" = "disable" ]; then echo "disabling rate limits" tc qdisc del dev $dev root > /dev/null 2>&1 #iptables -t mangle -D INPUT -d $ip_addr -p tcp --dport $ip_port -j MARK --set-mark $htb_class iptables -t mangle -D OUTPUT -s $ip_addr -p tcp --sport $ip_port -j MARK --set-mark $htb_class 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
我尝试通过列出下面的链接来回答这个问题:
stream量整形有两种模式,INGRESS和EGRESS。 INGRESS处理传入stream量和EGRESS传出stream量。 Linux不支持INGRESS上的整形/排队,但只支持pipe制。 因此,IFB存在,我们可以将其附加到INGRESS队列,而我们可以在IFB设备上添加任何正常排队,如FQ_CODEL作为EGRESS队列。 [ http://wiki.gentoo.org/wiki/Traffic_shaping%5D
为什么TC不能做入口塑造? 入口整形是否有意义?
Tc:入口pipe制和ifb镜像
所以,我对这个问题的解决scheme是:
#!/bin/bash dev=enp3s0 ifb_dev=ifb0 ip_addr=10.0.1.54 ip_port=2000 rate_limit=20kbit htb_class=10 if [ "$(id -u)" != "0" ]; then echo "This script must be run as root" 1>&2 exit 1 fi modprobe ifb ifconfig ifb0 up if [ "$1" = "enable" ]; then echo "enabling rate limits" tc qdisc add dev $dev handle ffff: ingress tc filter add dev $dev parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev $ifb_dev tc qdisc add dev $ifb_dev root handle 1: htb tc class add dev $ifb_dev parent 1: classid 1:$htb_class htb rate $rate_limit ceil $rate_limit tc filter add dev $ifb_dev parent 1: protocol ip prio 1000 u32 match ip dport 2001 0xffff flowid 1:$htb_class elif [ "$1" = "disable" ]; then echo "disabling rate limits" tc qdisc del dev $dev root > /dev/null 2>&1 tc qdisc del dev $dev ingress > /dev/null 2>&1 tc qdisc del dev $ifb_dev root > /dev/null 2>&1 tc qdisc del dev $ifb_dev ingress > /dev/null 2>&1 elif [ "$1" = "show" ]; then tc qdisc show dev $dev tc class show dev $dev tc filter show dev $dev else echo "invalid arg $1" fi
金正说的是对的,你不能形成入口的stream量。 但你可以像jackson船长那样做…改变事实。
使用“redirect-gateway”在主机和vps之间创build一个openvpn连接,以便所有的stream量通过vps。 所以它看起来像这样:你的家庭networking/电脑 – >互联网 – > VPS – >互联网
什么为您的家庭networking是INGRESS是EGRPS为vps然后塑造出口接口在vps。
一些提示:请记住指定您的家庭networking/ IP或您将杀死VPS上传速度。 vps必须比你的家庭networking有更好的带宽,测量带宽。 在德国,你可以从hetzner.de获得7€vps,他们非常可靠。