Интерфейсный уровень и его представление
Долги за прошлую лекцию:
- работа со snapshot-ами в VBox
скрипт sethostname в виртуалке
Задачи интерфейсного уровня:
Подключение среды передачи данных к устройству (собственно интерфейс)
- Как отличить данные от не-данных (или начало от середины)?
- Метаинформация
- Дисциплина использования среды
- Очерёдность, коллизии, приоритеты и т. п.
- Защита данных и авторизация абонента
Инкапсуляция на аппаратном уровне (то, чего на интерфейсном уровне не видно):
- Заворачивание фрейма в маркеры начала и конца / межфреймовый заполнитель
- Избыточность при кодировании (борьба с шумом на аппаратном уровне: payload vs overhead)
Ethernet:
- в действительности 10101010*7 10101011, потому что старший бит октета — последний
Interpacket_gap (12 октетов) пропуска
Пример принципиально иной дисциплины доступа: Token Ring
Фреймы (пакеты интерфейсного уровня)
Сеть с разделением пакетов (окончательно)
Состав фрейма:
- Паспорт (ID отправителя и получателя, сведения о топологии, всякое)
- Полезная нагрузка
- Контрольная сумма (нужно ли больше избыточного кодирования?)
- Данные по шифрованию / авторизации
Ethernet
Общая среда ⇒
- ID отправителя и получателя (MAC: 3*8 VENDOR + 3*8 ID [+ 4*8 VLAN])
- Аппаратная фильтрация MAC
- promiscuous mode
- Широковещательный адрес
Алгоритм доступа: неодновременный
- определение коллизий (CD)
- определение идущей передачи (CSMA)
- определение работоспособности сети
- вычисление задержки для повторной передачи / общий тайм-аут
⇒ нет гарантированного времени доставки
Linux
ethtool — взаимодействие с аппаратным уровнем
iproute2 — основной инструмент настройки
ip link (поднятие, останов, свойства)
tcpdump — основной инструмент анализа
Link-level: tcpdump -e
Настройка внутренней сети в VBox
- Типы сетей в VB
- «Внутренняя» появляется просто по факту наименования — это общая среда
- «Втыкание провода» и «неразборчивый режим»
Название intnet — произвольное
Проверка работоспособности
2 клона (не забываем: другие MAC-адреса всем интерфейсам)
- Просмотр интерфейсов:
# ip link
- Активация («поднятие») интерфейса
# ip link set eth1 up
- На одной машине:
# tcpdump -XXe -i eth1
-XX означает выводить шестнадцатеричный дамп всего фрейма
На другой машине: # echo "08:00:27:ab:cd:ef 08:00:27:fe:dc:ba 8102 48 69" | xxd -r -p | socat - INTERFACE:eth1
08:00:27:ab:cd:ef — MAC-адрес получателя
08:00:27:fe:dc:ba — MAC-адрес отправителя
8102 — Тип содержимого (IP-пакет, но у нас он неправильный)
48 69 — «Hi»
xxd -r -p — вырезает из входного текста всё, кроме шестнадцатеричных цифр, остальное преобразует в байты (операция, противоположная шестнадцатеричному дампу)
socat - INTERFACE:eth1 — запихивает получившийся фрейм в интерфейс eth1
Минимальный размер фрейма — 64 октета (включая 4 октета контрольной суммы, которая формируется / проверяется аппаратно и не выводится).
Если вместо -XX написать -X, увидим только payload — «Hi».
Если запустить tcpdump с добавочным ключом -p, то:
- Не будет включён promiscuous mode ⇒ если поменять MAC получателя, фрейм не дойдёт
- Вариант: поставить широковещательного получателя ff:ff:ff:ff:ff:ff
- А вот MAC отправителя может быть любой ☺
Протоколы интерфейсного уровня
Вообще-то Тысячи их
Wi-Fi
Например, IEEE 802.11g
- Воздух: затухание и вариабельность сигнала ⇒ избыточность
- Совместный доступ:
- Несколько «каналов»
OFDM (FDM+ортогональность)
…
- Воздух общий ⇒ авторизация/шифрование
WIFI в Linux
(На всякий случай — в конце лекции) Взято отсюда. См. также
rfkill
ip link set wlan0 up
iw wlan0 scan
iw wlan0 link
(stty -echo; wpa_passphrase) > config
wpa_supplicant -B -i wlan0 -c config
iw wlan0 link
dhcpcd wlan0
Если успеем: TUN/TAP
Отступление о screen: как запустить два шелла в одной консоли:
«Горячая клавиша» Ctrl+A
Два сеанса:
Разбить одно горизонтально на два: Ctrl+A S (от «Split»)
Переключение между окнами: Ctrl+A Tab
Заведение нового сеанса Ctrl+A c (от «create»)
(переключение между сеансами Ctrl+A Ctrl+A)
- …
(tmux был бы лучше, но он требует glibc-locales, ждём lite сборки)
# socat TUN,up,tun-type=tap - | hexdump -C
интерфейс tap0
В этот интерфейс можно заслать фрейм
(TODO ip tuntap add tap0 mode tap и т. д. — упирается в /dev/net/tun: File descriptor in bad state, потому что требует указания, куда его цеплять, см тут )
ЧЕРНОВИК:
# ip tuntap add mode tap name tap # ip link set tap0 up # # TUNSETIFF — системный вызов, зависит от ядра # cat tap.py import struct import sys import fcntl import binascii IFNAMSIZ = 16 IFREQSIZ = 40 TUNSETIFF = 0x400454ca fformat = f"{IFNAMSIZ}sH{IFREQSIZ-2-IFNAMSIZ}s" sflags = """ #define IFF_TUN 0x0001 #define IFF_TAP 0x0002 #define IFF_NAPI 0x0010 #define IFF_NAPI_FRAGS 0x0020 #define IFF_NO_CARRIER 0x0040 #define IFF_NO_PI 0x1000 #define IFF_ONE_QUEUE 0x2000 #define IFF_VNET_HDR 0x4000 #define IFF_TUN_EXCL 0x8000 #define IFF_MULTI_QUEUE 0x0100 #define IFF_ATTACH_QUEUE 0x0200 #define IFF_DETACH_QUEUE 0x0400 #define IFF_PERSIST 0x0800 #define IFF_NOFILTER 0x1000 """.strip().split() fflags = {sflags[i+1]: int(sflags[i+2], 16) for i in range(0, len(sflags), 3)} ifname = sys.argv[1] if len(sys.argv) > 1 else "tap0" fd = open("/dev/net/tun", "rb") print(fflags) ifreq = struct.pack(fformat, ifname.encode(), fflags["IFF_TAP"], b'') print(binascii.hexlify(ifreq, ' ')) fcntl.ioctl(fd, TUNSETIFF, ifreq) while s := fd.read(128): print(s) # python3 tun.py # # На другом экране: # cal | socat - INTERFACE:tap0
Ещё один вариант (используется пропатченный ioctl из Сизифа):
# { echo "74 61 70 30 00 00 00 00 00 00 00 00 00 00 00 00 02 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" | xxd -r -p | ioctl 3 TUNSETIFF -s 40 ioctl 3 TUNGETIFF -s 40 | hexdump -C cal >&3 } 3> /dev/net/tun # # На другом экране: # tcpdump -XXe -i tap0
Д/З
Новый Образ
Добавлена утилита ioctl
В .bashrc добавлена индикация окон screen
Задание 2
Воспроизвести пример из лекции с двумя виртуалками, объединёнными внутренней сетью
- Настроить в самом virtualbox общую виртуальную сеть
- Сделать два клона (base и second) и настроить на обеих машинах «Адаптер 2» как подключённый к некоторой одинаковой сети
- Отчёты:
На базовой машине (report 2 base)
- Поднять сетевой интерфейс, к которому подключена виртуальная сеть
Запустить tcpdump -p -XX -c 2 на этот интерфейс; дождаться окончания
На дублёре (report 2 second)
- Поднять сетевой интерфейс, к которому подключена виртуальная сеть
Трижды сгенерировать и отправить фрейм с помощью xxd + socat по примеру из лекции (payload может быть любым не длиннее 40 символов)
- MAC отправителя и MAC получателя должны совпадать с актуальными
MAC получателя должен не совпадать с актуальным
MAC получателя должен совпадать с актуальным, а MAC отправителя — нет
Оба отчёта (report.02.base и report.02.second) именно с такими названиями переслать одним письмом в качестве приложений на uneexlectures@cs.msu.ru
В теме письма должно встречаться слово LinuxNetwork2024