Linux: ограничение конкретной скорости порта путем объединения tc с iptables не работает должным образом
Сценарий удара пытается ограничить входящую скорость порта 2000 при использовании iptables для пометки INPUT
пакеты не работают, но OUTPUT
работает отлично.
я использую nc -kl 2000
на машине 10.0.1.54
а также iperf -c 10.0.1.54 -p 2000 -t 10
на другой машине, чтобы проверить это.
Зачем 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
3 ответа
Я пытаюсь ответить на этот вопрос, перечислив ссылки ниже:
Существует два режима формирования трафика: INGRESS и EGRESS. INGRESS обрабатывает входящий трафик и EGRESS исходящий трафик. Linux не поддерживает формирование / постановку в очередь на INGRESS, а только применение политик. Следовательно, существует IFB, который мы можем присоединить к очереди INGRESS, в то время как мы можем добавить любую обычную очередь, такую как FQ_CODEL, в качестве очереди EGRESS на устройстве IFB. [ http://wiki.gentoo.org/wiki/Traffic_shaping]
Итак, мое решение этого вопроса:
#!/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
То, что сказал Цзиньчжэн, правильно, вы не можете формировать входной трафик. но вы можете сделать это как капитан Джек Воробей... изменить факты.
создайте соединение openvpn между вашим хостом и vps с помощью "redirect-gateway", чтобы весь трафик проходил через vps. так это выглядит так: ваша домашняя сеть / пк -> интернет -> vps -> интернет
для вашей домашней сети INGRESS - это EGRESS для vps, а затем формируйте исходящий интерфейс для vps.
Несколько советов: не забудьте указать свою домашнюю сеть / IP, или вы убьете скорость загрузки VPS. VPS должен иметь лучшую пропускную способность, чем ваша сеть, измерьте пропускную способность. в Германии вы можете просто получить 7€ vps от hetzner.de, они довольно надежны.
Это не обязательно делать, это просто, вам нужно просто пропатчить ядро и iptables, а затем вы можете формировать входящий трафик +, если вы используете LXC, вам даже не нужно ничего патчить, только на KVM