Как пользоваться tcpdump
Утилита tcpdump — это очень мощный и популярный инструмент для перехвата и анализа сетевых пакетов. Она позволяет просматривать все входящие и исходящие из определенного интерфейса пакеты и работает в командной строке. Конечно, вы могли бы пользоваться Wirshark для анализа сетевых пакетов, это графическая утилита, но иногда бывают ситуации когда нужно работать только в терминале.
Tcpdump ничем не хуже Wireshark, и имеет все необходимые возможности для анализа пакетов, к тому же вы можете сохранить все перехваченные пакеты в файл, чтобы анализировать их потом с помощью того же самого Wireshark. В этой статье мы рассмотрим как пользоваться tcpdump для перехвата сетевых пакетов.
Установка tcpdump
Во многих дистрибутивах команда tcpdump поставляется по умолчанию, но если в вашем дистрибутиве ее нет, то вы можете очень просто ее установить из официальных репозиториев. Например, в Ubuntu/Debian:
sudo apt install tcpdum p
Когда установка завершится, вы можете переходить к работе.
Команда tcpdump
Перед тем как перейти к примерам работы с утилитой, давайте рассмотрим ее синтаксис и основные опции. Команда имеет такой синтаксис:
$ tcpdump опции -i интерфейс фильтры
При вызове обязательно нужно передать интерфейс, который будете отслеживать. Если интерфейс не указать, то будет использован первый в списке. Опции настраивают отображение и основные возможности утилиты, а фильтры позволяют отсеять ненужные пакеты. А теперь рассмотрим основные опции:
- -A — выводить все пакеты в формате ASCII;
- -c — закрыть программу после перехвата n-ого количества пакетов;
- -C — при записи пакетов в файл, проверять размер файла, и если он больше заданного — создать новый файл;
- -D — вывести список доступных сетевых интерфейсов;
- -e — выводить информацию уровня соединения для каждого пакета, это может быть полезно, например, для отображения MAC адреса;
- -f — выводить доменное имя для ip адресов;
- -F — читать пакеты из файла, а не интерфейса;
- -G — создавать новый файл лога через указанный промежуток времени;
- -H — обнаруживать заголовки 802.11s;
- -i — имя интерфейса для перехвата пакетов. Вы можете захватывать пакеты со всех интерфейсов, для этого укажите any;
- -I — переключить интерфейс в режим монитора для захвата всех проходящих пакетов;
- -j — установить формат Timestamp для записи пакетов;
- -J — посмотреть доступные Timestamp;
- -K — не проверять контрольные суммы пакетов;
- -l — добавить поддержку прокрутки к выводу;
- -L — вывести поддерживаемые протоколы подключения для интерфейса;
- -n — не отображать доменные имена;
- -r — прочитать пакеты из файла, созданного с помощью -w;
- -v, -vv, -vvv — более подробный вывод;
- -q — выводить минимум информации;
- -w — записать вывод в файл;
- -Z — пользователь, от имени которого будут создаваться файлы.
Это не все опции, но их вам будет вполне достаточно для решения большинства задач. Чаще мы будем применять фильтры. С помощью фильтров вы можете отсеивать только те типы пакетов, которые хотите видеть. Вы можете фильтровать по ip адресу, протоколу, сети, интерфейсу и многим другим параметрам. Но фильтры tcpdump мы будем рассматривать уже на примерах.
Как пользоваться tcpdump
Перед тем как перейти к использованию tcpdump нужно посмотреть какие сетевые интерфейсы вы можете использовать. Для этого запустите команду с опцией -D:
Начнем рассматривать примеры tcpdump с захвата трафика на интерфейсе eth0, у меня это основной интерфейс, который подключен к интернету. Для работы программе необходимы права суперпользователя, поэтому не забудьте указать sudo:
Чтобы остановить работу команды нажмите Ctrl+C. В выводе вы сразу же увидите все перехваченные пакеты. Формат записи для каждого пакета будет выглядеть следующим образом:
13:03:41.795599 IP udp032919uds.hawaiiantel.net.6881 > 192.168.1.2.52055 : Flags [.], seq 640160396:640161844, ack 436677393, win 2050, options [nop,nop,TS val 3805626438 ecr 4677385], length 1448
Такой формат характерен для пакетов данных, в зависимости от протокола выделенный черным текст будет отличаться. Сначала идет временная метка, затем протокол, далее зеленым отмечен ip адрес отправителя, а синим адрес адресата, в данном случае, нашего компьютера. Дальше идут дополнительные параметры tcp и в конце размер пакета в байтах. Подробность вывода информации можно контролировать с помощью опций -v, Например:
Здесь уже появляется информация о протоколе IP:
IP (tos 0x0, ttl 64 , id 50309, offset 0, flags [DF], proto TCP (6) , length 64)
Мы можем узнать информацию о времени жизни пакета ttl, версию протокола TCP и длину поля заголовка. Опция -vv будет выводить проверку контрольных сумм пакета и содержимое в некоторых случаях.
После опций вы можете указывать фильтры для пакетов. Вот основные параметры, по которым можно отсеивать пакеты:
- host — имя хоста;
- ip — ip адрес;
- proto — протокол;
- net — адрес сети или подсети;
- port — адрес порта;
- src — параметр, касающийся отправителя;
- dst — параметр, касающейся получателя;
- Доступны такие протоколы: ether, fddi, tr, wlan, ip, ip6, arp, rarp, decnet, tcp и udp.
Вы можете все это комбинировать между собой, чтобы получить желаемый результат. Рассмотрим более детально на примерах. Отсеем только пакеты, адресованные нашему компьютеру:
sudo tcpdump -i eth0 ip dst 192.168.1.2
Также мы можем отобрать пакеты, отправляемые на определенный узел:
sudo tcpdump -i eth0 dst host google-public-dns-a.google.com
Как видите, это DNS пакеты и здесь вместо флагов TCP содержится полезная информация, запрос ip адреса хоста. Также вы можете выбрать ответные пакеты от определенного хоста:
sudo tcpdump -i eth0 src host google-public-dns-a.google.com
Здесь нет полного содержимого пакета, если вы хотите его получить нужно использовать опцию -v или -vv:
sudo tcpdump -vv -i eth0 host dst google-public-dns-a.google.com
С помощью оператора and вы можете объединить несколько фильтров в один:
sudo tcpdump -i eth0 dst host google-public-dns-a.google.com and src host google-public-dns-a.google.com
Из операций объедения доступны and и or, также можно применять скобки для обозначения приоритета. Вам необязательно указывать host, во многих случаях достаточно src или dst, утилита сама поймет что имелось в виду. Точно такую же конструкцию можно использовать для портов. Например, мы можем отсеять все запросы или ответы к DNS (на порт 53):
sudo tcpdump -vv -i eth0 port 53
Точно такое же можно провернуть для http (порт 80):
sudo tcpdump -vv -i eth0 port 80
Естественно, тут тоже можно применять dst и src для более конкретных результатов. Вы можете фильтровать не один порт, а целый диапазон портов:
sudo tcpdump portrange 21-23
Если указать один из протоколов, вы отфильтруете только пакеты этого протокола, например tcp, udp или arp:
Точно также можно выбрать все udp пакеты:
Также доступен фильтр по обозначению сети:
sudo tcpdump net 129.168.1.1/24
Кроме того, вы можете фильтровать пакеты по их размеру, например, меньше 32 байт:
Иногда бывает необходимо сохранить захваченный трафик в файл, для этого используется опция -w:
sudo tcpdump -i eth0 -w file.pcap
Этот файл можно открыть с помощью любой программы для чтения таких файлов, например, Wireshark. Чтобы открыть сохраненные в файл пакеты используйте опцию -r:
Остался еще один момент, на который стоит обратить внимание. Это формат отображения содержимого пакетов. Вы можете вывести содержимое пакета в формате ASCII используйте опцию -A:
Также вы можете отобразить содержимое в формате HEX и ASCII для этого используйте -XX:
Выводы
В этой статье мы рассмотрели как пользоваться tcpdump. Это очень мощный сетевой анализатор, который работает только через командную строку. Надеюсь, эта информация была полезной для вас и теперь использование tcpdump будет намного проще, если у вас остались вопросы, спрашивайте в комментариях!
На завершение видео с лекцией о tcpdump:
Обнаружили ошибку в тексте? Сообщите мне об этом. Выделите текст с ошибкой и нажмите Ctrl+Enter.
How can I have tcpdump write to file and standard output the appropriate data? [closed]
Closed. This question is not about programming or software development. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
I want to have tcpdump write raw packet data into a file and also display packet analysis into standard output as the packets are captured (by analysis I mean the lines it displays normally when -w is missing). Can anybody please tell me how to do that?
5 Answers 5
Here’s a neat way to do what you want:
tcpdump -w - -U | tee somefile | tcpdump -r -
- -w — tells tcpdump to write binary data to stdout
- -U tells tcpdump to write each packet to stdout as it is received, rather than buffering them and outputting in chunks
- tee writes that binary data to a file AND to its own stdout
- -r — tells the second tcpdump to get its data from its stdin
Using this technic, WireShark has complained of some of the files claiming that the last packet is incomplete. I guess tcpdump would unbuffer and write all data before ending, but, in case it doesn’t, -U option may be useful here. From the man page: ` Use the -U flag to cause packets to be written as soon as they are received.`. (trying not to lose any buffered/still-not-written-to-file packet when tcpdump is killed). I haven’t had a change to confirm that, though.
@deppfx That would work, at the cost of only saving the text. -w causes tcpdump to write the data in the standard binary format.
@cnicutar This is genius. I like it. I’m using with options -U for packet buffered for printing per packet, -n for not converting IP addresses and ports to names. After modifications my command is tcpdump
@sdkks that was brilliant! tcpdump -i eth0 port 22 and not host 172.30.247.4 -U -w — | tee capture.pcap |tcpdump -r — God Bless stackoverflow!
Since tcpdump 4.9.3 4.99.0, the —print option can be used:
Wednesday, December 30, 2020, by mcr@sandelman.ca, denis and fxl. Summary for 4.99.0 tcpdump release [. ] User interface: [. ] Add --print, to cause packet printing even with -w.
Does not work for me on ubuntu 20.04 tcpdump 4.9.3 libpcap 1.9.1: tcpdump: unrecognized option ‘—print’ . It does with upstream git version of tcpdump.
tcpdump > output.txt if you are looking to save the output into a file in text format.
Use sudo if permission issues are there.
My exp, the data gets written continuously.
tcpdump $ & PID=$! tcpdump $ -w $ kill $PID
If you want a way to do it without running tcpdump twice, consider:
sudo tcpdump port 80 -w $(tty) | tee /tmp/output.txt
From the interactive command prompt you could use $TTY instead of $(tty) but in a script the former wouldn’t be set (though I’m not sure how common it is to run tcpdump in a script).
Side-note: it’s not very Unix-y the way tcpdump by default makes you write to a file. Programs should by default write to stdout. Redirection to a file is already provided by the shell constructs. Maybe there’s a good reason tcpdump is designed this way but I don’t know what that is.