Что такое сырой ip пакет

Статья ASM для х86 (5.5) RAW сокеты в XP и Win7

Возможность работы с сокетами предоставляют нам системные "Поставщики услуг" . Именно поставщик ограничивает тот или иной функционал, например возможность использовать протокол ICMP или девственные RAW-сокеты. В отношении WinSock, базовых поставщиков всего двое – это библиотека mswsock.dll , со-своей подругой rsvpsp.dll (заправляет функциями NetBIOS).

Поставщик подключается к WinSock при помощи имеющегося в нём интерфейса SPI — "Service Provider Interface". После регистрации поставщика в системе, служба Winsock использует его для реализации определённых функций сокета, например setsockopt() , ioctlsocket() , connect() и прочих для тех типов адресов, которые поставщик указал в качестве им реализуемых. Тип адреса под виндой всегда одинаковый – это AF_INET с константой =2 (для сетей IPv4).

Сторонние поставщики небезопасны и Microsoft относится к ним с презрением. Они могут с лёгкостью обойти надстройки безопасности сетевых протоколов, поскольку имеют прямой доступ к ядру операционной системы, а точнее к транспортной её части WSK (Winsock Kernel, в младенчестве TDI). Финт с установкой самих себя в качестве поставщика многоуровневой службы по модели "Layered Service Provider" ( LSP ) часто использует малварь и шпионские программы.

5.5.0. Системные ограничения WinSock

На борту Win имеется консольная утилита NETSH (Network Shell). На запрос вида winsock show catalog она отзывается портянкой с описанием услуг базовых поставщиков. Поскольку лог получается большой и не вмещается в консольную форточку, имеет смысл перенаправить вывод в файл. Вот пример, в котором я принебрёг деталями не интересного нам протокола NetBIOS. Как видим – выбор не велик, и попытки заставить сокеты работать с отсутствующими здесь протоколами, обречены на провал:

Ого… даже RAW имеется в списке! Круто!
Но бросать чепчики в воздух рановато – всё/это для отвода глаз, чтобы армия юзеров не посчитали систему ущербной. Продуманы из Microsoft не придумали ничего лучше, как ввести RAW-сокеты на уровне приложений, и тут-же ограничить их функционал на уровне ядра. Такой подход вводит в ступор большинство программистов, поскольку мы можем создавать сырьё, но первая-же операция с ними, приводит к ошибке. В точку здесь попадает определение – праздник закрытых дверей.

Однако не всё так плохо, и с барского стола нам тоже кое-что перепало. Нужно запомнить одно правило – в большинстве случаях, операции с сырыми сокетами под WinXP+ возможны только для входящих пакетов. Если стража системы пронюхает исходящий пакет RAW, то безжалостно уничтожит его, не дав возможности даже объясниться. Вот цитата из MSDN

В Win-7, Vista, XP(sp3) возможность отправки трафика по сырым сокетам была ограничена несколькими способами:

• Данные TCP не могут быть отправлены через сырые сокеты.
• Вызов функции bind() с сырым сокетом для протокола IPPROTO_TCP запрещён.
• UDP-трафик с недопустимым адресом отправителя не может быть отправлен через сырые сокеты.
• IP-адрес отправителя для любой исходящей UDP-дейтаграммы должен существовать в сетевом интерфейсе, или датаграмма удаляется.

Эти изменения были сделаны, чтобы ограничить способность вредоносного кода создавать распределённые атаки типа DDoS и возможность отправки TCP/IP-пакетов с поддельным IP-адресом источника.

Вся прелесть сырых сокетов в том, чтобы самому формировать заголовки пакетов – иначе они и даром не нужны. Но что сделали макрушники? Они ввели RAW, но предписывают использовать их только внутри своего узла. Это вообще труба! Да. мы можем отправлять сырые пакеты с валидным/нашим IP, но это превращает сырой сокет в обычный, и непонятно зачем вообще называть его RAW.

5.5.1. Тёмная сторона сокетов

В штанинах Winsock имеется функция для тюннинга сокетов – это setsockopt() . Характер опций во многом зависит от поставщика и не придаётся громкой огласке. Поэтому мелкософт выложила у себя только некоторые из них, хотя на самом деле список намного обширней. Вот прототип функции и некоторые (интересные на мой взгляд) рычаги управления.

С дефолтными настройками сокетов, всю черновую работу по инкапсуляции и заполнению заголовков всех уровней выполняет служба Winsock. С одной стороны это освобождает нас от низкоуровневой рутины, с другой – навязывает свои правила. Для таких случаев, у сокетов имеется опция IP-HDRINCL (Include Header, подключать заголовки = да/нет), которая предписывает службе Winsock не вмешиваться в этот процесс и что заголовки пакетов мы планируем формировать сами.

Ещё одна опция – это TCP_NODELAY , или нет задержкам! Столь философскую мысль выдвинул некто Джон Нейгл, и посоветовал внедрить в сокеты механизм, который позволял-бы не передавать по линии связи слишком мелкие пакеты, а копить их до определённого размера, после чего выстрелить в сеть дробью.

Дело в том, что по-умолчанию никто это дело не контролирует, и функции отправки данных send() абсолютно по-барабану, сколько полезных данных (payload) содержит пакет. В нём может быть всего 1-байт, а остальное – заголовки Header . КПД такого обмена стремится к нулю, и только занимает пропускную способность канала. Вот Нейгл и предложил перед отправкой тестить пайлоад, и собирать пакет по краполям, в один баш. Ясно, что при этом получаются задержки, и первыми бросились на амбразуру разработчики сетевых игр, для которых такие тайм-ауты критичны. Опция по-умолчанию отключена и пакеты буферизуются.

