Анализ сетевого трафика на сервере с помощью tshark

от автора

tshark

В практике системного администрирования довольно часто приходится cталкиваться со сложными ситуациями, в которых не помогают ни инструменты сбора статистики (например, netstat), ни стандартные утилиты на основе протокола ICMP (ping, traceroute и другие). В таких случаях часто используются специализированные диагностические утилиты, дающие возможность «слушать» сетевой трафик и анализировать его на уровне единиц передачи отдельных протоколов. Они называются анализаторами трафика, а на профессиональном жаргоне — снифферами. С их помощью можно, во-первых, локализовывать сетевые проблемы и более точно их диагностировать, а во-вторых — обнаруживать паразитный трафик и выявлять в сети зловредное ПО.

Особенно полезными оказываются анализаторы трафика в случаях, когда сетевое ПО плохо документировано или использует собственные закрытые протоколы.

Одним из самых распространенных и популярных анализаторов трафика сегодня является Wireshark, распространяемый под лицензией GNU GPL. Существуют версии Wireshark для различных операционных систем: Linux, Windows, MacOS, FreeBSD, Solaris.

Tshark использует для захвата библиотеку libpcap, реализующую API pcap (packet capture). Эту библиотеку использует и стандартная утилита tcpdump. Файлы, созданные в tcpdump, можно передавать tshark для последующего анализа.

Несомненным преимуществом tshark по сравнению с tcpdump является более ясный и человекопонятный формат вывода. Кроме того, tshark поддерживает огромное количество сетевых протоколов (более 300, что охватывает практически все когда-либо изобретенные виды сетей).

Об особенностях работы с tshark мы подробно расскажем в этой статье.

Начало работы

Tshark включена в дистрибутивы большинства современных Linux-систем и устанавливается при помощи стандартного менеджера пакетов:

 $ sudo apt-get install tshark 

Завершив установку, запустим программу:

 $ sudo tshark 

На консоль будет выводиться список пакетов, захватываемых в режиме реального времени:

 Capturing on eth0 0.000000 88:e0:f3:b6:47:c0 -> Broadcast ARP Who has 31.186.98.120? Tell 31.186.98.1 0.322046 5a:58:74:bf:a9:9c -> Broadcast ARP Who has 31.186.98.77? Tell 31.186.98.226 0.351801 31.186.98.235 -> 188.93.16.50 SSH Encrypted response packet len=224 0.352414 188.93.16.50 -> 31.186.98.235 TCP cap > ssh [ACK] Seq=1 Ack=225 Win=331 Len=0 TSV=194287231 TSER=416767897 0.600054 88:e0:f3:b6:47:c0 -> Broadcast ARP Who has 31.186.98.120? Tell 31.186.98.1 0.622913 Cisco_0d:0d:96 -> PVST+ STP Conf. Root = 32768/398/00:21:1c:0d:0d:80 Cost = 0 Port = 0×8016 0.800377 88:e0:f3:b6:47:c0 -> Broadcast ARP Who has 31.186.98.107? Tell 31.186.98.1 1.320775 31.186.98.235 -> 188.93.16.50 SSH Encrypted response packet len=528 1.321507 188.93.16.50 -> 31.186.98.235 TCP cap > ssh [ACK] Seq=1 Ack=753 Win=331 Len=0 TSV=194287474 TSER=416768866 1.322109 5a:58:74:bf:a9:9c -> Broadcast ARP Who has 31.186.98.77? Tell 31.186.98.226 1.400654 88:e0:f3:b6:47:c0 -> Broadcast ARP Who has 31.186.98.107? Tell 31.186.98.1 1.589797 Cisco_0d:0d:96 -> PVST+ STP Conf. Root = 32768/401/00:21:1c:0d:0d:80 Cost = 0 Port = 0×8016 2.100769 88:e0:f3:b6:47:c0 -> Broadcast ARP Who has 31.186.98.107? Tell 31.186.98.1 2.322163 5a:58:74:bf:a9:9c -> Broadcast ARP Who has 31.186.98.77? Tell 31.186.98.226 2.322764 31.186.98.235 -> 188.93.16.50 SSH Encrypted response packet len=720 2.323594 188.93.16.50 -> 31.186.98.235 TCP cap > ssh [ACK] Seq=1 Ack=1473 Win=331 Len=0 TSV=194287724 TSER=416769868 2.520048 88:e0:f3:b6:47:c0 -> Broadcast ARP Who has 31.186.98.64? Tell 31.186.98.1 2.635370 Cisco_0d:0d:96 -> PVST+ STP Conf. Root = 32768/398/00:21:1c:0d:0d:80 Cost = 0 Port = 0×8016 3.200299 88:e0:f3:b6:47:c0 -> Broadcast ARP Who has 31.186.98.64? Tell 31.186.98.1 3.451774 31.186.98.235 -> 188.93.16.50 SSH Encrypted response packet len=528 

