Средства сетевой диагностики в ОС Linux

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

Анализаторы пакетов tcpdump и tshark

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

В листинге ниже показан пример использования наиболее распространенного, «классического» анализатора пакетов tcpdump, анализирующего пакеты на интерфейсе (-i, interface) wlan0, адресованные порту port 53.

Анализатор пакетов tcpdump

pts/1

lumpy@ubuntu:~$ host 2x2tv.ru

2x2tv.ru has address 178.63.2.134

2x2tv.ru mail is handled by 20 relay2.tnt-tv.ru.

2x2tv.ru mail is handled by 30 relay3.tnt-tv.ru.

2x2tv.ru mail is handled by 10 mx.tnt-tv.ru.

pts/2

lumpy@ubuntu:~$ sudo tcpdump -i wlanO port 53

tcpdump: verbose output suppressed, use -v or -w for full protocol decode

listening on wlan0, link-type EN10MB (Ethernet), capture size 65535 bytes

tcpdump: verbose output suppressed, use -v or -w for full protocol decode

listening on wlanO, link-type EN10MB (Ethernet), capture size 65535 bytes

15:11:32.139394 IP ubuntu.local.40694 > 192.1£8.100.1.donaUi: 27739» A? 2x2tv.ru. 26)

15:11:32.144674 IP 192.168.100.1.donain > ubuntu.local.40694: 27739 1/0/0 A 178.63.2.134  (42)

15:11:32.145260 IP ubuntu.local.22022 > 192.1£8.100.1.dcnaln: 37673» AAAA? 2x2tv.ru. (26)

15:11:32.147959 IP 192.168.100.1.domain > ubuntu.local.48132: 41476 NXDomain 0/0/0 (44)

15:11:32.149187 IP ubuntu.local.58056 > 192.m 100.1.domain: 62332+ MX? 2x2tv.ru. (26)

15:11:32.154191 IP 192.168.100.1.domain > ubuntu.local.58056: 62332 3/0/2 MX mx.tnt-tv.ru. 10, … (130)

^C

6 packets captured

6 packets received by filter

0 packets dropped by kernel

Анализу подвергается работа DNS-клиента host, отображающего имя домена 2x2tv.ru на IP-адрес и имена его почтовых адресов (MX-записи DNS). В результате анализа захваченных пакетов наблюдаются запросы и ответы DNS-протокола к локальному кэширующему серверу 192.168.100.1, который на вопрос А? адреса IPv4, соответствующего имени 2x2tv.ru, отвечает адресом а 178.63.2.134, а на вопрос AAAA? адреса IPv6 отвечает NXDomain (отсутствует такая DNS-запись).

Терминальный1 анализатор пакетов tshark, позволяющий проводить детальный анализ прикладных протоколов, таких как SSH, HTTP, FTP, NFS и пр., проиллюстрирован в листинге ниже. Здесь анализируется работа пользовательского агента curl, запрашивающего Web-pecypc по адресу http://iplnfo.io/ctty.

В результате захвата пакетов на интерфейсе (-i, interface) wlan0, адресованных порту port 80, просматриваются (-R, read filter) пакеты, содержащие http-запросы, при этом детальному анализу (-V, view) подвергается только (-O, only) их http-содержимое.

В результате анализа, например, можно сделать вывод о программном обеспечении Web-сервера, обслуживающего сайт http://ipinfi.io.

Анализатор пакетов wireshark

pts/1

lumpy@ubuntu:~$ curl http://ipinfo.io/city

Saint Petersburg

lumpy@ubuntu:~$ sudo tshark -i wlanO port 80 -V -0 http,data-text-lines -R http

tshark: Lua: Error during loading:
[string «/usr/share/wireshark/init.lua»]:45: dofile has been disabled

Running as user «root» and group «root». This could be dangerous.
Capturing on wlan0
Frame 38: 229 bytes on wire (1832 bits), 229 bytes captured (1832 bits)
Ethernet II, Src: Intelcor_а2:28:4е (b8:03:05:a2:28:4е), Dst: 9c:37:f4:76:c5:S8 (9c:37:f4:76:c5:58)

Internet Protocol Version 4, Src: 192.168.100.5 (192.168.100.5), Dst: S2.28.249.93 (52.28.249.93)

Transmission Central Protocol, Src Port: 43564 (43564), Dst Port: http ($0), Seq: 1, Ack: 1, Len: 163

Hypertext Transfer Protocol

GET /city HTTP/1.1\r\n
[Expert Info (Chat/Seqgence): GET /city HTTP/1.1\r\n]
[Message: GET /city HTTP/1.1\r\n]
[Sa/erity level: Chat]
[Group: Sequence]
Request Method: GET

Request URI: /city

Request Version: HTTP/1.1
User-Agent: curl/7.22.0 (i686-pc-linux-gnu) libcurl/7.22.0 GpenSSL/1.0.1 zlib/1.2.3.4 libidn/1-23 …

Host: ipinfo.io\r\n

Accept: */*\r\n

[Full request URI: http://ipinfo.io/city]

Frame 54: 313 bytes on wire (2504 bits), 313 bytes captured (2504 bits)

Ethernet II, Src: 9c:37:f4:76:c5:58 (9c:37:f4:76:c5:58), Dst: IntelCor_a2:28:4e (b8:03:05:a2:28:4e)

Internet Protocol Version 4, Src: 52.28.249.93 (52.28.249.93), Dst: 192.168.100.5 (192.168.100.5)

Transmission Control Protocol, Src Port: http (80), Dst Port: 43564 (43564), Seq: 1, Ack 164, Len: 247

Hypertext Transfer Protocol

HTTP/1.1 200 OK\r\n

[Expert Info (Chat/Sequence): HTTP/1.1 200 OK\r\n]

[Message: HTTP/1.1 200 OK\r\n]

[Severity level: Chat]

[Group: Sequence]

Request Version: HTTP/1.1

Status Code: 200

Response Phrase: OK

Assess Control-Allow-Origin: *\r\n ,

Content-Type: text/html; charset=utf-8\r\n

Date: Sun, 13 Mar 2018 12:37:31 CMT\r\n

Server: ngirx/1.6.2\r\n

Set-Cookie: first_referrer=; Path=/\r\n

Content-length: 17\r\n

[Content length: 17]

Connection: keep-alive\r\n

\r\n

Line-based text data: text/html

Saint Petersburg\n

^C2 packets captured

Сетевой сканер nmap

Сетевой сканер W:[nmap] предназначен для поиска служб по их открытым портам на указанных узлах сети. В примере из листинга ниже показан процесс и результаты сканирования узла 192.168.190.1 (беспроводной маршрутизатор, арендованный у провайдера Интернета).

Сканирование выполнялось способом TCP connect scan т. е. предпринималась попытка установить соединение TCP с каждым из 1000 «популярных» портов. В результате оказывается, что на узле открыты 7 портов, 3 из которых недоступны (вероятно, отфильтрованы по IP-адресу), а оставшиеся 4 (в частности, порты 53/DNS и 80/WWW) доступны  для присоединения.

Сетевой сканер nmap

lumpy@ubuntu:~$ nmap -n -vvv —reason 192.168.100.1

Starting Nmap 5.21 ( http://nnap.org ) at 2018-04-03 17:48 MSK

Initiating Ping Scan at 17:48

Scanning 192.168.100.1 [2 ports]
Completed Ping Scan at 17:48, 0.00s elapsed (1 total hosts)

Initiating Connect Scan at 17:48

Scanning 192.168.100.1 [1000 ports]

Discovered open port 80/tcp on 192.168.100.1

Discovered open port 53/tcp on 192.168.100.1

Discovered open port 49152/tcp on 192.168.100.1

Discovered open port 49153/tcp on 192.168.100.1

Completed Connect Scan at 17:48, 1.58s elapsed (1000 total ports)

Nmap scan report for 192.168.100.1

Host is up, received conn-refused (0.055s latency).

Scanned at 2018-04-03 17:48:53 MSK for 2s

Not shown: 993 closed ports

Reason: 993 conn-refused

PORT           STATE      SERVICE        REASON
21/tcp          filtered      ftp                    no-response
22/tcp         filtered      ssh                    no-response
23/tcp         filtered      telnet               no-response
53/tcp         open          domain            syn-ack
80/tcp         open          http                 syn-ack
49152/tcp   open          unknown        syn-ack
49153/tcp   open          unknown        syn-ack

Read data files from: /usr/share/nmap

Nmap done: 1 IP address (1 host up) scanned in 1.63 seconds

Мониторинг сетевых соединений процессов

Интерфейс сокетов в целом является продолжением идеи «файлов», специально предназначенных для межпроцессного взаимодействия, некоторым развитием «файловой» природы простейших именованных и неименованных каналов.

Таким образом, сокеты сетевых семейств ip, ipv6 и пр. обладают «файловыми» свойствами точно так же, как и локальные сокеты unix. Например, каждый сетевой сокет идентифицируется при помощи файлового дескриптора в таблице открытых файлов процесса, что проиллюстрировано в листинге ниже при помощи lsof и ss.

Файловые дескрипторы сетевых сокетов

 

lumpy@ubuntu:~$ pgrep lftp

8715

lumpy@ubuntu:~$ lsof -t :5900

COMMAND  PID  USER   FD   TYPE   DEVICE   SIZE/OF  NODE    NAME
lftp                  8715 lumpy   cwd  DIR      252,0          4096 20430868 /home/lumpy
lftp                  8715  lumpy   rtd   DIR      252,0         4096                 2     /
lftp                  8715 lumpy    txt    REG     252,0    905324    3811570      /usr/bin/lftp
lftp                  8715  lumpy   0u    CHR     136,1           0t0                  4    /dev/pts/1
lftp                  8715  lumpy    1u    CHR     136,1           0t0                  4    /dev/pts/1
lftp                  8715  lumpy    2u    CHR     136,1          0t0                   4    /dev/pts/1
lftp                  8715  lumpy    3r     DIR      252,0      4096   20430868 /  home/lumpy
lftp                  8715  lumpy    4u    IPv4 16686880     0t0               TCP   ubuntu.local:35561>mirror.yandex.ru:ftp (ESTAB..
lumpy@ubuntu:~$ sudo ss -p dport = :21
State     Recv-Q Send-Q Local Address:Port            Peer Address: Port
ESTAB  0            0             192.168.100.5:35561         213.180.204.183: ftp           users:((«lftp»,8715,4^))

Более детально проследить за жизненным циклом сетевого сокета позволяет трассировка «сокетных» системных вызовов socket, connect, bind, listen, accept, send и recv.

В примере из листинга ниже показана трассировка «клиентского» сокета пользовательского агента curl, загружающего Web-pecypc http://www.gnu.org/graphlcs/ agnuheadterm-xterm.txt.

Системный вызов socket создает потоковый сокет семейства ip, которому назначается первый свободный файловый дескриптор FD=3, после чего системный вызов connect инициирует установку соединения  этого сокета с портом 80 узла 208.118.235.148. После установки соединения системный вызов send отсылает Web-серверу команду W: [HTTP] протокола GET на получение запрашиваемого ресурса, а несколько системных вызовов recv получают запрошенный ресурс.

Сетевой клиент: системные вызовы socket, connect, send и recv

lumpy@ubunu:~$ straсe -fe traсe=network curl http://ww.gru.org/graphics/agnuheadterm-xterm.txt

socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3

setsockopt(3, SOL_SOCKET, SO_KEEPALIVE, [1], 4) = 0

connect(3, {sa_farrlly=AF_INET, sin_port=htons(80), sin_addr=inet_addr(«208.118.235.148»)},
16) = -1 EINPROGRESS (Operation now in progress)
getsod<cpt(3, SOL_SOCKET, S0_ERROR, [0], [4]) = 0
getpeername(3, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr( «208.138.235.148»)}, [16]) = 0 getsockname(3, (sa_family=AF_INET, sin_port=htons(51090), sin_addr=inet_addr(«192.168.100.4»)}, [16]) = 0  send(3, «GET /graphics/agnuheadterm-xtem»…, 192, MSG_NOSIGNAL) = 192

recv(3, «HTTP/1.1 200 OK\r\nDate: Wed, 06 3″…, 16384, 0) = 1400
recv(3, «m\342\226\204\33[48;5;242n\33[38;5;244n\342\226\204\33[4″…, 14770, 0) = 1400

recv(3, 5; 59m\342\226\200\33[38; 5;240n\342\226\204\33[48; 5; 24″…, 13370, 0) = 7000

recv(3, » \33[48;5;251n \33[48;5;231m 6370, 0) = 1400
recv(3, «8; 5; 242n\33[38; 5;237m\342\226\204\33[48; 5; 16m’…, 4970, 0) = 4970

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

В примере из листинга ниже показана трассировка простейшего Web-сервера, реализованного модулем SinpleHTTPServer языка программирования W:[python]. Web-сервер запускается из «рабочего» каталога /usr/share/doc и предоставляет Web-доступ ко всем файлам этого каталога, используя «нестандартный» порт 8000.

Для начала при помощи socket создается потоковый сокет семейства ip, которому назначается первый свободный файловый дескриптор FD = 3. Этот сокет и будет выступать в роли «слушающего», т. е. принимающего клиентские соединения, поэтому ему «привязывается» адрес 0.0.0.0 и порт 8000 (куда и будут поступать клиентские соединения) при помощи системного вызова bind, а сам сокет переводится в слушающее состояние системным вызовом listen.

Все входящие клиентские соединения ставятся в очередь «слушающего» сокета и изымаются из нее системным вызовом accept, который создает для каждого клиентского соединения, собственный сокет (клонируя слушающий).. При поступлении клиентского соединения был создан новый «обслуживающий» сокет с файловым дескриптором FD = 4, используя который посредством recv была получена W:[HTTP] команда get на доступ к «корневому» ресурсу сервера, а с помощью нескольких системных вызовов send в ответ был направлен сформированный HTML-список файлов в каталоге /usr/share/doc.

Сетевой сервер: системные вызовы socket, bind, listen, accept, send и recv

lumpy@ubuntu:~$ cd /usr/share/doc
lumpy@ubuntu:/usr/share/doc$ strace —fe trace=network python -n SimpLeHTTPServer

socket(PF_INET, SOCK_STREAM, IPPROTO) = 3

setsockopt(3, SOL_SOCKET, 90_REUSEADDR, [1], 4) = 0
bind(3, {sa_family=AF_INET, sin_port=htons(8800), sin_addr=inet_addr( «0.0.0.0»)}, 16) = 0

getsockname(3, {sa_family=AF_INET, sin_port=htons(8000), sin_addr=inet_addr(«0.0.0.0,’)}, [16]) = 0 getsockname(3, {sa_family=AF_INET, sin_port=htons(8000), sin_addr=inet_addr(«0.0.0.0,’)}, [16]) = 0

listen(3, 5)                                                                = 0
getsockname(3, {sa_family=AF_INET, sin_port=htons(8000), sin_addr=inet_addr(«0.0.0.0»)}, [16]) = 0

Serving HTTP on 0.0.0.0 port 8000 …
accept(3, {sa_family=AF_INET, sin_port=htons(5S094), sin_addr=inet_addr(«127.0.0.1»)}, [16]) = 4

recv(4 «GET / HTTP/1. 1\r\nUser-Agent: Wget»…, 8192, 0) = 111

localhost — — [03/Apr/2018 19:52:14] «GET / HTTP/1.1″ 200 —

send(4 ‘HTTP/1.0 200 CK\r\n», 17, 0) = 17

send(4, «Server: SimpleHTTP/0.6 Python/2.»…, 37, 0) = 37

send(4, «Date: Sun, 03 Apr 2016 16:52:14 «…, 37, 0) = 37

send(4, «Content-type: text/html; charset»…, 40, 0) = 40

send(4, «Content-length: 140946\r\n», 24, 0) = 24

send(4, «\r\n», 2, 0) = 2

send(4, «<!DOCTYPE html PUBLIC \»-/W3C/D)»…, 8192, 0) = 8192

send(4, «video-qxl/</a>\n<li><a href=\»xser»…, 1682, 0) = 1682

shutdown(4, 1 /* send */) = 0^C

lumpy@ubuntu:~$ wget http://ubuntu: 8000

—2018-04-03 19:52:14- http://ubuntu: 8000/

Распознаётся ubuntu (ubuntu).., 127.0.1.1

Подключение к ubuntu (ubuntu)|127.0.1.1|:8000… соединение установлено.

HTTP-запрос отправлен. Ожидание ответа… 200 OK

Длина: 140946 (138К) [text/html]

Сохранение в: «index.html.1»

100%[ =======================>] 140 946 -K/s за 0,003s

2018-04-03 19:52:14 (51,0 MB/s) — «index.htnl. 1» сохранён [140946/140946]

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