Формирование трафика и нетабличная маршрутизация
Заметим, что в этой лекции разговор идёт сразу о двух уровнях TCP/IP — сетевом и транспортном. В действительности нет больших проблем в том, чтобы, например, на уровне IP вполне можно заглянуть в TCP-сегмент и найти там порт, а на уровне TCP — выставить поле «тип обслуживания» (ToS) в IP пакетах на уровне сознания сокета.
Целевая маршрутизация
Ранее мы работали с destination-based принципом табличной маршрутизации: «сеть получателя ⇒ маршрут».
Задача source-based маршрутизации: «свойства пакета отправителя ⇒ маршрут».
Linux: просто заведём несколько таблиц маршрутизации (разных), и будем обрабатывать пакет по правилам одной из них сообразно его свойствам:
- Адрес отправителя
- Порт получателя (или отправителя)
- Интерфейс, протокол и т. п. …
Команда ip -6 rule (немного документации)
Заготовка:
Два компьютера; у каждого выход на третий: mid1 — out — mid2
Маршрутизатор router, подключённый к этим двум машинам по отдельным интерфейсам и третьей сетью для внутренних клиентов
Пример 1: подключаем два клиента ко внутренней сети, настраиваем source routing: с одного адреса пакеты в одну сторону, с другого — в другую
[root@router ~]# ip -6 route add default второй_сервер table какой-то-номер [root@router ~]# ip -6 rule add from «IP_B» table какой-то-номер
Пример 2: подключаем один клиент, перекидываем трафик по 80/443 портам в другую сторону
# ip -6 route add default второй_сервер table какой-то-номер [root@router ~]# ip -6 rule add dport 80 table какой-то-номер
Получаем такую настройку:
1 [root@router ~]# ip -6 rule list
2 0: from all lookup local
3 32765: from all dport 80 lookup какой-то-номер
4 32766: from all lookup main
5 [root@router ~]# ip -6 route list
6 default via Сервер1 dev eth1
7 …
8 [root@router ~]# ip -6 route list table какой-то-номер
9 default via Сервер2 dev eth2
10
Правила в ip rule
- Просматриваются в порядке увеличения номера (приоритет 0 — наивысший)
Правило lookup приводит к поиску в соответствующей таблице
- Если этот поиск удачен, происходит маршрутизация
Например, правило с наивысшим приоритетом «0: from all lookup local» приводит к поиску в таблице local (посмотрите на неё), отражающей подключённые локальные сети. Если адрес не из локальной сети, lookup local ничего не находит,
Если правило lookup не нашло маршрута, поиск продолжается дальше
Приоритет правила можно задавать вручную, добавив в конце priority номер
Основная таблица — main, именно её показывает ip route (т. е. ip route list table main)
Разумеется, в обоих примерах на серверах надо дополнительно настраивать маршрут в клиентскую сеть через центральный маршрутизатор.
Введение в обработку трафика
Эта тема на целый семестр! Поэтому про главную задачу — traffic shaping — только упомянем.
Задача: если сетевое устройство пересылает несколько потоков данных, надо обеспечить:
- «Справедливое» разделение трафика между абонентами (в т. ч. сообразно приоритетам)
- Работоспособность при перегрузках
Базовая статья: Traffic Control HOWTO
Как всегда Арчевики
Общая идея: маршрутизируемые пакеты нельзя просто перекладывать по одному
∃ серьёзная вероятность, что прямо сейчас принятый пакет отсылать нельзя (занято etc.)
- ⇒ буферизация (очередь)
- Приоритизация трафика
- ⇒ Выделение потоков (TCP)
⇒ IPv6: Метки потоков в основном заголовке
- Например, SSH с быстрыми командами vs HTTP с большими объёмами
Кстати: SSH / SFTP и ToS 0x48 / 0x00 0xb8 / 0x20
Различные дисциплины (по длине очереди, по времени ожидания и т. п.)
Деревья очередей и фильтры для ветвления
Проблема: Bufferbloat
Дисциплина по умолчанию: tc-fq_codel:
CoDel (анти-буферблоат: 5ms в очереди + выбрасывание пакетов из «плохих» очередей) + Fair_queuing (равномерное распределение пропускной способности по потокам данных)
Умеет Explicit_Congestion_Notification вместо Random_early_detection
Пример: дисциплина Network Emulator
Статья (не всё работает так, как написано)
- Удобно использовать на тест-стендах в курсах по сетям!
Потестируем её с помощью «flood ping» (безудержной отправки ping-ов с максимальной скоростью)
Топология: client — mid — srv
Исходное состояние (используем mid):
# tc -col qdisc show # tc -s qdisc show # ping -f -c1000 2001:db8:0:1::1b
Дисциплина по умолчанию CoDel
Медленная сеть:
# tc qdisc add dev eth1 root netem delay 400ms # tc qdisc show # ping -f -c100 2001:db8:0:1::1b
- Должна выстроиться стопка из отправленных, но ещё не отвеченных пакетов
Плохая сеть, в которой пакеты пропадают:
# tc qdisc del root dev eth1 # tc qdisc add dev eth1 root netem loss 10% # tc qdisc show # ping -f -c500 2001:db8:0:1::1b
- Не забудем сначала удалить старую дисциплину
- К. О. рапортует: пакеты пропали
Очень плохая сеть, и медленная, и пакеты портятся:
# tc qdisc del root dev eth1 # tc qdisc add dev eth1 root netem delay 400ms corrupt 5% # tc qdisc show # ping -f -c500 2001:db8:0:1::1b
Немного про shape:
Шейпить имеет смысл только исходящий трафик, потому что входящий уже получен ☺
- (на самом деле не только, но use case всё равно непростой)
Простейшая дисциплина — Token Bucket Filter
- Очередь пакетов → выдача «жетонов» из «ведра» → отсылка пакета с «жетоном»
По объёму: tbf limit объём_очереди burst ёмкость_ведра rate пропускная_способность
По времени ожидания tbf latency сколько_ждать burst ёмкость_ведра rate пропускная_способность
- Классовая очередь (дерево) — на каждый поток своя труба + общий слив
Простая приоритизация по ToS
Hierarchy Token Bucket с произвольной топологией (учебник)
Будем исследовать пропускную способность с помощью IPerf
На втором абоненте запустим iperf3 -6s (серверная часть, только IPv6)
На исследуемой машине будем настраивать дисциплину и запускать iperf3 -6c
Исходная ситуация (эмулятор гигабитной сетевой карты):
# tc qdisc del root dev eth1 # iperf3 -t5 -6c 2001:db8:0:1::1b
Понизим пропускную способность до мегабита в секунду:
# tc qdisc add dev eth1 root tbf rate 1mbit burst 32kbit latency 400ms # tc qdisc show # iperf3 -t5 -6c 2001:db8:0:1::1b
TODO НЕ исключено, что теперь время на это есть
К сожалению, наиболее популярную дисциплину — HTB — рассмотреть не успеем. Тема большая.
Д/З
Образ не изменился
Задание 7
- Суть: построить сеть с выбором маршрута между быстрым каналом и каналом с задержкой на интерфейсе.
- Площадка (сетевые адреса и маршруты настроены заранее, в отчёт не входят)
client: просто работает, подключен к router
router: имеет ещё два интерфейса к маршрутизаторам normal и delayed
normal: просто маршрутизирует между router и out
delayed: просто маршрутизирует между router и out, но обе эти сети медленные (симулируем при помощи qdisc netem)
srv: тоже связан с normal и delayed
- Отчёт:
report 7 router
Узнать, какое значение поля Traffic Class использует ssh (подсмотреть в исходящих пакетах, или в выводе strace)
Настроить целевую маршрутизацию трафика с этим значением traffic class в сторону normal, а остального трафика в сторону delayed
Запустить tcpdump на интерфейсе в сторону delayed, который отловит пакеты TCP-соединения от client на srv и несколько пакетов ping-а, а затем сам остановится (-c <число>). Если сложно — просто остановите перед продолжением отчёта.
Запустить tcpdump на интерфейсе в сторону simple, который отловит пакеты TCP-соединения от client на srv, а затем сам остановится (-c <число>). Если сложно — просто остановите перед продолжением отчёта.
report 7 srv
- Принять одно TCP-соединение на порт 80
report 7 delayed
Настроить (с помощью netem) задержку при отсылке пакетов в 200ms на оба интерфейса
Немного по ping-ать srv (чтобы запущенный там tcpdump остановился)
report 7 client
Зайти по SSH на машину srv, выйти (дать команду exit)
Отправить при помощи netcat несколько строк на порт 22 машины srv
Запустить ping адреса delayed (в отчёте должна быть видна задержка ⩾ 200ms)
Четыре отчёта (названия сохранить, должно быть: report.07.client, report.07.router, report.07.delayed, report.07.srv) переслать одним письмом в качестве приложений на uneexlectures@cs.msu.ru
В теме письма должно встречаться слово LinuxNetwork2026