Как видно из приведенного вывода, tshark показывает информацию обо всех пакетах подряд, в том числе и о тех, которые в данный момент нам совершенно не нужны. С помощью специальных опций можно сделать так, чтобы на консоль выводилась только та информация, которая нам действительно требуется.

Фильтры

Выбор интерфейса для захвата

Опция -i позволяет захватывать трафик только для конкретного интерфейса. Просмотреть список доступных сетевых интерфейсов можно с помощью команды:

 $ sudo tshark -D  1. eth0 2. any 3. lo (Loopback) 4. nflog 5. nfqueue 6. usbmon1 

После опции -i указывается любой из доступных интерфейсов:

 $ sudo tshark -i eth0 

С помощью дополнительных аргументов можно получать более специализированную информацию. Например, с помощью аргумента host можно осуществить захват пакетов для конкретного IP-адреса:

 $ sudo tshark -i eth0 host 192.168.1.100 

В вывод будут включены как входящие, так и исходящие пакеты. Чтобы просмотреть информацию только о входящих пакетах или только об исходящих пакетах, используются аргументы dst и src соответственно:

 $ sudo tshark -i eth0 src host 192.168.1.100  

Команда выведет на консоль список пакетов, исходящих с адреса 192.168.1.100

 $ sudo tshark -i eth0 dst host 192.168.1.100  

На консоль будет выведен список пакетов, поступающих на адрес 192.168.1.100.

Аналогичным образом можно захватывать трафик для целой подсети — для этого используется аргумент net:

 $ sudo tshark -i eth0 src net 192.168.1.0/24 

Можно также указать порт, на котором будут захватываться пакеты:

 $ sudo tshark -i eth0 host 192.168.1.1 and port 80 

Tshark позволяет захватывать пакеты в течение определенного промежутка времени:

 $ sudo tshark -i eth0 -a duration:10 -w traffic.pcap 

В приведенном примере была также использована опция -w. После неё указывается путь к файлу, в который будут записаны полученные данные.

Фильтры захвата

Эти фильтры используются при захвате трафика «на лету». Они перекомпилируются в набор правил для pcap, в соответствии с которыми осуществляется фильтрация пакетов. На консоль выводится лишь та информация, которая соответствует установленным с помощью фильтров критериям.

В общем виде синтаксис команды tshark с фильтрами можно представить так:

 $ sudo tshark -i <интерфейс> -f <фильтр> 

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

Фильтры чтения

Tshark может сохранять информацию о захваченных пакетах в файлах. Чтобы извлечь из этих файлов нужную информацию, используются фильтры чтения, называемые так же правилами (опция -R). Они могут быть использованы и при захвате пакетов «на лету». Обработка информации осуществляется не pcap, а средствами самого tshark.

Эти фильтры дают гораздо более широкие возможности для отбора и конкретизации информации.

Следует, однако, учитывать, что при анализе большого количества информации «на лету» они могут не справиться с возлагаемыми на них задачами: не успевают осуществлять фильтрацию и сбрасывают пакеты.

В общем виде синтаксис правил можно представить так:

 $ sudo tshark -R "правило" -r "путь к файлу" 

Рассмотрим особенности формирования правил на конкретных примерах.
Так, команда

 $ sudo tshark -R "ip.addr == 192.168.0.1" -r /tmp/capture.cap 

указывает, что из файла /tmp/capture.cap нужно извлечь информацию об исходящих и входящих пакетах для IP-адреса 192.168.0.1.

Следующее правило будет указывать, что из этого файла нужно извлечь информацию о входяших и исходящих пакетов для всех IP- адресов, кроме 192.168.0.1:

 $ sudo tshark -R "!(ip.addr == 192.168.0.1)" -r /tmp/capture.cap  

Аналогичным образом можно задавать правила и для других протоколов и портов (фильтры eth.addr, udp.port, tcp.port):

 $ sudo tshark -R  "eth.addr == 00:08:15:00:08:15" -r /tmp/capture.cap  $ sudo tshark -R "udp.port == 80" -r /tmp/capture.cap  $ sudo tshark -R "tcp.port == 80" -r /tmp/capture.cap 

Правила можно также объединять при помощи логических операторов and, or и not:

 $ sudo tshark -R "not arp and not (udp.port == 53)" -r /tmp/capture.cap 

Приведенная команда указывает, что нужно извлечь список всех захваченных пакетов, кроме ARP и DNS (53 порт).

