Вот это этот манул, и он работал...
tc
Утилита tc в Linux применяется для управления трафиком. Она позволяет ограничивать или сглаживать исходящий трафик, обеспечивать гарантированную полосу определённому виду трафика, применять разные политики ко входящему трафику и не умеет разве что грабить корованы. Замечательно, что tc написан нашим соотечественником Алексеем Кузнецовым и включён в ядро Linux, начиная с версии 2.2.
В этой области “правят бал” несколько понятий. Это:
qdisc (queueing discipline) – фактически очередь для конкретного сетевого интерфейса, из которого выбираются пакеты перед отправкой драйверу сетевой карты.
class – классы внутри очередей, в которые входят другие очереди. Разбиение по классам позволяет создавать приоритеты для обслуживания разных видов трафика. Класс всегда имеет одного родителя-qdisc.
filter – фильтры для определения, в очередь какого класса помещать тот или иной исходящий пакет.
Все очереди, классы и фильтры должны иметь идентификатор (который, впрочем, может назначаться автоматически). Идентификатор состоит обычно из двух чисел, разделенных двоеточием. Qdisc, потенциально могущий иметь классы-наследники, обычно имеет идентификатор только из старшего числа с двоеточием – handle. Классы наследуют это старшее число, которое вместе с младшим (например 1:10), образует classid.
Для всех объектов tc доступен набор команд, смысл, которых в основном ясен из их названия: add, remove, change, replace.
Очереди
Существуют несколько видов очередей, соответствующих моделям из теории массового обслуживания и телетрафика:
CBQ (Class-Based Queueing) – Очередь, основанная на классах. Позволяет создавать иерархию классов с приоритетами. Управление производится в зависимости от общей пропускной способности и загруженности канала.
HTB (Hierarchical Token Bucket) – Алгоритм дырявого ведра. Позволяет ограничивать пропускную способность независимо от общей пропускной способности канала. Поддерживает приоритеты.
PRIO – очередь, не влияющая на пропускную способность. Пакеты более низких приоритетов уходят на сетевую карту только при отсутствии в очереди пакетов полее высоких приоритетов.
Ещё есть несколько бесклассовых видов очередей:
[P|B]FIFO – First In, First Out с ограничением в пакетах или байтах.
RED (Random Early Detection) – имитирует физические заторы, отбрасывая пакеты при приближении к выделенной полосе пропускания.
SFQ (Stochastic Fairness Queueing) – равномерное распределение пакетов из разных сессий внутри очереди. Трафик разбивается на большое количество FIFO очередей, которые получают доступ к сетевой карте в режиме round-robin. Параметры: perturb – время, через которое будет меняться алгоритм распределения пакетов (обычно ставят 10 с), quantum – объем данных, выпускааемых из потока за один раз (по умолчанию MTU).
TBF (Token Bucket Filter) – замедляет трафик по точно заданному лимиту. Параметры следующие: rate – нужная скорость, latency – максимальное время в очереди, burst – размер “ведра” в байтах.
Если подвести итог, то TBF хорошо подходит, если надо замедлить весь исходящий трафик от узла на конкретном интерфейсе, а HTB – для построения иерархии классов и шейпинга трафика в соответствии с этой иерархией. При этом CBQ требует учитывания ряда дополнительных параметров, которые придётся для каждого конкретного случая получать эмпирическим путём, поэтому используется редко.
Приступим
Для начала определим корневую дисциплину для конкретного сетевого интерфейса и набор классов-наследников:
1.
tc qdisc add dev eth0 root handle 1: htb default 3
2.
tc class add dev eth0 parent 1: classid 1:1 htb rate 64kbit
3.
tc class add dev eth0 parent 1: classid 1:2 htb rate 4mbit burst 15k
4.
tc class add dev eth0 parent 1: classid 1:3 htb rate 4mbit ceil 100mbit
Здесь мы создали корневой qdisc с идентификатором 1: , дисциплиной обслуживания HTB, сетевым интерфейсом eth0 и классом по умолчанию 1:3. И для него 3 класса: один с постоянной полосой 64kbit, второй с постоянной полосой 4mbit и максимальным объемом данных, который может быть передан через сетевую карту без переключения на другие классы, 15k, и, наконец, третий с гарантированной скоростью 4mbit и выше.
Для каждого класса при необходимости можно прописать отдельную дисциплину, например:
1.
tc qdisc add dev eth0 parent 1:1 red min 1600 max 3210 burst 2 limit 32100 avpkt 1000
2.
tc qdisc add dev eth0 parent 1:2 sfq perturb 10
После создания иерархии классов и набора дисциплин нам останется только распределить трафик по классам. Сделать это можно несколькими способами.
Способ первый – tc filter. В зависимости от некоторых условий направляем пакеты в класс 1:1
1.
tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip dst 192.168.0.1 flowid 1:1
В данном случае это пакеты, получателем у которых указан ip 192.168.0.1.
Способ второй – пометка пакетов с помощью iptables
1.
iptables -A OUTPUT -t mangle -p tcp -d 192.168.0.2 --dport 80 -j MARK --set-mark 20
2.
tc filter add dev eth0 protocol ip parent 1: prio 2 handle 20 fw classid 1:2
Способ третий – установка класса сразу с помощью iptables
1.
iptables -t mangle -A POSTROUTING -p tcp -d 192.168.0.3 -j CLASSIFY --set-class 1:3
Резюме
Задачу по ограничению исходящего трафика в направлении определенного хоста можно выполнить, например, следующими тремя командами:
1.
tc qdisc add dev eth0 root handle 1: htb default 1
2.
tc class add dev eth0 parent 1: classid 1:1 htb rate 1mbit
3.
iptables -t mangle -A POSTROUTING -p tcp -d 192.168.0.3 -j CLASSIFY --set-class 1:1
Напоследок
Полезными могут оказаться знания о том, как проверить маркировку пакетов в iptables:
iptables -L -n -v -t mangle
Вот так можно удалить все правила:
tc qdisc del dev eth0 root
iptables -t mangle -F