Я пытаюсь ограничить скорость всего входящего трафика на портах 8128-8191. Прочитал все, что нашел, раз десять проверил, все равно не работает.
Команды:
tc qdisc del dev eth0 root
tc qdisc add dev eth0 root handle 1: htb default 1
tc class add dev eth0 parent 1:0 classid 1:1 htb rate 1kbit ceil 1kbit
tc filter add dev eth0 parent 1:0 prio 1 protocol ip u32 match ip dport 8128 0xFFC0 classid 1:1
Вот как я рассчитал маску:
expected = lowest port = 0b_0001_1111_1100_0000 = 0x1FC0 = 8128d
mask = highest port = 0b_1111_1111_1100_0000 = 0xFFC0
highest port = 0b_0001_1111_1111_1111 = 0x1FFF = 8191d
Выход:
#tc -s class show dev eth0
class htb 1:1 root prio 0 rate 1000bit ceil 1000bit burst 1600b cburst 1600b
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
rate 0bit 0pps backlog 0b 0p requeues 0
lended: 0 borrowed: 0 giants: 0
tokens: 200000000 ctokens: 200000000
# tc filter show dev eth0
filter parent 1: protocol ip pref 1 u32
filter parent 1: protocol ip pref 1 u32 fh 800: ht divisor 1
filter parent 1: protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:1
match 00001fc0/0000ffc0 at 20
Я отправляю поток байтов со своей рабочей станции с помощью:
cat /dev/urandom | pv -L 3k | nc -nvv ${SERVER_ADDRESS} 8128
На сервере я их получаю с:
nc -nvvl -p 8128 > /dev/null
Я проверяю использование eth1 с помощью отличного iptraf, и пропускная способность остается на уровне 3 кбит / с и более, и нет увеличения счетчиков class htb 1:1
.
Я считаю, что хорошо с масками. Я также пробовал что-то попроще с dport 8128 0xFFFF
без результатов.
При отображении фильтра at 20
кажется правильным, потому что IP-заголовок имеет длину 20 байт. Порты источника и назначения - это первые 4 байта, поэтому 32-битное совпадение является правильным. Я не понимаю других ценностей.
Я использую Debian 7:
# uname -a
Linux node-1 3.2.0-4-amd64 #1 SMP Debian 3.2.68-1+deb7u5 x86_64 GNU/Linux
Я также очищен все в iptables, прежде чем пытаться выполнить вышеуказанное.
Может, я что-то напортачил в том, как подключаю фильтр к классу. Может есть какая-то опция ядра, которую я забыл активировать.
Есть идеи?
1) Ограничение (формирование) входящего трафика с помощью tc
со стандартным ядром Linux сложно. Можете попробовать патч IMQ http://www.linuximq.net/ для вашего ядра. Вам также нужен патч для iptables. Затем вы можете «пометить» пакет для перехода на устройство IMQ, и с помощью tc
на imq0 устройство вы можете формировать трафик как хотите.
2) Еще одно простое, но не точное решение - использование iptables, но оно основано на подсчете пакетов (вам необходимо приблизить средний размер пакета для вашего протокола / соединения)
iptables -A INPUT -p tcp --dport 8128:8191 -m limit --limit 5/seconds -j ACCEPT
iptables -A INPUT -p tcp --dport 8128:8191 -j DROP
Вам нужны эти две строки: первая будет принимать первые 5 пакетов каждую секунду для всех ip вместе, а вторая отбрасывать все поверх нее.