Дополнительные настройки

Cбор статистики

C помощью опции -z можно собирать и выводить на консоль различную статическую информацию о пакетах.

Например, команда

 $ sudo tshark -z "proto,colinfo,tcp.srcport,tcp.srcport" -r /tmp/capture.cap 

указывает, что из файла /tmp/capture.cap нужно извлечь информацию о порте-источнике всех пакетов.

Рассмотрим еще один пример:

 $ sudo tshark -R "http.response and http.content_type contains image" \ -z "proto,colinfo,http.content_length,http.content_length" \ -z "proto,colinfo,http.content_type,http.content_type" \ -r /tmp/capture.cap 

Эта команда извлечет из файла /tmp/capture.cap информацию обо всех пакетах, в которых были изображения, и выведет на консоль содержимое полей content_type и content_length:

 439 12.717117 66.249.89.127 -> 192.168.1.108 HTTP HTTP/1.1 200 OK (GIF89a) http.content_type == "image/gif" http.content_length == 35 452 12.828186 66.114.48.56 -> 192.168.1.108 HTTP HTTP/1.1 200 OK (GIF89a) http.content_type == "image/gif" http.content_length == 477 479 13.046184 66.114.48.56 -> 192.168.1.108 HTTP HTTP/1.1 200 OK (GIF89a) http.content_type == "image/gif" http.content_length == 105 499 13.075361 203.190.124.6 -> 192.168.1.108 HTTP HTTP/1.1 200 OK (GIF89a) http.content_type == "image/gif" http.content_length == 35 506 13.177414 66.114.48.56 -> 192.168.1.108 HTTP HTTP/1.1 200 OK (GIF89a) http.content_type == "image/gif" http.content_length == 4039 514 13.190000 66.114.48.56 -> 192.168.1.108 HTTP HTTP/1.1 200 OK (JPEG JFIF image) http.content_type == "image/jpeg" http.content_length == 11997 519 13.231228 66.114.48.56 -> 192.168.1.108 HTTP HTTP/1.1 200 OK (JPEG JFIF image) http.content_type == "image/jpeg" http.content_length == 1033 523 13.273888 72.233.69.4 -> 192.168.1.108 HTTP HTTP/1.1 200 OK (PNG) http.content_type == "image/png" http.content_length == 1974 561 728 19.096984 60.254.185.58 -> 192.168.1.108 HTTP HTTP/1.1 200 OK (GIF89a) http.content_type == "image/gif" http.content_length == 592 805 19.471444 60.254.185.58 -> 192.168.1.108 HTTP HTTP/1.1 200 OK (GIF89a) http.content_type == "image/gif" http.content_length == 259 

Автоматическое сохранение в несколько файлов

Представим себе, что нам нужно сохранять статистику трафика в течение длительного периода времени. Сохранить весь вывод в одном файле в такой ситуации не очень удобно: его потом трудно анализировать.

Вывод можно сохранять в нескольких файлах, количество и размер которых указываются пользователем. Как только один файл будет заполнен, tshark продолжит запись в следующий. Например, команда:

 $ sudo tshark -b filesize:100 -a files:20 -w temp.pcap 

будет сохранять вывод в 20 файлах размером по 100 кБ каждый.

В приведенном выше примере опция -b означает, что будет задействован кольцевой буфер, а filesize устанавливает размер; опция -a указывает автоматическую остановку по достижении заданного предела, files — указывает количество файлов.

Автосохранение по истечении заданного времени

В приведенном ниже примере tshark будет сохранять захваченную информацию в несколько файлов. Новый файл будет создан автоматически при превышении размера в 10240 кБ или по истечении интервала 1 с:

 $ sudo tshark -b filesize:10240 -b duration:1 -w temp.pcap    Capturing on eth0  34  # ls -lrt  -rw------- 1 root root 1863 Apr 10 16:13 temp_00001_20140410161312.pcap  -rw------- 1 root root 1357 Apr 10 16:13 temp_00002_20140410161313.pcap  -rw------- 1 root root 1476 Apr 10 16:13 temp_00003_20140410161314.pcap  -rw------- 1 root root 1216 Apr 10 16:13 temp_00004_20140410161315.pcap 

Установка размера буфера

Эта опция может быть полезной в случаях, когда приходится иметь дело с отбрасыванием пакетов. По умолчанию размер буфера составляет 1МБ; при помощи опции -B можно установить любой другой размер (в мегабайтах), по достижении которого все данные будут сбрасываться на диск:

 $ sudo tshark -B 2 

Отображение статистики для выбранного протокола