5.5.1(1) Общаемся с драйвером сетевой карты

Другой полезной фишкой является возможность передавать команды напрямую драйверу транспорта WSK. Как мы помним, на системах х32 пространство памяти ОЗУ разделено на две равные части – нижняя половина от 0x1000 и до адреса 0x7FFFFFFF выделена в наше юзерское распоряжение, а выше 0х80000000 и до самых небес системное ядро забирает себе. Доступ к ядерной памяти контролируется центральным процессором CPU на аппаратном уровне, и любые попытки вторжения в кернел жёстко пресекаются сторожем страниц PageGuard.

Однако большинство служб и системных сервисов сами тусуются в пространстве юзера, и по роду своей деятельности должны общаться с ядром. Поэтому полностью изолировать юзера на необитаемый остров нельзя, в результате чего появился шлюз в Kernel в виде функции DeviceIoControl() . Эта функция универсальна и не привязана к какому-то одному драйверу. В качестве аргумента она ждёт код-запроса , по которому передаёт сообщение только одному из многочисленных драйверов в системе. Необнародованный список кодов затмит роман "Война и мир", а с документированным листом можно ознакомиться например здесь (для Winsock искать (Ctrl+F) по маске TDI и NDIS).

Дочерней по отношению к DeviceIoControl() является функция ioctlsocket() . Эту функцию можно использовать для любого сокета в любом состоянии, независимо от протокола и подсистемы связи. Прототип функции выглядит так (нуль на выходе в EAX свидетельствует об успешной операции):

5.5.2. Историческая справка

Ещё во-времена динозавров, разработчикам приходилось долго и муторно тестить поддержку сети на ошибки, в результате чего на свет появились "анализаторы пакетов" . При помощи анализа, админы и службы тех/поддержки могут наблюдать за передвижением трафика в сети, диагностировать и устранять возникающие проблемы и т.д. Но как это часто бывает, обычный анализатор превратился в грозное оружие под названием "сниффер" .

В былые времена, используя снифер хакеры рыбачили в сети и вылавливали из неё пароли и другую конфиденциальную инфу. Особенно актуально это было для таких протоколов как Telnet, где трафик гуляет в незашифрованном виде. Прослушивание линии стало возможным благодаря особенности архитектуры Ethernet, в которой все узлы подключены к одной среде передачи данных и делят её по-братски. Для прослушки локальной сети не нужно резать кабели – в ней и так все связаны кровными узами.

Но беззаботная жизнь на хабах продолжалась не долго.. В локальную сеть, как слон в посудную лавку, ввалился коммутатор Switch . Теперь хоть линия передачи как и прежде одна, зато узлы в ней разделены логически. Виной тому – всего-то крошечный логический элемент с аббревиатурой "И" . Он имеет два входа и один выход, на который вешают узел сети. Если "И" на первый "И" на второй вход подать единицу, то затвор на выходе открывается и трафик поступает на подключённый к выходу узел. Таким образом, обычный логический элемент из двух транзисторов полностью перекрыл кислород сниферам, оставив в их владениях периметр только до коммутатора.

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

switch.png

Для простоты понимания, в примере с коммутатором я исключил из схемы дешифратор . Этот электронный компонент может иметь, например, 4-входа и 16-выходов, чего достаточно для 16-портовых свитчей. На 4-входа дешифратора поступает двоичная тетрада последнего байта IP-адреса (см.рис.выше), по которой он подключает один из 16-ти выходных портов (бинарная логика).

Если собрать всё во-едино, то получается что в современных сетях снифать пакетики можно только внутри своей локальной сети. Высунуть нос наружу мешает в первую очередь коммутатор, после которого может быть ещё и VPN, и дальше маршрутизатор. В добавок, хоть мы и пронюхаем пакет в своей сетке LAN, всё-равно получить от него профит не получится, т.к. сейчас весь трафик передаётся только в зашифрованном виде и привести его в понятный вид не так просто. Только посмотрите на эту баррикаду, и всё сразу станет ясно:

vpn.png

5.5.3. Практика – пишем сниффер на RAW сокетах

Теперь посмотрим, что представляет из-себя сниффер на генетическом уровне..
Во-первых, нужно перевести сетевую карту в неразборчивый режим Promisc. Для этого задействуем функцию ioctlsocket() с кодом SIO_RCVALL равным 0x98000001 , который отключит в контроллере способность фильтровать трафик на свой/чужой. Теперь остаётся в непрерывном режиме принимать пакеты функцией recv() в свой буфер и выводить его содержимое на экран.

После чтения очередной порции трафика, в буфере получим пакет, формат которого сильно зависит от типа протокола. Можно снабдить программу фильтром протоколов, например чтобы прожка принимала только TCP пакеты, UDP или ICMP. Но в демонстрационном примере лучше принимать всё-подряд, а прикрутить фильтр можно будет позже – главное понять суть.

В независимости от используемого отправителем протокола, пакет в буфере будет начинаться с IP-заголовка, а дальше — в игру вступает уже конкретный протокол. Если вспомнить, как инкапсулируются в пайлоад заголовки, то картина прояснится:

hdr_88.png

