Мониторинг сети с помощью tcpdump

Довольно часто встает проблема, когда ему нужно узнать как работает сеть. Или просто для учебных-исследовательских целей узнать как взаимодействуют между собой объекты сети. Для этих целей в UNIX-мире написано целая куча инструментов. В данном материале будет рассматриваться один из них: tcpdump.

Итак, tcpdump.

$ man tcpdump, нам гласит

Tcpdump выводит заголовки пакетов проходящих через сетевой интерфейс, которые совпадают с булевым выражением. Он может также быть запущен с ключем -w, который заставляет сохранять данные пактов в файл для дальнейшего исследования, и/или с ключем -r, который заставляет читать сохраненные пакеты из файла, вместо чтения пакетов из сетевого интерфейса. В любом случае, tcpdump будут обработаны только те пакеты, которые совпадают с выражением.

Tcpdump будет, если не запущен с ключем -c, продолжать собирать пакеты до тех пор, пока не будет прерван сигналом SIGINT (генерируемым, для примера, вводом Вашего символа прерывания, обычно CTRL+C) или сигналом SIGTERM (обычно генерируемого командой kill). Если запуск был с ключем -c, то сбор пакетов будет продолжаться до тех пор, пока не произойдет прерывание сигналом SIGINT или SIGTERM или пока не будет обработано определенное количество пакетов.

Когда tcpdump закончит сбор пакетов, то будет сообщено об количестве:

Это был перевод - исправления приветствуются.

Дальше идет описание ключей. Вот некоторые из них:

Теперь, рассмотрим фильтрующее выражение.
Оно выбирает какие пакеты будут выбираться из общего потока. Если оно не указано, то будут выбираться и выводится все пакеты идущие через интерфейс. Иначе, будут обработаны только те пакеты, для которых проверка с выражением выдаст значение "истина" (true).

Выражение состоит из одного или более примитивов. Примитивы обычно состоят из ID (имя или номер) следующего за одним или более классификаторами. Различают три вида классификаторов:

В добавок, существует несколько специальных примитивов - ключевых слов: gateway, broadcast, less, greater и арифметические выражения.

Более сложные фильтрующие выражения могут быть построены с помощью слов and, or и not, объединяющих примитивы. Пример, 'host foo and not port ftp and not port ftp-data'. Чтобы уменьшить количество вводимой информации, идентичные списки классификаторов могут быть опущены. Пример, 'tcp dst port ftp or ftp-data or domain' это тоже самое, что и 'tcp dst port ftp or tcp dst port ftp-data or tcp dst port domain'

Перечислим некоторые из допустимых примитивов (за более полным списком в man tcpdump):

dst host host

src host host

host host

net net mask netmask

net net/len

dst port port

src port port

port port

less length

greater length

ip proto protocol

Прежде чем переходит к примерам рассмотрим, что может нам выдать tcpdump при выполнении.
Типичные результаты работы tcpdump -ttt:

1. 000107 192.168.2.13 > 192.168.2.254: icmp: 192.168.2.13 udp port 3631 unreachable
2. 000313 192.168.2.254.53 > 192.168.2.13.3656:  4 ServFail 0/0/0 (22) (DF)
3. 000287 192.168.2.254 > 192.168.2.100: icmp: net 205.188.179.233 unreachable [tos 0xc0]
4. 010956 192.168.2.254.139 > 192.168.2.13.3661: P 1:5(4) ack 73 win 5840 NBT Packet (DF)
5. 276274 192.168.2.150.3053 > 192.168.2.254.53:  7+ A? Tatyana.karavay-shops.ru. (42)
6. 001162 192.168.2.100.32772 > 192.168.2.254.16007: . ack 73 win 5840 (DF)


Первое поле - поле времени, т. к. запуск осуществлялся с ключом "-ttt", то это разница в микросекундах между этим пакетом и предыдущим.
Потом идет IP-адрес (или имя) отправителя пакета, через точку может указываться порт. После знака ">", указывается получатель пакета (или его имя) и также порт. Затем будет идти либо сразу служебная информация идущая в пакете, либо протокол (у нас это icmp). В служебной информации может быть указано либо состояние флагов в пакете, либо расшифрованная информация ("192.168.2.13 udp port 3631 unreachable" или DNS-запрос об хосте "Tatyana.karavay-shops.ru").

Ну а теперь пора взяться за конкретные примеры.

1. Ловим весь входящий трафик из локальной сети на сервер. Здесь все просто.

# /usr/sbin/tcpdump -i eth0 -n -nn -ttt dst host 192.168.2.254

Если вы запускаете его в SSH сессии, то подготовьтесь - польется очень много и очень быстро...

2. Ловим весь входящий трафик, исключая трафик генерируемый нашей SSH-сессией.

# /usr/sbin/tcpdump -i eth0 -n -nn -ttt 'dst host 192.168.2.254 and not ( src host 192.168.2.100 and dst port 22 )'

Вот теперь в потоке пакетов можно разобраться.

3. Нужна информация об DNS-общении между сервером и каким-нибудь узлом сети.

# /usr/sbin/tcpdump -i eth0 -n -nn -ttt 'host 192.168.2.13 and ip proto \udp'

Здесь, кстати будет бегать не только DNS-трафик. А вообще весь, который идет по UDP. Исправить это можно следующим:

# /usr/sbin/tcpdump -i eth0 -n -nn -ttt 'host 192.168.2.13 and port 53'

4. Отлавливаем исключительно icmp пакеты.

# /usr/sbin/tcpdump -i eth0 -n -nn -ttt 'ip proto \icmp'

Вот. Теперь все.
Не забывайте, что более подробную информацию можно получить из man tcpdump. Там же можно прочитать об структуре пакетов основных протоколов, что позволит еще глубже исследовать Ваши сети.

Источник linuxcenter.ru