TCP рукопожатие с сокетом SOCK_RAW - PullRequest
17 голосов
/ 21 сентября 2008

Хорошо, я понимаю, что эта ситуация несколько необычна, но мне нужно установить соединение TCP (трехстороннее рукопожатие), используя только необработанные сокеты (в C, в Linux) - т.е. мне нужно создать заголовки IP и Заголовки TCP сам. Я пишу сервер (поэтому я должен сначала ответить на входящий пакет SYN), и по какой-то причине я не могу понять, что это правильно. Да, я понимаю, что SOCK_STREAM будет обрабатывать это для меня, но по причинам, которые я не хочу вдаваться в это, не вариант.

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

Итак, кто-нибудь знает хороший учебник по использованию необработанных сокетов, который выходит за рамки создания SYN-флудера, или у кого-нибудь есть код, который мог бы сделать это (используя SOCK_RAW, а не SOCK_STREAM)? Буду очень признателен.


MarkR абсолютно прав - проблема в том, что ядро ​​отправляет пакеты сброса в ответ на начальный пакет, потому что считает, что порт закрыт. Ядро бьет меня в ответ и связь умирает. Я уже использовал tcpdump для мониторинга соединения - я должен был быть более наблюдательным и заметил, что есть ДВА ответа, один из которых был сбросом, который испортил все, а также ответ, созданный моей программой. D'OH!

Решение, которое кажется наиболее эффективным, состоит в том, чтобы использовать правило iptables, как предложено MarkR, для блокировки исходящих пакетов. Тем не менее, есть более простой способ сделать это, чем использовать параметр mark, как предлагается. Я просто сопоставляю, установлен ли флаг сброса TCP. Во время нормального соединения это вряд ли понадобится, и для моего приложения не имеет значения, блокирую ли я все исходящие пакеты сброса с используемого порта. Это эффективно блокирует нежелательный ответ ядра, но не мои собственные пакеты. Если порт, который прослушивает моя программа, это 9999, тогда правило iptables выглядит следующим образом:

iptables -t filter -I OUTPUT -p tcp --sport 9999 --tcp-flags RST RST -j DROP

Ответы [ 7 ]

11 голосов
/ 21 сентября 2008

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

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

Один из способов избежать этого - использовать IP-адрес и интерфейс, которые ядро ​​не имеет, используя свой собственный стек IP, - это нормально, но вам придется самостоятельно разбираться с вещами канального уровня (в частности, arp). Для этого потребуется сокет ниже IPPROTO_IP, SOCK_RAW - вам нужен сокет пакета (я думаю).

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

Читать справочные страницы

гнездо (7) ф (7) пакет (7)

которые объясняют различные опции и ioctl, которые применяются к типам сокетов.

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

Извините, я не могу рекомендовать конкретное руководство.

Удачи.

4 голосов
/ 30 июля 2012

Я понимаю, что это старый поток, но вот учебник, который выходит за рамки обычных SYN-флудеров: http://www.enderunix.org/docs/en/rawipspoof/

Надеюсь, это кому-нибудь поможет.

2 голосов
/ 21 сентября 2008

Я не могу вам помочь ни в одном учебнике.

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

Прежде всего, как предложил bmdhacks , получите себе копию wireshark (или tcpdump - но wireshark проще в использовании). Захватите хорошее рукопожатие. Убедитесь, что вы сохранили это.

Захватите одно из ваших рукопожатий, которое терпит неудачу. Wireshark имеет неплохой анализ пакетов и проверку ошибок, поэтому, если есть прямая ошибка, она, вероятно, сообщит вам.

Далее, получите себе копию tcpreplay . Это также должно включать инструмент под названием «tcprewrite». tcprewrite позволит вам разделить ранее сохраненные файлы захвата на два - по одному для каждой стороны рукопожатия. Затем вы можете использовать tcpreplay для воспроизведения одной стороны рукопожатия, чтобы у вас был постоянный набор пакетов для игры.

Затем вы используете wireshark (снова), чтобы проверить свои ответы.

1 голос
/ 21 сентября 2008

У меня нет учебника, но я недавно использовал Wireshark для хорошего отладки некоторых необработанных программ сокетов, которые я делал. Если вы перехватываете отправляемые вами пакеты, wireshark будет хорошо показывать вам, если они искажены или нет. Это также полезно для сравнения с обычным соединением.

0 голосов
/ 02 ноября 2012

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

0 голосов
/ 06 июня 2009

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

Один стек IP с открытым исходным кодом - это lwIP (http://savannah.nongnu.org/projects/lwip/), который обеспечивает полный стек tcp / ip. Его можно запустить в пользовательском режиме, используя SOCK_RAW или pcap.

0 голосов
/ 21 сентября 2008

Существуют структуры для заголовков IP и TCP, объявленные соответственно в netinet / ip.h и netinet / tcp.h. Возможно, вы захотите взглянуть на другие заголовки в этом каталоге, чтобы найти дополнительные макросы и другие полезные вещи.

Вы отправляете пакет с установленным флагом SYN и случайным порядковым номером (x). Вы должны получить SYN + ACK с другой стороны. Этот пакет будет иметь номер подтверждения (y), который указывает следующий порядковый номер, который другая сторона ожидает получить, а также другой порядковый номер (z). Вы отправляете обратно пакет ACK, который имеет порядковый номер x + 1 и подтверждающий номер z + 1, чтобы завершить соединение.

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

TCP определен в RFC 793, доступно здесь: http://www.faqs.org/rfcs/rfc793.html

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