Чтобы вытянуть из пакета полезные данные payload, нам придётся сначала в IP-заголовке проверить поле "iph_proto" , где будет указан код протокола, по которому был отправлен данный пакет. Если это IPPROTO_TCP с кодом 0х06 , значит после IP-заголовка идёт 20-байтный TCP-заголовок (см.рис.выше). Для IPPROTO_UDP код будет 0х11 , а для ICMP = 0x01 . Дамп перехваченного пакета в отладчике выглядит так:

shiff_01.png

Ну и немного о деталях самого исходника..
Чтобы вывести тип протокола на экран, придётся по его коду искать соответствующую строку. Для этого я создал таблицу переходов, где первое значение это код-протокола из поля iph_proto заголовка IP, а второе – адрес строки с его именем в секции данных программы. Получив код я ищу его в таблице, и при совпадении беру следующее значение, которое будет указателем на соответствующую строку. Вот образец этой таблицы:

  1. Узнать свой IP и вывести его на экран. Это позволит ориентироваться в адресах – куда, кому, зачем и почему.
  2. Создать сырой RAW-сокет типа IPPROTO_IP , что позволит ловить пакеты всех предыдущих протоколов в стеке TCP/IP. Например если создать сокет типа IPPROTO_UDP , то получим фильтр пакетов и кроме дейтаграмм UDP наш снифер нишиша не получит.
  3. Перевести сетевой контролёр в режим Promisc – без этого ничего не выйдет. Результаты всех операций будем выводить на экран.
  4. Зациклиться на приёме пакетов функцией recv() и внутри каждого цикла парсить приёмный буфер. Здесь я ввёл счётчик.. можете установить его на любое кол-во пакетов.
  5. Вот собственно и все шаги..

shiff_02.png

Как показывает скрин, снифер исправно нюхает сеть и если его не остановить, то в поле зрения попадаются интересные пакеты, в которых IP-адреса вообще не принадлежат моей сети. Судя по всему, без моего ведома кто-то периодически стучится в сеть в поисках своего сервера (или демона на моём узле). По сути прожка вместе с IP выводит и порты, так-что вычислить софтину и заинжектить ей ледокаин пониже радикулита, будет не сложно.
———————————————————

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

HackWare.ru

Этичный хакинг и тестирование на проникновение, информационная безопасность

Трассировка сетевого маршрута

Оглавление

Что такое трассировка. Для чего нужна трассировка узлов

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

Трассировка может применяться для выявления связанных с работой компьютерной сети проблем, а также для исследования сети (определения структуры сети, поиска промежуточных сетевых узлов).

Принципы работы трассировки

Пересылаемые сетевые пакеты состоят из двух областей: заголовки и данные. В заголовках находится разная информация, например, IP адреса пункта отправки и пункта назначения, порты отправки и назначения, тип пакета, контрольная сумма пакета и прочее. Среди полей заголовка, у IP протокола есть такое поле как time to live (TTL) — время жизни пакета. Это счётчик с числом, которое уменьшается на единицу каждый раз, когда пакет проходит новый узел. Этот счётчик сделан для того, чтобы проблемный пакет (например, при ошибке, повлекшей закольцованный маршрут) не путешествовал по сети бесконечно. То есть любой пакет пройдя определённое количество узлов в конце-концов достигнет точки назначения или будет отброшен одним из узлов сети, когда закончится «время жизни».

Когда счётчик TTL становится равным нулю, очередной шлюз просто не пересылает этот пакет дальше. Но при этом шлюз на тот IP адрес, откуда пришёл пакет с истёкшим временем жизни, отправляет по протоколу ICMP ответ TIME_EXCEEDED (время жизни кончилось). И этот ответ содержит IP адрес шлюза, где пакет закончил своё существование.

Так вот, суть трассировки в том, что отправляется один пакет с временем жизни (TTL) установленным на единицу — первый шлюз уменьшает значение на единицу, смотрит, что счётчик стал равен нулю, никуда не отправляет этот пакет, зато нам отправляет ответ, что пакет «умер». Мы и так знаем, что пакет умер — из этого ответа нас интересует только IP адрес шлюза, где с пакетом случилось это несчастье. Затем отправляется пакет со счётчиком установленным на 2 — пакет проходит первый шлюз (его IP мы уже знаем), но несчастье (счётчик достигает нуля) с ним случается уже на втором шлюзе — мы получаем ICMP ответ с IP этого шлюза. Затем отправляется следующий пакет и т. д., пока не будут определены все узлы до нужного нам сетевого хоста.

Виды трассировки

Имеется несколько видов трассировки. В основном они различаются отправляемым пакетом — это может быть пакет транспортного протокола TCP или UDP, либо протокола межсетевых управляющих сообщений ICMP, либо сырой IP пакет.

Иногда из-за файерволов или настройки сетевых узлов не удаётся получить IP адрес узла. В этом случае можно попробовать использовать другой метод, который может дать результаты.

Это можно проиллюстрировать на следующих двух примерах трассировки до одного и того же хоста:

Звёздочки говорят о том, что мы не узнали часть узлов.

Благодаря изменению метода трассировки удалось узнать все промежуточные узлы. Другие методы могут дать отличные от показанных результаты.

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

Программы для трассировки

Имеется много разных утилит для трассировки, некоторые из них поддерживают различные методы трассировки. Примеры таких программ:

  • traceroute
  • tracepath
  • mtr и mtr-gtk (соответственно, консольная и графическая версия)
  • lft
  • tcptraceroute