В tshark имеется также возможность захватывать только пакеты, передаваемые по указанному пользователем протоколу.

Вот так, например, выглядит статистика для протокола HTTP:

 $ sudo tshark -q -r a.pcap -R http -z http,tree   ===================================================================  HTTP/Packet Counter value	 rate	 percent  -------------------------------------------------------------------  Total HTTP Packets 7 0.000375  HTTP Request Packets 4 0.000214 57.14%  GET 4 0.000214 100.00%  HTTP Response Packets 3 0.000161 42.86%  2xx: Success 2 0.000107 66.67%  200 OK 2 0.000107 100.00%  3xx: Redirection 1 0.000054 33.33%  302 Found 1 0.000054 100.00%  5xx: Server Error 0 0.000000 0.00%  Other HTTP Packets 0 0.000000 0.00% 

Практические примеры

В этом разделе мы рассмотрим, как можно использовать tshark для решения повседневных администраторских задач.

Мониторинг http-запросов

Чтобы вывести список http-запросов к серверу, используется следующая команда:

 $ sudo tshark 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<>2)) != 0)' -R 'http.request.method == "GET" || http.request.method == "HEAD"' 

Вывод этой команды будет выглядеть так:

 190.302141 192.168.0.199 -> 74.125.77.104 HTTP GET / HTTP/1.1 190.331454 192.168.0.199 -> 74.125.77.104 HTTP GET /intl/en_com/images/srpr/logo1w.png HTTP/1.1 190.353211 192.168.0.199 -> 74.125.77.104 HTTP GET /images/srpr/nav_logo13.png HTTP/1.1 190.400350 192.168.0.199 -> 74.125.77.100 HTTP GET /generate_204 HTTP/1.1 

Следующая команда выведет на консоль список из 10 URL-адресов, с которых поступают http-запросы:

 $ tshark -r sample1.cap -R http.request -T fields -e http.host -e http.request.uri | sed -e ‘s/?.*$//’ | sed -e ‘s#^(.*)t(.*)$#http://12#’ | sort | uniq -c | sort -rn | head 

Просмотр списка HTTP-заголовков

Чтобы просмотреть список http-заголовков запросов к серверу, используется команда:

 $ tshark -r sample1.cap -R http.request -T fields -e http.host -e http.request.uri | sed -e ‘s/?.*$//’ | sed -e ‘s#^(.*)t(.*)$#http://12#’ | sort | uniq -c | sort -rn | head 

Соответственно, список заголовков для http-ответов можно получить так:

 $ sudo tshark tcp port 80 or tcp port 443 -V -R «http.request» 

Чтобы в список были включены заголовки как запросов, так и ответов, используется следующая команда:

 $ sudo tshark "tcp port 80 or tcp port 443" -V -R "http.request || http.response" 

Просмотр списка файлов определенного типа

С помощью tshark можно просматривать списки файлов определенного типа, передаваемых через http-протокол. Вот так, например, можно просмотреть список изображений в формате GIF:

 $ sudo tshark -R "http.response and http.content_type contains image" \ -z "proto,colinfo,http.content_length,http.content_length" \ -z "proto,colinfo,http.content_type,http.content_type" \ -r /tmp/capture.tmp| grep "image/gif"| wc -l 

Мониторинг запросов к MySQL

Отследить в реальном времени запросы в базе данных MySQL можно с помощью следующей команды:

 $ sudo tshark -i eth0 -a duration:60 -d tcp.port==3306,mysql -T fields -e mysql.query ’port 3306′ 

C помощью tshark можно записывать в лог информацию обо всех запросах к MySQL. Запустим захват всего MySQL-трафика с помощью tcpdump:

 $ sudo tcpdump -i eth0 port 3306 -s 1500 -w tcpdump.out 

Из полученного файла c помощью tshark извлечем список запросов:

 $ sudo tshark -r tcpdump.out -d tcp.port==3306,mysql -T fields -e mysql.query > query_log.out 

Из этого списка удалим пустые строки и сохраним отредактированный вариант в новом файле:

 $ sudo cat query_log.out | grep -v "^$" | grep -v "^commit" | grep -v "^SET autocommit" | grep -v "^rollback" > query_log_no_blank.out 

Заключение

Tshark — инструмент с очень широкими возможностями, о которых вряд ли возможно подробно рассказать в рамках одной статьи. На все вопросы мы с удовольствием ответим в комментариях. Будем рады, если вы поделитесь собственным опытом диагностики сетевых проблем с помощью tshark.

Читателей, которые не могут оставлять комментарии здесь, приглашаем к нам в блог.

ссылка на оригинал статьи http://habrahabr.ru/company/selectel/blog/233837/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *