Рубрика:
Карьера/Образование /
Лабораторная работа
|
Facebook
Мой мир
Вконтакте
Одноклассники
Google+
|
ВЛАДИМИР ЗАКЛЯКОВ, советник налоговой службы 2-го ранга
Лабораторная работа Исследуем сокеты. Часть 2 (продолжение)
В предыдущем номере [1] были описаны цели работы, схема исследований, устройство и подготовка лабораторного стенда, ход проведения работы и отдельные компоненты. Вданной части познакомимся с оставшимися компонентами стенда
Браузер lynx
Один из первых текстовых браузеров.
Недостатки: не поддерживает отрисовку таблиц HTML, фреймы HTML и JavaScript.
Плюсы: небольшой, консольный, то есть работающий только через CLI-интерфейс, кроссплатформенный (Linux, Windows, UNIX, OS/2, DOS и др.), умеет работать с простыми формами.
Обратите внимание, что также имеется созвучный по названию lynx совершенно другой программный продукт: Links. Это уже текстово-графический браузер с поддержкой фреймов, вкладок, таблиц и JavaScript. Также поддерживается широкая кроссплатформенность, и даже имеются 64-битные сборки.
Дополнительно в данный момент существуют две основные ветки разработки на базе кода links:
- ELinks – для повышения функциональности имеет встроенный язык программирования Lua.
- Links2 – поддерживает также графику.
Пример обращения к веб-серверу по адресу 192.168.1.1:
$ lynx 192.168.1.1
Использование текстовых браузеров может быть оправданно, в случае если на сервере по каким-то причинам отсутствует оконная система X Window System. Например, домашний маршрутизатор или какое-либо иное бытовое устройство с сетевым интерфейсом и ОС Linux «на борту».
Замечание. Обратите внимание, что существует библиотека AAlib [7], с помощью которой возможно просматривание графических объектов посредством «ascii-графики» непосредственно на текстовой консоли.
wget
Cвободная неинтерактивная консольная программа для загрузки файлов по сети. Поддерживает протоколы HTTP, FTP и HTTPS. Умеет работать через HTTP-прокси. Имеются сборки под Linux, Windows, UNIX. Включена практически во все дистрибутивы GNU/Linux.
Из полезного – умеет самостоятельно находить в HTML-документах ссылки на другие документы, находящиеся на сервере, и также скачивать их, что используется в функции «выкачивания сайтов», вплоть до указанного уровня вложенности.
Многие сторонние коммерческие программы предпочитают не изобретать велосипед и активно пользуются штатными функциями wget, например, для получения файлов обновлений.
tcpdump
Консольный анализатор трафика (сниффер) позволяет захватывать и анализировать сетевой трафик, проходящий через сетевой интерфейс. Часто используется сетевыми администраторами для оценки сетевой активности и диагностики сетевых подключений.
Поскольку доступ к сетевым интерфейсам имеется лишь у администратора, то запуск программы в режиме подключения к сетевым интерфейсам системы (в том числе и lo) возможен лишь с его правами.
Среди полезных (для данной работы) опций у программы следует отметить следующие:
- -e – выводит заголовки канального уровня для каждого перехваченного кадра;
- -i имя_интерфейса – задаёт сбор пакетов с указанного интерфейса. Параметр any соответствует всем сетевым интерфейсам. Если интерфейс не задан, tcpdump ищет в системе список доступных интерфейсов и выбирает первый (исключая loopback, в том числе даже если интерфейс находится в состоянии down). Также возможен анализ данных, передаваемых по USB, например, через обращение к интерфейсам usbmon1, usbmon2 и так далее;
- -c <число пакетов> – указывает завершить программу по достижении заданного числа перехваченных кадров;
- -n – отключает преобразование адресов в символьные имена;
- -nn – отключает преобразование номеров портов в символьные имена;
- -X – задаёт вывод дампа в шестнадцатеричном и ASCII-форматах без заголовков канального уровня. Эта опция может быть очень удобна при анализе новых протоколов, атакже для просмотра передаваемых данных в рамках данной работы;
- -s xxx – указывает производить просмотр первых xxx байт от начала пакета (по умолчанию просматриваются лишь первые 68);
- -w имя_файла – указывает записывать все перехваченные кадры в файл в сыром (raw) виде. Указанный файл впоследствии можно просмотреть с использованием ключа -r илипередать сторонней программе, например Wireshark Network Analyzer.
Примеры запуска:
1) Просмотр всего трафика, проходящего через интерфейс lo:
# tcpdump -i lo
2) Просмотр всего TCP и UDP-трафика, приходящего на сетевой интерфейс eth0 из сети 192.168.1.0/24, в котором порт получателя равен 80 или 1080:
# tcpdump 'src net 192.168.1.0/24 and (dst port 80 or 1080)'
3) Просматривать UDP-трафик, идущий на порты 1234 и 1235 от хоста 192.168.1.3 через интерфейс eth0:
# tcpdump -i eth0 'src 192.168.1.3 and udp and (dst port 1234 or 1235)'
4) Просматривать содержимое UDP-дейтаграмм, имеющих порт получателя 1234 на интерфейсе eth0:
# tcpdump -X -s 1000 -i eth0 'udp and (dst port 1234)'
Замечание. Для ОС Windows доступна бесплатная портированная версия tcpdump – WinDump [2].
Tshark
Программа tcpdump имеет довольно простой синтаксис написания правил и фактически является своего рода «неустаревающей классикой» среди снифферов. В большинстве случаев она продолжает удовлетворять потребности администраторов, и в ближайшее десятилетие также будет это делать.
Однако TShark умеет работать с протоколом HTTPS, поддерживает огромное количество и других сетевых протоколов (более трёх сотен), имеет более информативный вывод информации о полученных данных.
Для целей данной лабораторной работы TShark не даст каких-либо существенных преимуществ по сравнению с tcpdump, тем более обе программы используют одну и ту же библиотеку libpcap, реализующую API pcap (packet capture).
Среди полезных ключей для запуска программы можно выделить следующие:
- -a условие_останова_перехвата – указывает условие, при котором программа завершит своё выполнение; возможно задание разных условий, например по длительности работы, если в качестве параметра в ключе указать duration:10, то это укажет программе завершить свою работу через 10 секунд после её запуска. Например, просматривание информации о приходе UDP-дейтаграмм, имеющих порт получателя 1234 и адрес отправителя 192.168.1.1 на интерфейсе eth0, в течение 30 секунд с момента запуска можно осуществить командой:
# tshark -i eth0 src host 192.168.1.1 and dst port 1234 and udp -a duration:30
- -b опции_кольцевой_записи – позволяет производить запись в несколько файлов. Представьте ситуацию, что вам необходимо сохранять статистику трафика в течение длительного периода времени. Сохранить весь вывод в одном файле в такой ситуации заведомо не получится. Использование сторонних механизмов ротации файлов журналов возможно, но не очень удобно. Самое простое, что можно сделать, – это производить сохранение информации о трафике в нескольких файлах, количество и размер которых указываются пользователем. При заполнении одного файла запись продолжается в следующий. Например, укажем 15 файлов размером по 100 КБ каждый:
# tshark -b filesize:100 -a files:15 -w traffic_dump.pcap
Запись будет производиться в файлы с именами вида:
traffic_dump_00001_20160317185736.pcap traffic_dump_00001_20160317185802.pcap traffic_dump_00002_20160317185806.pcap ...
- -R фильтр_отображения – позволяет производить фильтрацию полученных данных по различным критериям (в том числе и на основе данных об уровнях приложений) ивыводить лишь ту информацию, что соответствует заданному условию. Например, фильтр http.request будет отображать лишь приходящие HTTP. Совместно с другими параметрами можно рассматривать лишь запросы, приходящие на 80-й порт протокола TCP на интерфейсе eth1:
# tshark tcp dst port 80 and tcp -R http.request -i eth1
- -V – сообщает TShark выводить подробную информацию, а не отчёты в одну строку на каждый фрейм (пакет, дейтаграмму);
- -x – сообщает TShark также печатать содержимое (поле данных) из полученных пакетов (дейтаграмм, кадров) в шестнадцатеричном формате и в виде ASCII.
Wireshark
Wireshark (Wireshark Network Analyzer) – это достаточно известный кроссплатформенный инструмент для захвата и анализа сетевого трафика, аналогичный tcpdump и tshark, но сграфическим интерфейсом.
Wireshark работает с подавляющим большинством известных протоколов, имеет понятный и логичный графический интерфейс на основе GTK+ и мощнейшую систему фильтров.
Использование графического интерфейса интуитивно понятно. Для начала захвата достаточно в окне Capture найти в списке Interface List нужный сетевой интерфейс, например eth0, и нажать на него.
После чего и начнётся процесс захвата, причём «прилетевшие» на сетевой интерфейс пакеты (кадры, дейтаграммы) будут появляться в реальном времени, подобно получению писем электронной почты. Имеется возможность «щёлкнуть» на любую из строчек и открыть просмотр содержимого, подобно письму электронной почты, после чего в нижней половине будут показаны структура заголовков, представленная деревом, и побайтовое наполнение пакета, как в hex-редакторах.
netstat, ss
netstat – консольная утилита для просмотра списка установленных сетевых соединений, таблиц маршрутизации, статистики сетевых интерфейсов и другой полезной сетевой информации.
На сегодняшний день считается устаревшей, а вместо неё рекомендуется использовать утилиту ss (из комплекта утилит iproute2). ss показывает ту же информацию, что и netstat, выдавая больше данных о состоянии и о TCP-сокетах, нежели какие-либо другие утилиты.
Среди полезных ключей для запуска обеих программ можно выделить следующие:
- -n – не преобразовывать имена хостов и номера портов в соответствующие им доменные имена и названия сервисов. Отображение в цифровом виде производится значительно быстрее;
- -t – выводить информацию лишь по TCP-сокетам. Обратите внимание, что прослушивающие сокеты по умолчанию не отображаются, для получения полной картины используйте совместно с ключом -а;
- -u – выводить информацию лишь по UDP-сокетам (аналогично, см. замечание про ключ -a выше);
- -a – выводить информацию по всем сокетам (то есть вне зависимости от состояния сокета).
Примеры использования:
1) Показать информацию обо всех TCP-сокетах (в том числе и слушающих):
$ netstat -t -a -n
$ ss -t -a -n
2) Показать информацию обо всех UDP-сокетах (в том числе и слушающих):
$ netstat -u -a -n
$ ss -u -a -n
3) Отобразить все установленные TCP-соединения с веб-сервером. (Соответствие названий сервисов их номерам согласно рекомендациям IANA смотрите в файле в /etc/services):
$ ss -o state established '( dport = :http or sport = :http )'
$ ss -o state established '( dport = :80 or sport = :80 )'
4) Отобразить все TCP-сокеты с адресом клиента из подсети 192.168.1.0/24:
$ ss -t -a src 192.168.1.0/24
lsof
Отображает список открытых файлов и псевдофайлов, в том числе и сокетов, как локальных, так и протоколов TCP и UDP.
Примеры использования:
1) Показать все TCP и UDP-сокеты:
$ lsof -i
2) Показать все TCP и UDP-сокеты, связанные с адресом 192.168.1.5:
$ lsof -i@192.168.1.5
$ lsof -i @192.168.1.5
3) То же самое, но при отображении не преобразовывать адреса хостов и номера портов в доменные имена и названия сервисов:
$ lsof -i@192.168.1.5 -n -P
4) Показать все TCP-сокеты; при отображении не преобразовывать адреса хостов и номера портов:
$ lsof -i TCP -n -P
5) Показать все UDP-сокеты, связанные с адресом 192.168.1.5; при отображении не преобразовывать адреса хостов и номера портов:
$ lsof -i UDP@192.168.1.5 -n -P
iptables
Программа iptables используется для взаимодействия суперпользователя со структурой и кодом ядра netfilter. Фактически используется для управления правилами и цепочками правил, определяющими режимы фильтрации сетевого трафика. В рамках данной работы данная утилита интересна тем, что позволяет просматривать счётчики, имеющиеся у всех правил и цепочек, то есть получать статистическую информацию о количестве переданных (принятых) байт и пакетов (дейтаграмм).
Для просмотра статистики используется следующий синтаксис вызова:
# iptables -L -v -x -n --line-numbers
То же самое, но только для цепочки INPUT:
# iptables -L INPUT -v -x -n --line-numbers
Назначение ключей:
- -L – отобразить статистическую информацию;
- -v – отобразить дополнительную информацию, в том числе статистику;
- -x – отображать значения счётчиков с точностью до байта;
- -n – не преобразовывать при отображении адреса и номера портов в доменные имена и названия сервисов;
- --line-numbers – перед каждым правилом выводить его порядковый номер в цепочке.
Для обнуления значений счётчиков используется ключ -Z:
# iptables -Z
Возможно совмещение с ключом -L для просмотра статистики с последующим обнулением.
Также из полезных функций iptables для исследования сокетов можно отметить возможность создания фильтрующих правил без указания действия (то есть без «-j действие»), такие правила могут использоваться для ведения статистического учёта.
Например, следующая команда добавит в начало цепочки INPUT правило для подсчёта пакетов протокола TCP во входном трафике, идущих с адреса 192.168.1.4:
# iptables -I INPUT -p tcp -s 192.168.1.4
Для удаления правил используется ключ -D:
# iptables -D INPUT -p tcp -s 192.168.1.4
или
# iptables -D INPUT номер_правила
При использовании модулей TCP и UDP (параметры -p tcp и -p udp) возможно дополнительное указание портов отправителя и получателя через ключи (--source-port XX, --destination-port XX, либо --sport XX и --dport XX).
ps
Используется для просмотра списка запущенных процессов в системе. Для просмотра всех процессов в системе часто используется в следующих формах запуска:
$ ps aux
и
$ ps ax
Данная команда не отображает никакой информации о сокетах. В рамках данной работы приведена лишь в целях более полного представления происходящих в операционной системе процессов.
Может быть полезна для получения дополнительной информации. Заметим, что утилита lsof в столбце «PID» отображает идентификаторы процессов, работающих с файлами ипсевдофайлами (в нашем случае с сокетами).
Веб-сервер Apache
В данной работе нужен лишь для придания «веса» процессу исследований, как солидное программное средство, работающее с сокетами.
Задумка заключается в том, чтобы понять и «прочувствовать», что только что им написанная и скомпилированная программа на языке Си способна выступать в роли клиента иполучать данные от веб-сервера. При наличии постоянного прямого подключения к интернету возможно использование любых известных пользователю и работающих веб-сайтов сэтой целью.
«Прямое подключение» означает возможность обращения к сайтам на 80-й порт по протоколу TCP без использования прокси-серверов для этой цели. Использование нелегитимных адресов (согласно RFC 1918) и/или трансляция адресов для осуществления подключения не имеет значения.
Запуск сервера:
# service httpd start
Для проверки работы исследования достаточно и тестовой страницы.
По умолчанию в качестве корневой директории веб-сервера (то, куда помещать html, php и другие файлы) используется /var/www/html.
Замечание. При включённом SELinux и отсутствии разрешающих доменов обратите внимание на используемый для файлов и директорий контекст безопасности. (system_u:object_r:httpd_sys_content_t:s0)
Программы на Си
Ниже приведены простые программы на Си, реализующие клиентское и серверное использование TCP и UDP-сокетов.
В угоду краткости и понятности (важные требования, чтобы не отпугнуть начинающих и сомневающихся в своих силах программистов) их простота заключается в том, что в них вомногих привычных местах отсутствуют проверки получаемых статусов соединений, учёта переданных данных и проверки самого факта передачи данных.
Несомненно, в реальных условиях эксплуатации подобных программ не избежать различных доработок, а там, глядишь, и... «лиха беда начало», и... «у совершенства нет предела», и... «лучшее враг хорошего». Чувствуете свои силы и имеете под рукой более сложный код? Тогда – дерзайте!
Всем же остальным, кто сомневается в своих силах ещё на старте, ниже даны примеры простого и работоспособного кода.
tcp_client1.c – простой TCP-клиент:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main(void)
{
int s;
char buf[256]="Привет! Hello!\n";
struct sockaddr_in serv_addr;
bzero(&serv_addr, sizeof(serv_addr));
serv_addr.sin_family=AF_INET;
serv_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
serv_addr.sin_port=htons((u_short) 1234);
s=socket(PF_INET, SOCK_STREAM, 0);
connect(s, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
send(s, buf, strlen(buf), 0);
close(s);
}
tcp_client2.c – по сути, тот же клиент, что tcp_client1.c, но после отправки своей порции данных на сервер он получает от него ответ и выводит его на консоль (не более 255 байт, большее будет утрачено), для этого в коде перед закрытием сокета (строчка close(s);) следует дописать:
int nbytes;
nbytes=recv(s, buf, sizeof(buf)-1, 0);
if (nbytes>0) { buf[nbytes]='\0';
printf("%s",buf); }
tcp_client3.c – в коде клиента tcp_client2.c самостоятельно поменяйте местами порядок получения и отправки данных. На практике существуют TCP-серверы, выдающие приветственное приглашение, прежде чем что-то получать от клиента. Что-то вроде жизненного случая, когда... вы определились с мыслями куда пойти («выбрали заведение», поаналогии с «создали сокет»), вошли через двери заведения (подключились к сокету), ещё не успели подумать, что сказать (отправить серверу), а вы уже слышите в свой адрес: «Свободная касса!» (получили приглашение от сервера), либо более грубое, но чёткое «Чего надо?!».
Замечание. Посылаемые в программах сообщения специально выбраны содержащими как кириллицу, так и латиницу. Сделано это по причине наиболее вероятного использования кодировки Unicode и способа кодирования UTF-8 для записи текстового сообщения. Поскольку символы кириллицы в этом случае кодируются двумя байтами, а латиницы – одним (сиспользованием ASCII), то при просмотре сырых данных из сокета, полученных с помощью сниффера, требуется изрядное искусство, чтобы разглядеть великий и могучий русский язык в сообщениях. А вот текстовые строки, закодированные с помощью ASCII, увидят все и сразу. А потом, если захотят, смогут раскодировать и оставшуюся часть сообщения. Какэто сделать – см. [3].
udp_client1.c – в коде tcp_client1.c самостоятельно замените в строке:
s=socket(PF_INET, SOCK_STREAM, 0);
тип сокета с SOCK_STREAM на SOCK_DGRAM.
udp_server1.c – простой UDP-сервер:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/socket.h>
int main(void)
{
struct sockaddr_in serv_addr, clnt_addr;
int s, i, slen = sizeof(clnt_addr), nbytes;
char buf[256];
if ((s=socket(PF_INET, SOCK_DGRAM, 0)) == -1)
{
perror("Ошибка вызова socket()");
exit(1);
}
/* Очистка памяти структуры serv_addr. */
memset((char *) &serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(1234);
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
/* Привязка сокета к прослушиваемому порту и адресу. */
if( bind(s , (struct sockaddr*)&serv_addr, sizeof(serv_addr) ) == -1)
{
perror("Ошибка вызова bind()");
exit(2);
}
/* Принимаем входящие соединения. */
while(1)
{
printf("Ждём подключения.\n");
fflush(stdout);
if ((nbytes = recvfrom(s, buf, sizeof(buf)-1, 0, (struct sockaddr *) &clnt_addr, &slen)) == -1)
{
perror("Ошибка вызова recvfrom()");
exit(3);
}
buf[nbytes]='\0';
printf("Дейтаграмма от %s:%d\n", inet_ntoa(clnt_addr.sin_addr), ntohs(clnt_addr.sin_port));
printf("Её содержимое: %s\n", buf);
}
close(s);
return 0;
}
Читайте продолжение лабораторной работы в следующем номере журнала.
- Закляков В. Лабораторная работа. Исследуем сокеты. Часть 1. //«Cистемный администратор», №4, 2016 г. – С. 75-79 (http://samag.ru/archive/article/3179).
- Сайт библиотеки WinPcap и программы WinDump – http://www.winpcap.org.
- Грошев А., Закляков П. Информатика: учеб. для вузов – 3 е изд., перераб. и доп. – М.: ДМК Пресс, 2015. – 588 с.: цв. ил. ISBN 978-5-97060-304-8.
- Стивенс У. UNIX: разработка сетевых приложений. – СПб.:Пи-тер, 2003. – 1088 с. ISBN 5-318-00535-7.
Facebook
Мой мир
Вконтакте
Одноклассники
Google+
|