Ещё определять узлы маршрута пакета можно с помощью Nmap (несколькими способами) и даже с помощью ping!

В этой статье я рассмотрю все перечисленные выше программы. Начнём знакомство с traceroute, поскольку в ней реализовано больше всего методов сканирования.

traceroute

Как пользоваться traceroute

Для запуска трассировки достаточно указать IP или сайт, до которого вы хотите проследить маршрут:

Если вас интересуют ближайшие узлы (локальная сеть, например), то в качестве конечного пункта можно выбрать любой сайт.

Методы трассировки в traceroute

В современном сетевом окружении традиционные методы трассировки не всегда применимы из-за широкого распространения файерволов. Такие файерволы фильтруют «маловероятные» UDP порты или даже ICMP echo пакеты. Для решения этой проблемы реализованы некоторые дополнительные методы трассировки сети (включая tcp). Эти методы пытаются использовать другие протокол и порт источника/назначения, чтобы обойти файерволы (чтобы файерволы воспринимали их как просто начало сетевой сессии разрешённого типа).

У разных методов есть специфичные для них опции — они зависят от используемого протокола. Эти опции метода можно указать с помощью опции -O. Несколько опций разделяются запятой (или используйте в командной строке несколько -O). Каждый метод может иметь свои собственные особенные опции или может не иметь из вовсе.

default

Метод по умолчанию — используется если не указан другой, либо можно указать явно опцией -M default. Это традиционный, древний метод трассировки маршрута.

Пакетами зондирования являются udp датаграммы с так называемым "unlikely" (маловероятным) портом назначения. Первым "unlikely" портом зондирования является 33434 затем для каждого следующего зонда он увеличивается на единицу. Поскольку ожидается, что порт не используется, то хост назначения обычно возвращает конечный ответ "icmp unreach port". Номер порта можно поменять (об этом ниже).

Данный метод могут выполнять непривилегированные пользователи.

icmp

Сейчас это самый типичный метод, он использует в качестве зондов пакеты icmp echo. Если вы можете пинговать хост назначения, то icmp трассировка также применима. Для выбора этого метода используется опция -M icmp или её короткий вариант -I.

Этот метод разрешён для непривилегированных пользователей.

У этого метода имеется две специфичные опции

raw

Использовать только сырые сокеты (традиционный способ).

По умолчанию этот методы пробуется первым (по причинам совместимости), затем новые сокеты dgram icmp в качестве резервного варианта.

dgram

Использовать только сокеты dgram icmp

tcp

Хорошо известный современный метод, предназначен для обхода файерволов. Для использования укажите опцию -M tcp либо короткий вариант -T. Использует постоянный порт назначения (по умолчанию это 80, http).

Если на сетевом пути трассировки присутствуют какие-либо фильтры, то весьма вероятно, что фильтруются «необычные» udp порты (такие, как используется методом по умолчанию) или даже icmp echo (как для icmp), и весь процесс трассировки остановится на таком файерволе. Для обхода сетевого фильтра нам нужно использовать только комбинации из разрешённой пары протокол/порт. Если мы делаем трассировку, допустим, до почтового сервера, то весьма вероятно, что с помощью -T -p 25 мы можем достичь его, даже если с помощью -I не получается это сделать.

Этот метод использует хорошо известную «технику полуоткрытых соединений», благодаря которой приложения на компьютере назначения вовсе не видят наши пакеты для исследования (зонды). Обычно отправляется tcp syn. Для портов, которые не прослушиваются, мы получаем ответ tcp reset — и всё готово. Для активно прослушиваемых портов мы получаем tcp syn+ack, но отвечаем на это tcp reset (вместо ожидаемого tcp ack), таким образом удалённая tcp сессия сбрасывается, а прослушивающее порт приложение даже не получает уведомление.

Для метода tcp имеется несколько опций:

syn,ack,fin,rst,psh,urg,ece,cwr

Устанавливает определённые tcp флаги для пакета зондирования, можно использовать любую их комбинацию.

flags=ЧИСЛО

Устанавливает поле флагов в tcp заголовке на точное ЧИСЛО.

ecn

Отправляет пакет syn с флагами tcp ECE и CWR (для Explicit Congestion Notification, rfc3168).

sack,timestamps,window_scaling

Использует соответствующую опцию tcp заголовка в исходящем пакете зондирвоания.

sysctl

