Я пытаюсь просто задержать трафик, нацеленный на определенный IP-адрес в поле Ubuntu 16.06, безуспешно. Есть много ресурсов, как этот этот этот или этот что я изучал. Я получил эти два набора команд, ни одна из них не работает:
tc qdisc add dev eth0 root handle 1: prio
tc qdisc add dev eth0 parent 1:1 handle 10: netem delay 100ms
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dst 172.19.0.2/32 flowid 1:1
-- или --
tc qdisc add dev eth0 root handle 1: prio priomap 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
tc qdisc add dev eth0 parent 1:1 handle 10: netem delay 100ms
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dst 172.19.0.2/32 flowid 1:1
После их выполнения весь трафик блокируется - т.е. ничего не выходит, хост недоступен:
$ ping pingserver2
PING pingserver2 (172.19.0.4) 56(84) bytes of data.
From 14d25a894559 (172.19.0.3) icmp_seq=1 Destination Host Unreachable
From 14d25a894559 (172.19.0.3) icmp_seq=2 Destination Host Unreachable
$ ping pingserver
PING pingserver (172.19.0.2) 56(84) bytes of data.
From 14d25a894559 (172.19.0.3) icmp_seq=1 Destination Host Unreachable
From 14d25a894559 (172.19.0.3) icmp_seq=2 Destination Host Unreachable
Он делает это даже сразу после того, как я выполняю самую первую строку.
Кто-нибудь знает, что не так в моем подходе?
Я наконец-то понял. После тщательного изучения этот и этот главы Я гораздо лучше понимаю, как это должно работать и как tc
обрабатывает пакеты.
Итак, в основном, что мне нужно сделать, это построить такое дерево:
1: root qdisc
/ | \
/ | \
/ | \
1:1 1:2 1:3 classes
| | |
10: 20: 30: qdiscs qdiscs
netem sfq ---
band 0 1 2
Это означает, что помимо добавления netem
qdisc мне нужно было добавить sfq
ко второй полосе и добавьте фильтр для «всеобъемлющего» случая. Вот все команды, которые я использую:
tc qdisc add dev eth0 root handle 1: prio
tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip dst 172.19.0.2 match ip dport 6363 0xffff flowid 1:1
tc filter add dev eth0 protocol all parent 1: prio 2 u32 match ip dst 0.0.0.0/0 flowid 1:2
tc filter add dev eth0 protocol all parent 1: prio 2 u32 match ip protocol 1 0xff flowid 1:2
tc qdisc add dev eth0 parent 1:1 handle 10: netem delay 10ms
tc qdisc add dev eth0 parent 1:2 handle 20: sfq
Вот пояснения к каждой строке выше:
Добавить prio
дисциплина очереди к корню с дескриптором (id) 1:0
(0 не обязательно) на интерфейсе eth0
. prio
По умолчанию qdisc имеет три класса - 1: 1, 1: 2 и 1: 3. Этим классам будут назначены фильтры в следующих трех строках (порядок имеет значение!). Важно понимать, как обрабатываются исходящие пакеты - они попадают в дерево из корня и выйдите из него также из корня (не падают листья!).
Добавьте фильтр для трафика, который мы хотим замедлить (это трафик, 172.19.0.2
в порту 6363
в моем случае). Фильтр присоединяется к корневому узлу (parent 1:
) - значит, все исходящие пакеты будут проверяться этим фильтром. Фильтр проверяет ip и порт (ip dst ... ip dport ...
) и перенаправляет в класс 1:1
(flowid 1:1
).
Таким же образом, как и в предыдущем случае, устанавливается универсальный фильтр (спасибо, Почта), перенаправляет в класс 1:2
.
Точно так же этот фильтр является универсальным для пакетов ICMP (ping-пакетов), а также перенаправляет на 1:2
.
Прикреплять qdisc
к классу 1:1
, дайте ему ручку 10:0
и пусть будет netem
qdisc с задержкой 10мс.
Прикреплять sfq
qdisc в класс 1:2
- этот qdisc будет обрабатывать все остальные пакеты, которые соответствуют фильтру «уловителя», в режиме «стохастической справедливости».
Я настоятельно рекомендую прочитать те главы, на которые я давал ссылки, так как они многое проясняют и позволяют вам перестать отчаянно искать решение в поисковой системе и начать самостоятельное проектирование формирования сети.
Кроме того, я нашел эти команды чрезвычайно полезными для отладки / изучения:
tc -s qdisc ls dev eth0
tc -s filter ls dev eth0