URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID1
Нить номер: 63884
[ Назад ]

Исходное сообщение
"Шейпинг в линукс"

Отправлено aleks , 03-Фев-06 15:48 
Доброго времени суток!

Есть необходимость средствами сервера с ОС Linux нарезать полосу в интернет для компьютеров локальной сети. Я не специалист в iptables, ранее делал подобное средствами предаставляемыми FreeBSD. Вот например как я резал полосу с помощью ipfw pipe для адресов в локалке 1.1.1.100 и 1.1.1.101:

ipfw pipe 1000 config bw 64Kbit/s
ipfw add 1000 pipe 1000 ip from 1.1.1.100 to not 1.1.1.0/24 via fxp0
ipfw add 1000 pipe 1000 ip from 1.1.1.0/24 to not 1.1.1.100 via ed0

ipfw pipe 1001 config bw 64Kbit/s
ipfw add 1001 pipe 1000 ip from 1.1.1.101 to not 1.1.1.0/24 via fxp0
ipfw add 1001 pipe 1000 ip from 1.1.1.0/24 to not 1.1.1.101 via ed0

Т.о. я организовываю симетричный канал толщиной 64К. Не поможите перевести это на язык iptables? Буду благодарен за пример.

Заранее благодарен.


Содержание

Сообщения в этом обсуждении
"Шейпинг в линукс"
Отправлено Nimdar , 03-Фев-06 16:00 
Ключевые слова в поиске на opennet - shaper linux

"Шейпинг в линукс"
Отправлено aleks , 03-Фев-06 16:02 
>Ключевые слова в поиске на opennet - shaper linux

Искал. Кое что нашёл, но не проникся идеей...
Может быть всё же кто-то пример приведёт...


"Шейпинг в линукс"
Отправлено Nimdar , 03-Фев-06 16:10 
Средствами _только_ iptables, наподобие ipfw во фре, это сделать невозможно.

"Шейпинг в линукс"
Отправлено aleks , 03-Фев-06 16:21 
>Средствами _только_ iptables, наподобие ipfw во фре, это сделать невозможно.

Понятно. Но вроде можно утилиту tc попользовать. Только вот я ни как не врублюсь как увязать tc и iptables вместе.


"Шейпинг в линукс"
Отправлено ipmanyak , 03-Фев-06 16:53 
может проще поставить проксю сквид и там настроить  delay pool ?

"Шейпинг в линукс"
Отправлено aleks , 03-Фев-06 17:23 
>может проще поставить проксю сквид и там настроить  delay pool ?
>


не это не пойдёт


"Шейпинг в линукс"
Отправлено Slimm , 04-Фев-06 00:38 
вообщем tc и iptables несвязанные вещи, но в целом обе управляют трафиком
tc управляет очередями протокола, а iptables управляет файрволом
цепочка прохождения пакета - сначало файрвол потом очереди затем интерфейс его "выплюнет", это касается исходящих пакетов.
С входящими дело сложней так как скорость их прихода регулировать нельзя, есть некоторые ухищрения вообщем связанныйе с псевдоинтерфейсом относительно которого пакеты считаются исходящими ...
Так же ясно что маршрутизатор обычно имеет >2 интерфейсов, что и позволяет одинаково шейпить трафик, в обе стороны

tc qdisc add dev $DEVICE root handle 1: htb

tc class add dev $DEVICE parent 1: classid 1:1 htb rate 100mbit ceil 100mbit burst 16k
tc class add dev $DEVICE parent 1:1 classid 1:10 htb rate ${UP}kbit ceil ${UP}kbit burst 16k
tc filter add dev $DEVICE parent 1:0 protocol ip prio 1 handle 1 fw flowid 1:10

и теперь связь с iptables :)

iptables -t mangle -A PREROUTING -s 10.10.10.10 -j MARK --set-mark 1
iptable -t mangle -A POSTROUTING -d 10.10.10.10 -j MARK --set-mark 1

tc filter - настроен так, что пакеты помеченные как --set-mark 1 загоняет в classid 1:10 скорость которого ограничена.

Ну и так на всякий случай ;) не путайте --set-mark 1 это внутриядерная маркировка пакета, она не модифицирует пакет.


"Шейпинг в линукс"
Отправлено jonatan , 06-Фев-06 09:25 
>tc class add dev $DEVICE parent 1: classid 1:1 htb rate 100mbit
>ceil 100mbit burst 16k
>tc class add dev $DEVICE parent 1:1 classid 1:10 htb rate ${UP}kbit
>ceil ${UP}kbit burst 16k
В данном случае ceil можно не указывать
tc class add dev $DEVICE parent 1: classid 1:1 htb rate 100mbit burst 16k
tc class add dev $DEVICE parent 1:1 classid 1:10 htb rate 64kbit burst 16k
>tc filter add dev $DEVICE parent 1:0 protocol ip prio 1 handle
>1 fw flowid 1:10
Рекомендуется добавлять еще sfq
tc qdisc add dev $DEVICE parent 1:10 handle 10:0 sfq perturb 10

"Шейпинг в линукс"
Отправлено aleks , 07-Фев-06 14:26 
В итоге я реализовал шейпинг следующим образом:
# Создаю очереди на внешнем (eth1) и внутреннем (eth2) интерфейсе
tc qdisc add dev eth1 root handle 1:0 cbq avpkt 10000 bandwidth 100mbit
tc qdisc add dev eth2 root handle 2:0 cbq avpkt 10000 bandwidth 100mbit