Использует настройки текущей sysctl (/proc/sys/net/*) для опций tcp заголовка для вышеприведённых опций и ecn. Всегда установлено на значение по умолчанию, если ничего не указано.

mss=ЧИСЛО

Использовать значение ЧИСЛО для опции tcp заголовка maxseg (когда syn).

info

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

Опциями по умолчанию являются syn,sysctl.

tcpconn

Начальная реализация tcp метода просто использующего вызов connect(2), который открывает полную tcp сессию. Не рекомендуется для нормального использование, поскольку всегда влияет на приложение прослушивающее порт на хосте назначения.

Для задействования этого метода используйте опцию -M tcpconn.

udp

Использует udp датаграммы с постоянным портом назначения (по умолчанию 53, dns). Также предназначена для обхода файерволов. Для использования этого метода трассировки укажите опцию -M udp или сокращённый вариант -U.

Обратите внимание, что в отличие от tcp метода, соответствующее приложение на хосте назначения всегда получает наши зонды (со случайными данными) что может смутить его. В большинстве случаев оно не ответит на наши пакеты, поэтому мы никогда не увидим последний хоп (узел) в пути трассировки. (К счастью, кажется что по крайней мере DNS серверы присылают какой-то ответ).

Этот метод не требует повышенных прав.

udplite

Использует для зондов датаграммы udplite (с постоянным портом назначения, по умолчанию 53). Для активации этого метода укажите опцию -M udplite или -UL.

Этот метод не требует повышенных прав.

coverage=ЧИСЛО

Устанавливает покрытие отправки udplite на ЧИСЛО.

dccp

Использует для зондов пакеты DCCP Request (rfc4340). Этот метод можно задействовать опциями -M dccp или -D.

Этот метод использует такую же «технику полуоткрытых соединений», которая используется для TCP. Портом назначения по умолчанию является 33434.

service=ЧИСЛО

Устанавливает сервисный код DCCP на ЧИСЛО (по умолчанию это 1885957735).

raw

Этим методом отправляются сырые пакеты указанного протокола. Для вызова этого метода используйте опцию -M raw или -P ПРОТОКОЛ.

Не используется специфичные для транспортных протоколов заголовки, только заголовки IP протокола.

Подразумевает -N 1 -w 5 .

protocol=ПРОТОКОЛ

Использовать IP ПРОТОКОЛ (по умолчанию 253).

Список протоколов, инкапсулируемых в IP на Википедии, в первоисточнике.

Как ускорить трассировку. Как отключить обратное преобразование IP в имена хостов при трассировке

Чуть выше описаны принципы работы трассировки — отправка пакетов с постоянно увеличивающимся сроком жизни. На самом деле — все пакеты (с TTL 1, с TTL 2, с TTL 3 и т. д.) можно отправить одновременно. И именно так это и происходит — по умолчанию отправляются 16 пакетов за раз (количество можно изменить опцией -N). Это делается для ускорения трассировки.

Поэтому в действительности трассировка выполняется очень быстро. Те 1-2 секунды, которые как нам кажется определяются узлы сети, на самом деле тратятся на получение имён хостов для IP. С помощью опции -n это можно отключить.

Используя программу time можно замерить время выполнения программы с опцией -n и без неё:

Время выполнения самой трассировки 0,206s, а время трассировка+определение имени хостов получилось 2,360s, то есть в 10 раз дольше.

Трассировка IPv6

По умолчанию программа получает IP для указанного для трассировки хоста и на основе полученного IP адреса автоматически определяет, какой протокол используется: IPv4 или IPv6. Если получены IP для обоих протоколов, то по умолчанию используется IPv4.

С помощью опций -4 и -6 можно явно указать желаемый протокол.

Сеть, из которой делается трассировка с опцией -6, должна поддерживать IPv6, иначе ничего не получится.

Изменение порта

Поменять порт назначения можно с помощью опции:

Для UDP трассировки указанный порт будет использовать в качестве базового (номер порта назначения будет увеличиваться для каждого зонда).

Для ICMP трассировки указанное число будет использоваться в качестве начальное значение ICMP последовательности (также увеличенное для каждого зонда).

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

Обычно это не требуется, но также можно указать и порт источника, это делается опцией:

Эта опция подразумевает -N 1 -w 5 . Обычно исходные порты (если это примениму к выбранному методу трассировки) выбираются системой.

Как начать трассировку с определённого узла. Как уменьшить или увеличить число узлов для трассировки

С помощью опции -f можно указать номер узла, с которого следует начать трассировку. По умолчание значение равно 1.

С помощью опции -m можно указать максимальное число хопов для трассировки, по умолчанию установлено на 30.

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

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

Как показать к какой автономной системе принадлежит узел при трассировке

Каждый IP адрес привязан к Автономной системе (AS). С помощью опции -A вы можете включить запрос номера AS для каждого узла по пути трассировки, например:

Как можно видеть, автономная система не определена для локальных IP 10.*.*.* — что вполне логично, так как эти адреса никому не назначены. Что касается адреса 192.168.1.1 и автономной единицы AS198949, то это какая-то ошибка.

Как можно увидеть из вывода предыдущей команды, первые четыре узла имеют локальный IP адреса. Узлы с 5 по 9 принадлежат одной автономной системе AS38082/AS7470. Предпоследние два узла принадлежат одной автономной системе AS12389 и последние два узла также принадлежат одной автономной системе AS48666 — интернет-провайдеру, на котором размещён сайт suip.biz.

Опции traceroute

У команды traceroute имеются и другие опции которые могут вам пригодиться. Вы можете ознакомиться с ними в справочной странице данной программы:

tracepath

Программа tracepath схожа с traceroute, но использует только одну технику трассировки: UDP, для которой можно указать свой порт. Из-за выбранной техники, программа не требует повышенных привилегий.

В первой колонке рядом с номера узла может стоять знак вопроса — он означает, что в присланном ответе отсутствует номер TTL и программа пытается его предположить.

Вместо звёздочек, если IP не узнан, пишется no reply.

В последнем столбце может быть цифра и слово asymm. Слово asymm означает, что маршрут является ассиметричным — то есть от нас до этого узла пакет идёт по одному пути, а от этого узла к нам пакет проходит по другому пути. Цифра означает возможное количество хопов от этого узла до нас — но информация не является надёжной.

У tracepath не очень много опций:

-4

Использовать только IPv4

-6

Использовать только IPv6

-n

Не печатать имя хоста, а печатать цифровое значение IP.

-b

Печатать и имя хоста и IP адрес в цифровом виде.

-l

Установить начальную длину пакета вместо 65535 для tracepath или 128000 для tracepath6.

-m

Установить максимальное число хопов (или максимум TTL) — то есть количество максимально «простукиваемых» узлов. По умолчанию 30.

-p

Установить начальный порт назначения.

mtr и mtr-gtk (консольная и графическая версия)

Программа mtr совмещает в себе функциональность программа traceroute и ping в едином инструменте диагностики сети. То есть эта программа показывает маршрут до указанного узла и непрерывно пингует каждые хоп и при этом собирает общую статистику потерь — на основе этих данных можно определить проблемный узел, на котором теряются пакеты.

Данная программа поддерживает несколько методов трассировки.

Также она поддерживает разные форматы вывода для сохранения результатов, например, опция -C, —csv для сохранения результатов в формате CSV (обратите внимание, что на самом в качестве разделителя используется не запятая, а точка с запятой), а также опция -j, —json для сохранения в формате вывода JSON.

С помощью опции -n, —no-dns можно отключить преобразование IP в имена хостов.

Опцией -b, —-show-ips можно включить отображение и имён хостов, и IP адресов.

Опцией -y n, —ipinfo n можно настроить вывод дополнительной информации о каждом IP хопа. В качестве n нужно указать цифру, которая означает:

У меня при любых значениях -y всегда показывается только номер автономной системы. К счастью, между различными видами можно переключаться по кругу используя кнопку y:

Опция -z, —aslookup отображает номер Автономной Системы (AS) для каждого хопа.

Опция -f NUM используется для установки номера первого TTL. По умолчанию равно 1.

Опция -m указывать максимальное число хопов (максимальное значение time-to-live) которое будет обрабатываться при трассировке. По умолчанию равно 30.

Опция -U ЧИСЛО устанавливает максимум незнакомых хостов. По умолчанию равно 5. Видимо, после достижения этого значения дальнейшая трассировка будет остановлена.

С помощью опции -u, —udp программа будет использовать датаграммы UDP вместо ICMP ECHO.

А опцией -T, —tcp можно установить использование TCP SYN пакетов вместо ICMP ECHO. PACKETSIZE игнорируется, поскольку SYN пакеты не могут содержать данные.

В mtr можно использовать даже SCTP протокол для трассировки, для этого укажите опцию -S, —sctp и будет задействованы пакеты Stream Control Transmission Protocol вместо ICMP ECHO.

Во время работы программы доступны интерактивные команды. Если нажать на d, то можно переключаться между различными отображениями:

Кнопкой r можно сбросить статистику.

Кнопкой o можно поменять порядок полей. Кстати, опцией -o можно установить, какие поля вы хотите отображать и их последовательность. Подробности смотрите по:

Программа lft имеет много опций трассировки и из описание следует, что программа пробует несколько комбинаций и автоматически выбирает лучшее решение. Честно говоря, я этого не заметил: результаты с ручным перебором разных методов трассировки позволяют подобрать наилучший вариант.

Программа хорошо документирована и при желании может использоваться в качестве альтернативы traceroute.

tcptraceroute

В программе tcptraceroute используются пакеты только одного протокола TCP. В заголовках этих пакетов опциями можно установить разные флаги. В программе traceroute также можно устанавливать флаги протокола TCP, причём возможностей для настройки больше.

Трассировка сети в Nmap

В Nmap для трассировки есть опция —traceroute, пример трассировки до сайта suip.biz:

Если вы не хотите сканировать порты, а хотите просто выполнить трассировку, то добавьте опцию -sn:

Кстати, это значительно сократить время до вывода результатов.

Бывает, что выводимые при трассировке программой nmap данные не являются полными. В этом случае попробуйте дополнительно добавить опцию -PE:

В Nmap можно установить опции в заголовке пакета IP протокола. Среди этих опций имеется такая, которая сохраняет в заголовке пакета пройденный маршрут. Но у этого варианта есть ряд ограничений:

  • всего 9 слотов
  • некоторые устройства игнорируют эту опцию
  • некоторые устройства вообще не пропускают пакеты с установленной этой опцией

Тем не менее иногда это работает, пример команды:

Обратите внимание на строку:

В ней перечислены первые 9 узлов через которые прошёл пакет.

Трассировка программой ping

Программа ping также умеет записывать маршрут — для этого программу нужно запустить с опцией -R. Она в пакет ECHO_REQUEST добавляет опцию RECORD_ROUTE и отображает буфер маршрута возвращаемых пакетов. Эта та же опция, которую использует Nmap. Ограничения такие же: максимум 9 слотов, многие хосты игнорирует или отбрасывают эту опцию.

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

Несмотря на все ограничения опции RECORD_ROUTE, иногда она бывает единственным вариантом получить хоть какую-то информацию о маршруте, поскольку команда ping практически всегда присутствует и не требует повышенных привилегий для запуска.

Трассировка в Windows

В Windows для трассировки сети имеется встроенная команда tracert. У неё практически отсутствуют опции. Для запуска команды достаточно указать имя удалённого хоста:

Если вам недостаточно такой функциональности, то вы можете установить Nmap в Windows.

Заключение

Трассировка может быть полезной для изучения структуры сети (например, сети вашего Интернет-провайдера), а также для исправления проблем с передачей данных (например, для определения узла, дальше которого пакеты не проходят).

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

Сокеты

XYZ School

— это один конец двустороннего канала связи между двумя программами, работающими в сети. Соединяя вместе два сокета, можно передавать данные между разными процессами (локальными или удаленными). Реализация сокетов обеспечивает инкапсуляцию протоколов сетевого и транспортного уровней.

Первоначально сокеты были разработаны для UNIX в Калифорнийском университете в Беркли. В UNIX обеспечивающий связь метод ввода-вывода следует алгоритму open/read/write/close. Прежде чем ресурс использовать, его нужно открыть, задав соответствующие разрешения и другие параметры. Как только ресурс открыт, из него можно считывать или в него записывать данные. После использования ресурса пользователь должен вызывать метод Close(), чтобы подать сигнал операционной системе о завершении его работы с этим ресурсом.

Когда в операционную систему UNIX были добавлены средства межпроцессного взаимодействия (Inter-Process Communication, IPC) и сетевого обмена, был заимствован привычный шаблон ввода-вывода. Все ресурсы, открытые для связи, в UNIX и Windows идентифицируются дескрипторами. Эти дескрипторы, или описатели (handles), могут указывать на файл, память или какой-либо другой канал связи, а фактически указывают на внутреннюю структуру данных, используемую операционной системой. Сокет, будучи таким же ресурсом, тоже представляется дескриптором. Следовательно, для сокетов жизнь дескриптора можно разделить на три фазы: открыть (создать) сокет, получить из сокета или отправить сокету и в конце концов закрыть сокет.

Интерфейс IPC для взаимодействия между разными процессами построен поверх методов ввода-вывода. Они облегчают для сокетов отправку и получение данных. Каждый целевой объект задается адресом сокета, следовательно, этот адрес можно указать в клиенте, чтобы установить соединение с целью.

Типы сокетов

Существуют два основных типа сокетов — потоковые сокеты и дейтаграммные.

Потоковые сокеты (stream socket)

Потоковый сокет — это сокет с установленным соединением, состоящий из потока байтов, который может быть двунаправленным, т, е. через эту конечную точку приложение может и передавать, и получать данные.

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

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

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

Потоки базируются на явных соединениях: сокет А запрашивает соединение с сокетом В, а сокет В либо соглашается с запросом на установление соединения, либо отвергает его.

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

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

Дейтаграммные сокеты (datagram socket)

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

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

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

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

Сырые сокеты (raw socket)

Главная цель использования сырых сокетов состоит в обходе механизма, с помощью которого компьютер обрабатывает TCP/IP. Это достигается обеспечением специальной реализации стека TCP/IP, замещающей механизм, предоставленный стеком TCP/IP в ядре — пакет непосредственно передается приложению и, следовательно, обрабатывается гораздо эффективнее, чем при проходе через главный стек протоколов клиента.

По определению, — это сокет, который принимает пакеты, обходит уровни TCP и UDP в стеке TCP/IP и отправляет их непосредственно приложению.

При использовании таких сокетов пакет не проходит через фильтр TCP/IP, т.е. никак не обрабатывается, и предстает в своей сырой форме. В таком случае обязанность правильно обработать все данные и выполнить такие действия, как удаление заголовков и разбор полей, ложится на получающее приложение — все равно, что включить в приложение небольшой стек TCP/IP.

Однако нечасто может потребоваться программа, работающая с сырыми сокетами. Если вы не пишете системное программное обеспечение или программу, аналогичную анализатору пакетов, вникать в такие детали не придется. Сырые сокеты главным образом используются при разработке специализированных низкоуровневых протокольных приложений. Например, такие разнообразные утилиты TCP/IP, как trace route, ping или arp, используют сырые сокеты.

Работа с сырыми сокетами требует солидного знания базовых протоколов TCP/UDP/IP.

Порты

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

Сокет состоит из IP-адреса машины и номера порта, используемого приложением TCP. Поскольку IP-адрес уникален в Интернете, а номера портов уникальны на отдельной машине, номера сокетов также уникальны во всем Интернете. Эта характеристика позволяет процессу общаться через сеть с другим процессом исключительно на основании номера сокета.

За определенными службами номера портов зарезервированы — это широко известные номера портов, например порт 21, использующийся в FTP. Ваше приложение может пользоваться любым номером порта, который не был зарезервирован и пока не занят. Агентство Internet Assigned Numbers Authority (IANA) ведет перечень широко известных номеров портов.

Обычно приложение клиент-сервер, использующее сокеты, состоит из двух разных приложений — клиента, инициирующего соединение с целью (сервером), и сервера, ожидающего соединения от клиента.

Например, на стороне клиента, приложение должно знать адрес цели и номер порта. Отправляя запрос на соединение, клиент пытается установить соединение с сервером:

Запрос клиента серверу

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

Взаимодействие клиента и сервера

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

Работа с сокетами в .NET

Поддержку сокетов в .NET обеспечивают классы в пространстве имен System.Net.Sockets — начнем с их краткого описания.

Классы для работы с сокетами
Класс Описание
MulticastOption Класс MulticastOption устанавливает значение IP-адреса для присоединения к IP-группе или для выхода из нее.
NetworkStream Класс NetworkStream реализует базовый класс потока, из которого данные отправляются и в котором они получаются. Это абстракция высокого уровня, представляющая соединение с каналом связи TCP/IP.
TcpClient Класс TcpClient строится на классе Socket, чтобы обеспечить TCP-обслуживание на более высоком уровне. TcpClient предоставляет несколько методов для отправки и получения данных через сеть.
TcpListener Этот класс также построен на низкоуровневом классе Socket. Его основное назначение — серверные приложения. Он ожидает входящие запросы на соединения от клиентов и уведомляет приложение о любых соединениях.
UdpClient UDP — это протокол, не организующий соединение, следовательно, для реализации UDP-обслуживания в .NET требуется другая функциональность.
SocketException Это исключение порождается, когда в сокете возникает ошибка.
Socket Последний класс в пространстве имен System.Net.Sockets — это сам класс Socket. Он обеспечивает базовую функциональность приложения сокета.

Класс Socket

Класс Socket играет важную роль в сетевом программировании, обеспечивая функционирование как клиента, так и сервера. Главным образом, вызовы методов этого класса выполняют необходимые проверки, связанные с безопасностью, в том числе проверяют разрешения системы безопасности, после чего они переправляются к аналогам этих методов в Windows Sockets API.

Прежде чем обращаться к примеру использования класса Socket, рассмотрим некоторые важные свойства и методы этого класса:

Что такое сырой ip пакет

Уровень IPv4 генерирует заголовок IP при посылке пакета, если только для сокета не включён параметр IP_HDRINCL. Если он включён, то пакет должен содержать заголовок IP. Принимаемые пакеты всегда содержат заголовок IP.

Открывать неструктурированные сокеты могут только процессы с идентификатором эффективного пользователя, равным 0, или имеющие мандат CAP_NET_RAW.

Все пакеты или ошибки, совпадающие с номером протокола protocol, указанным неструктурированному сокету, передаются этому сокету. Список допустимых протоколов назначается списком IANA и содержится в getprotobyname(3).

Протокол IPPROTO_RAW подразумевает включённый параметр IP_HDRINCL и позволяет отправлять любой протокол IP, который указан в передаваемом заголовке. Приём любых протоколов IP посредством IPPROTO_RAW через неструктурированные сокеты невозможен.

Поля заголовка IP, изменяемые IP_HDRINCL при передаче
IP Checksum всегда заполняется
Source Address заполняется, если значение равно нулю
Packet Id заполняется, если значение равно нулю
Total Length всегда заполняется

Если указан IP_HDRINCL и заголовок IP имеет ненулевой адрес назначения, то для маршрутизации пакета используется адрес назначения сокета. Если указан MSG_DONTROUTE, то адрес назначения должен ссылаться на локальный интерфейс, иначе в любом случае будет производиться поиск в таблице маршрутизации, но маршруты со шлюзами будут игнорироваться.

Если IP_HDRINCL не указан, то параметры заголовка IP в неструктурированных сокетах могут быть установлены с помощью setsockopt(2); более подробная информация приведена в ip(7).

Начиная с Linux 2.2 все поля заголовка IP и параметры могут быть заданы с помощью параметров сокета IP. Это означает, что неструктурированные сокеты, как правило, необходимы лишь для новых протоколов или протоколов без интерфейса пользователя (например, ICMP).

Принятый пакет передаётся всем подключенным (bound) к этому протоколу неструктурированным сокетам до того, как он будет передан другим обработчикам протоколов (например, протокольным модулям ядра).

Формат адреса

Параметры сокета

Кроме этого, поддерживаются все датаграммные параметры сокетов ip(7) для IPPROTO_IP.

Обработка ошибок

ОШИБКИ

ВЕРСИИ

Код неструктурированных сокетов в версии Linux 2.0 при установленном параметре SO_BSDCOMPAT был специально сделан совместимым с BSD «вплоть до ошибок». Из Linux 2.2 это было удалено.

ЗАМЕЧАНИЯ

Неструктурированный сокет может быть подключён к определённому локальному адресу с помощью вызова bind(2). Если он не подключён, то принимаются все пакеты указанного протокола IP. Кроме того, неструктурированный сокет может быть подключён к определённому сетевому устройству с помощью SO_BINDTODEVICE; смотрите socket(7).

Сокет IPPROTO_RAW предназначен только для отправки. Если вы хотите получать все пакеты IP, используйте сокет packet(7) с протоколом ETH_P_IP. Заметим, что пакетные сокеты, в отличие от неструктурированных сокетов, не собирают пакеты из фрагментов IP.

Если вы хотите получать все пакеты ICMP для датаграммного сокета, то лучше использовать IP_RECVERR на определённом сокете; смотрите ip(7).

Неструктурированные сокеты могут перехватывать в Linux все протоколы IP, даже имеющие протокольный модуль в ядре (такие, как ICMP или TCP). В этом случае пакеты передаются как модулю ядра, так и неструктурированным сокетам. На это нельзя закладываться в переносимых программах, так как многие другие реализации сокетов BSD так не делают.

Linux никогда не изменяет заголовки, полученные от пользователя (за исключением обнуления некоторых полей, как описано в случае с IP_HDRINCL). Такое поведение отличается от поведения многих других реализаций неструктурированных сокетов.

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

Передача через неструктурированный сокет должна осуществляться с помощью протокола IP из sin_port; эта возможность исчезла в Linux 2.2. Метод обхода — использовать IP_HDRINCL.

ДЕФЕКТЫ

Если установлен параметр IP_HDRINCL, датаграммы не будут фрагментированы и их размер будет ограничен MTU интерфейса.

В Linux 2.2 отсутствует настройка протокола IP для отправки sin_port — всегда используется тот протокол, к которому был подключён сокет или который был указан при первом вызове socket(2).

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

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