Часто в работе сталкиваюсь с тем, что нужно понять, как функционирует та или иная сетевая система. Как правило, современные компьютерные системы объединены в сеть, и взаимодействие между узлами этой сети можно рассматривать через теоретическую призму модели OSI.
Много лет назад, когда я пытался разобраться в этом вопросе, думал так: сейчас прочитаю книгу, и сразу всё встанет на свои места. Но так не работает. Существует масса книг и статей, в которых описывается работа сетей — но без практики в ней не разобраться. Где же набраться опыта, поковыряться в протоколе, взглянуть на устройство конкретного протокола изнутри? Как изучать тему сетевого взаимодействия, если информационные блоки, которые циркулируют по сети и называются пакетами, фреймами, являются в некотором смысле “чёрными ящиками”, и разбирать их по байтам крайне долго? И я стал искать инструменты, которые могут эти чёрные ящики представить в виде, удобном для восприятия. В итоге нашёл несколько подходящих инструментов.
Цель этой статьи — поделиться с вами полезными инструментами для изучения сетевых протоколов. Не буду разбирать протоколы, цитировать книги и повторять их содержание, а рассмотрю несколько инструментов, которые могут быть крайне полезны для изучения сетей: scapy, tshark, ip, linux, docker, docker-compose.
Для начала необходимо скачать тестовый репозиторий:
git clone git@github.com:yvv4git/exp-scapy.git
По ряду причин название интерфейсов или другая информация может отличаться. Так что следует использовать стандартные команды linux, которые позволяют узнать, какие есть интерфейсы в системе. Команда для запуска тестовой среды:
make start
Чтобы завершить работу тестового окружения, можно воспользоваться командой:
make stop
Протокол ARP
Начнём с одного очень популярного протокола канального уровня — ARP. Базовое назначение ARP протокола: компьютер А отправляет широковещательный запрос всем компьютерам в текущем широковещательном домене. Этот запрос получают все компьютеры в домене. Но отвечает на него тот компьютер, чей mac адрес соответствует указанному в ARP запросе ip адресу. И только один компьютер, которому принадлежит указанный в запросе ip адрес, отвечает. В ответе он указывает свой mac адрес. Эта информация сохраняется в ARP таблицах всех устройств в сети. Есть обратный запрос, но суть этой статьи не в описании протокола, а в том, чтобы продемонстрировать инструменты, которые можно использовать для изучения данного протокола.
Для начала проверим, какие есть сетевые интерфейсы:
cat /proc/net/dev
Нас интересует интерфейс eth0, т.к. наши машины scapy и target находятся в одной сети, в одном широковещательном домене.
Теперь воспользуемся двумя инструментами: scapy, tshark.Потребуется в первом терминале выполнить make start, чтобы поднять docker машины и попасть в консоль scapy. Во втором терминале необходимо зайти в target машину и запустить в ней sniffer:
docker exec -it exp-target bash
tshark -i eth0 -Y icmp
Поясню, что здесь происходит. В левой панели с хоста scapy мы отправляем ARP запрос, а в правой панели мы запускаем сетевой sniffer и слушаем эфир.
Этот пример наглядно демонстрирует огромные возможности scapy для создания пакетов. Кроме того, данный пакет позволяет наглядно изучить структуру, поиграть с полями, написать тесты и подтвердить гипотезы.
Протокол ICMP
Теперь поднимемся на сетевой уровень. Третий уровень нужен для того, чтобы “маршрутизировать” пакеты из одной сети в другую. Проведём практический эксперимент — отправим ICMP запрос c машины scapy на target. Для этого нужно запустить python скрипт icmp_send_simple.py. Во втором терминале потребуется войти на хосте target и запустить sniffer:
docker exec -it exp-target bash
tshark -i eth0 -Y icmp
В примере отчётливо видна структура ICMP пакетов. В правом терминале на хосте target запущен sniffer, который позволяет проверить факт получения ICMP пакетов.
Для того, чтобы продемонстрировать больше возможностей чудесного пакета scapy, попробуем добавить некоторый payload к ICMP пакету(icmp_send_payload.py).
Кстати, указанную возможность можно использовать для управления серверами, у которых были закрыты все порты из соображений безопасности, но тем не менее они получали ICMP на уровне ядра системы. Конечно же, тут нужна система авторизации — и это отдельная серьёзная тема. В данном случае я лишь демонстрирую очень удобный инструмент.
Протокол DNS
Про этот протокол все слышали или хотя бы где-то с ним сталкивались, даже не осознавая этого. Например, когда мы вводим имя хоста в браузере. Благодаря данному протоколу система узнает, с каким IP адресом необходимо работать по имени хоста. В протоколе DNS есть некоторое количество ресурсных записей. Я бы хотел отметить следующие:
- A — это запись о соответствии имени хоста IPv4 адресу.
- AAAA — то же самое, но для IPv6. MX — адрес почтового шлюза. Важное поле для функционирования почты.
- NS — адрес узла, который отвечает за доменную зону, т.е. DNS сервер.
- PTR — имя, которое соответствует заданному IP адресу. Это как A запись, только наоборот.
Больше информации можно взять из спецификации, книг и статей. Моя цель — показать, как можно поиграть с этим протоколом, и какие есть для этого инструменты. Для этого воспользуемся scapy.
Порядок действий:
- Запустить необходимое окружение:
make start
- Внутри контейнера воспользоваться готовой программой:
dns_send_simple.py../dns_send_simple.py
В результате получим следующий ответ:
Кроме того, с помощью scapy можно манипулировать различными полями протокола DNS, инкапсулировать свои данные и вообще получить полный контроль над структурой пакетов. И всё это — удобным для восприятия способом.
Заключение
Я рассмотрел несколько инструментов, которые можно использовать для получения практических навыков и более эффективного закрепления теоретического материала по сетям. Несмотря на то, что scapy охватывает огромное количество протоколов, есть возможность добавлять свои собственные. Это очень мощный инструмент для начинающих специалистов и для профессионалов разных направлений. На мой взгляд, данный инструмент особенно полезен специалистам по сетям, информационной безопасности, системным администраторам и разработчикам.