# Создаю 2 класса трафика на внешнем и внутреннем интерфейсах
tc class add dev eth1 parent 1:0 classid 1:10001 cbq rate 128kbit allot 1500 bounded isolated
tc class add dev eth2 parent 2:0 classid 2:20001 cbq rate 128kbit allot 1500 bounded isolated

# Загоняю исходящий траффик относительно интерфейсов сервера в соответствующие классы.
# IP рабочей станции в локалке 1.1.1.101, локальная сеть 1.1.1.0/24
tc filter add dev eth1 parent 1:0 protocol ip handle 10001 fw flowid 1:10001
tc filter add dev eth2 parent 2:0 protocol ip handle 20001 fw flowid 2:20001
iptables -t mangle -A POSTROUTING -d 1.1.1.101 -s ! 1.1.1.0/24 -j MARK --set-mark 20001
iptables -t mangle -A PREROUTING  -s 1.1.1.101 -d ! 1.1.1.0/24 -j MARK --set-mark 10001

Проверка на практике показала что вроде бы всё получилось. Трафик жмётся в обе стороны. Причём при одновременной заливке и скачивании, сумарная пропускная способнось немного привышает 128К. На фре решение безусловно выглядело красивее :).

Но вот с чем я попутно столкнулся. На самом деле интерфейсы eth1 и eth2 у меня объединины в бридж с помощью "brctl":
# brctl addbr br0
# brctl addif br0 eth1
# brctl addif br0 eth2
# ifconfig br0 up
Я подумал что интерфейс br0 является исходящим и для пакетов уходящих через бридж от компов локалки в интернет и для пакетов приходящих из интернет в локалку. Исходя из этих соображений я решил повесить очередь, классы и фильтры на интерфейс br0 (тем самым я надеялся получить полный аналог pipe - FreeBSD):

tc qdisc add dev br0 root handle 1:0 cbq avpkt 10000 bandwidth 100mbit
tc class add dev br0 parent 1:0 classid 1:10001 cbq rate 128kbit allot 1500 bounded isolated
tc filter add dev br0 parent 1:0 protocol ip handle 10001 fw flowid 1:10001
iptables -t mangle -A POSTROUTING -d 1.1.1.101 -s ! 1.1.1.0/24 -j MARK --set-mark 10001
iptables -t mangle -A PREROUTING  -s 1.1.1.101 -d ! 1.1.1.0/24 -j MARK --set-mark 10001

Но к сожалению такая конфигурация не заработала. Трафик ходил через сервер без всякого шейпинга. По всей видимости "tc" не может работать с бридж-интерфейсом. Или я что-то сделал не так?


"Шейпинг в линукс"
Отправлено nrvalex , 07-Фев-06 18:20 
>Но к сожалению такая конфигурация не заработала. Трафик ходил через сервер без
>всякого шейпинга. По всей видимости "tc" не может работать с бридж-интерфейсом.
>Или я что-то сделал не так?

tc умеет работать с бриджем , но на бридже не работает c iptables mark

tc filter add dev br0 parent 1:0 protocol ip match ip src 1.2.3.0/24 classid 1:10001


"Шейпинг в линукс"
Отправлено aleks , 07-Фев-06 19:15 
>>Но к сожалению такая конфигурация не заработала. Трафик ходил через сервер без
>>всякого шейпинга. По всей видимости "tc" не может работать с бридж-интерфейсом.
>>Или я что-то сделал не так?
>
>tc умеет работать с бриджем , но на бридже не работает c
>iptables mark
>
>tc filter add dev br0 parent 1:0 protocol ip match ip src
>1.2.3.0/24 classid 1:10001

Сделал так:
tc qdisc add dev br0 root handle 1:0 cbq avpkt 10000 bandwidth 100mbit
# шайплю 1.1.1.101
tc class add dev br0 parent 1:0 classid 1:1 cbq rate 32kbit allot 1500 bounded isolated
tc filter add dev br0 parent 1:0 protocol ip u32 match ip src 1.1.1.101 classid 1:1
tc filter add dev br0 parent 1:0 protocol ip u32 match ip dst 1.1.1.101 classid 1:1

Хост 1.1.1.101 не жмётся :((


"Шейпинг в линукс"
Отправлено aleks , 07-Фев-06 19:51 
Теперь я пытаюсь автоматически управлять скоростью интернет для компьютера в локалке. Делать это пытаюсь изменением битрейт на классе. Для этого мне необходимо удалить класс и добавить его уже с другим битрейтом. Но чтобы это сделать надо сначало удалить фильтр ссылающийся на него. С удалением фильтра проблема. Он или не удаляется (tc ругается на синтаксис) или удаляются все фильтры прицепленные к данному устройству. Добавлен фильтр следующей командой:

tc filter add dev eth2 parent 1:0 protocol ip handle 10001 fw flowid 1:10001

Не подскажите как удалить интересующий меня фильтр (и только его)?


"Шейпинг в линукс"
Отправлено nrvalex , 07-Фев-06 20:53 
>Теперь я пытаюсь автоматически управлять скоростью интернет для компьютера в локалке. Делать
>это пытаюсь изменением битрейт на классе. Для этого мне необходимо удалить
>класс и добавить его уже с другим битрейтом. Но чтобы это
>сделать надо сначало удалить фильтр ссылающийся на него. С удалением >фильтра проблема.
tc class change classid 1:1 ... ?

"Шейпинг в линукс"
Отправлено aleks , 08-Фев-06 11:10 
>tc class change classid 1:1 ... ?


Можно и так. Но чтобы сделать "tc class change", надо сначало убидиться что данный класс присутствует. А это усложнит алгоритм программы. Проще было бы это реализовать тупо: сначало del, а потом add.