Транспортный уровень: трансляция адресов и формирование трафика
Ещё про VirtualBox
socat -,cfmakeraw,echo=0,escape=15 TCP4:localhost:порт
- — то же, что и STDIO:
cfmakeraw — raw режим (с control flow)
echo=0 — не отображать символы сразу при вводе
escape=15 — символ с кодом 15 (Ctrl+O) закрывает ввод
… socat
VBoxManage:
modifyvm
clonevm
startvm
controlvm … acpipowerbutton
unregistervm … --delete
Всё это умеют сценарии из лекций
- Соответствующая команда выводится на экран
NAT
Network address translation — что такое и зачем нужно.
NAT без транспортного уровня
Идея замены конкретного IP другим конкретным IP (и обратно) — например, если «внутренний» IP из интернет-диапазона.
- Работает только 1:1
( actually, не работает)
Проблемы:
Любые контрольные суммы некорректны, если в них входит IP (надо пересчитывать)
- Нет информации для подмены «много → один»
- Давно выбросили ☺
NAT с идентификацией потока (NAPT)
Динамическая подмена IP на основании «состояния»
- Таблица: пара IP + идентификатор «состояния»
- Может работать N:1, M:N
- Destination NAT (например, для отдельного веб-сервера)
- Идентификаторы — всё, что можно извлечь из пакетов
- TCP: 2 порта + 2 IP (+ initial SeqN?)
- DNS (UDP): DNS Query ID (поле прикладного уровня!) + 2 порта + 2 IP
- NTP (UDP): Originator Timestamp (поле прикладного уровня!) + 2 порта + 2 IP
- ping: ICMP-serial (поле сетевого уровня) + IP
- …
- Проблема коллизий SEQN / портов / идентификаторов в вариантах N/1 и M/N:
- Два хоста (A и B идут на один и тот же порт хоста C через NAT):
- У них могут совпасть порты отправителя:
- A:1234 → C:80; B:1234 → C:80
=> коллизия
- Оок, введём в идентификатор ещё seqn:
- A:1234, seqn 4321 → C:80; B:1234, seqn 34234 → C:80
=> вероятность коллизии?
Примеры SNAT и DNAT
SNAT — при отсылке «наружу» (например, из intranet-диапазона)
- Кстати, MASQUERADE — это на случай динамического IP, при формировании conntrack-а всякий IP раз запрашивается у интерфейса
DNAT — при приёме (например, межсетевой экран на одной машине, а веб-сервер — внутри сети, на другой)
- Т. н. «проброс портов» — подключение к манише по попределённому порту «пробрасывается» на другую машину (можно поменять номер порта тоже):
# iptables -t nat -A PREROUTING -i интерфейс -p tcp --dport порт -j DNAT --to-destination внутренний_адрес
- Т. н. «проброс портов» — подключение к манише по попределённому порту «пробрасывается» на другую машину (можно поменять номер порта тоже):
- Работа с iptables (только введение, изучать будем NFTables)
/proc/net/nf_conntrack и утилита conntrack
Syn flood атака и SYNPROXY
- Суть: на каждый SYN в ядре выделяется приличная структурка. Можно заDOS-ить большим потоком безответственных SYN-ов.
- Решение: разделить МЭ и сервер, и до сервера доносить только «хорошие» SYN-ы, точнее — SYN-SYNACK-ACK-и всей пачкой (частичное проксирование)
- Требует более сложной логики
- Требует подмены SEQN (потому что мы всё ещё не знаем, какую SEQN выберет сервер, но уже «проиграли» для него 3WH)
Введение в обработку трафика
Эта тема на целый семестр! Поэтому про главную задачу — traffic shaping — только упомянем.
TODO
Базовая статья: Traffic Control HOWTO
Как всегда Арчевики
Общая идея: маршрутизируемые пакеты нельзя просто перекладывать по одному
∃ серьёзная вероятность, что прямо сейчас принятый пакет отсылать нельзя (занято etc.)
- ⇒ буферизация (очередь)
- Приоритизация трафика
- ⇒ Выделение потоков (TCP)
- Например, SSH vs HTTP
- Кстати: SSH / SCP и ToS 0x48 / 0x00
Различные дисциплины (по длине очереди, по времени ожидания и т. п.)
Деревья очередей и фильтры для ветвления
Проблема: Bufferbloat
Дисциплина по умолчанию: fq_codel:
CoDel (анти-буферблоат: 5ms в очереди + выбрасывание пакетов из «плохих» очередей) + Fair_queuing (равномерное распределение пропускной способности по потокам данных)
Умеет Explicit_Congestion_Notification вместо Random_early_detection
Пример: дисциплина Network Emulator
Конспект:
# tc qdisc show # tc -s qdisc show # ping -f -c1000 10.1.1.2 # tc qdisc add dev eth1 root netem delay 400ms # ping -f -c100 10.1.1.2 # tc qdisc del root dev eth1 # tc qdisc add dev eth1 root netem loss 10% # ping -f -c500 10.1.1.2 # tc qdisc del root dev eth1 # tc qdisc add dev eth1 root netem delay 400ms corrupt 5% # ping -f -c100 10.1.1.2
Немного про shape:
Шейпить имеет смысл только исходящий трафик, потому что входящий уже получен ☺
- (на самом деле не только, но use case всё равно непростой)
Простейшая дисциплина — Token Bucket Filter
- Очередь пакетов → выдача «жетонов» из «ведра» → отсылка пакета с «жетоном»
По объёму: tbf limit объём_очереди burst ёмкость_ведра rate пропускная_способность
По времени ожидания tbf latency сколько_ждать burst ёмкость_ведра rate пропускная_способность
- Классовая очередь (дерево) — на каждый поток своя труба + общий слив
Простая приоритизация по ToS
Hierarchy Token Bucket с произвольной топологией (учебник)
На srv запустим iperf3 -4s
Конспект про tbf:
# tc qdisc del root dev eth1 # iperf3 -4c 10.1.1.2 # tc qdisc add dev eth1 root tbf rate 1mbit burst 32kbit latency 400ms # iperf3 -4c 10.1.1.2
TODO Если успеем: про фильтры и про HTB (по примеру в учебнике) или в Арчевики
Д/З
Новое в образе: обновление пакетной базы и ядра; добавлен iperf3
Задание 7
- Суть: воспроизвести примеры из лекции, с выходным NAT-ом, пробросом порта и задержкой на интерфейсе.
- Площадка (сетевые адреса и маршруты настроены заранее, в отчёт не входят)
A — адрес shaped
B — адрес client
R — «внешний» (для доступа из sev) адрес router
- Отчёт:
report 7 router
Настроить исходящий NAT на интерфейсе R, который работал бы для A и B (Например, для всей их сети)
Настроить проброс порта 1234 при подключении к R → на порт 1234 адреса B
Запустить tcpdump на «внешнем» интерфейсе, который отловит все пакеты TCP-соединений и несколько пакетов ping-а, а затем сам остановится (ключ -c). Если сложно — просто остановите перед концом отчёта.
report 7 client
- Принять одно TCP-соединение на порт 1234
report 7 shaped
Настроить (с помощью netem) задержку при отсылке пакетов в 200ms
report 7 srv
Принять одно TCP-соединение на порт 1212 (в tcpdump на router-е должно быть видно, что это соединение от R, потому что SNAT)
report 7 client
Отправить несколько строк на порт 1212 машины srv
Запустить ping адреса A (в отчёте должна быть видна задержка ⩾ 200ms)
(продолжение отчёта srv)
Отправить несколько строк на порт 1234 адреса R (его должен принять B, потому что DNAT)
Четыре отчёта (названия сохранить, должно быть: report.07.router, report.07.srv, report.07.client, report.07.shaped) переслать одним письмом в качестве приложений на uneexlectures@cs.msu.ru