Выход из клиента на локальном хосте без отключения TCP-соединения с сервером на локальном хосте (без пакета FIN)

Оригинальный вопрос

Я подключаюсь к TCP-серверу node.js (на локальном хосте) с помощью telnet и пытаюсь изучить проверки активности.

В качестве первого теста я хотел бы подключиться к серверу с помощью telnet и завершить сеанс telnet таким образом, чтобы не отправлять пакет FIN. (Позволить серверу думать, что сокет TCP все еще «исправен».) К сожалению, я не могу найти умный способ проверить это.

  • Когда я выхожу из telnet из приглашения telnet, событие end сокета срабатывает в node. Он явно получил пакет FIN.
  • Когда я kill запускаю процесс telnet, он также аккуратно разрывает соединение с пакетом FIN до того, как процесс завершится.

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

Улучшенный вопрос

Я хочу имитировать сбой сети, используя только локальный хост/петлю (без фактического отключения каких-либо интерфейсов/сетевых кабелей). Я хочу открыть TCP-соединение между клиентом и сервером, как на локальном хосте. Затем я хочу, чтобы клиент умер, не сообщив серверу, что он ушел. (т. е. без отправки пакета FIN.) Это может произойти в реальной сети, например, если маршрутизатор выйдет из строя.

Благодаря комментариям ниже я узнал, что ядро ​​будет собирать все открытые порты/сокеты, принадлежащие процессу, когда процесс умирает (или принудительно уничтожается), как мой telnet выше, и закрывает их для процесса, отправляя Пакет ФИН. Поэтому мне нужно заставить ядро ​​не закрывать существующее соединение.

Итак, как я могу создать клиентский процесс, сохранить его живым, но позволить ему вести себя как полностью мертвое TCP-соединение?

Спойлеры

  • (Ответ 1 ниже: используйте необработанный сокет (scapy), пусть он игнорирует любые пакеты, отправленные сервером после первоначального подключения и некоторых тестовых данных. (например, через определенное время.))
  • (Ответ 2, Идея от коллеги: настроить iptables для отключения трафика между клиентом и сервером. Актуальное правило iptables в комментарии ниже.)

person rdrey    schedule 04.10.2012    source источник
comment
Я не понимаю. Сеанс telnet по определению совпадает с TCP-соединением. Таким образом, «выйти из Telnet без отправки FIN» не имеет определенного значения.   -  person user207421    schedule 05.10.2012
comment
Я пытаюсь создать «разорванное TCP-соединение» с помощью telnet.   -  person rdrey    schedule 05.10.2012
comment
Таким образом, вы хотите вызвать отказ физической сети, не создавая отказ физической сети. Вам нужно только четко сформулировать это, чтобы увидеть, что это противоречие в терминах.   -  person user207421    schedule 05.10.2012
comment
@EJP нет, он здесь за чем-то другим. К сожалению, сетевые стеки живут в ядре, и как часть выхода и очистки процесса (как в Windows, так и в Linux) ядро ​​пойдет и FIN все сокеты, которые, по его мнению, у вас открыты, как часть CloseHandle() или close() или что-то еще ... Таким образом, вы должны поддерживать процесс в рабочем состоянии, иначе ядро ​​вступит во владение. Если вы не сделаете что-то вроде моего ответа ниже, вам придется изменить сетевой стек и перекомпилировать его или самостоятельно подключить сетевые функции. Мое решение ниже намного проще.   -  person mattypiper    schedule 05.10.2012
comment
@mattypiper Я все это знаю, хотя не вижу смысла. Чего я не понимаю, так это части о выходе из сеанса telnet без FIN. Пока сеанс telnet не получит FIN или не будет уведомлен о сбое сети через RST, он остается активным. Он пытается спровоцировать FIN здесь?   -  person user207421    schedule 05.10.2012


Ответы (2)


Нужно ли убивать клиентский процесс? Если это так, просто используйте netcat и дайте процессам работать в фоновом режиме. В Баше:

for i in $(seq 5) do nc localhost 5001 &; sleep 1; done

Это создает 5 клиентов TCP с интервалом SYN в 1 секунду. Если вам нужно взаимодействовать с одним из сеансов, вы можете использовать

fg $PID

чтобы вернуть одну из спинок netcat на передний план оболочки.

Другой вариант — правило iptables:

iptables -A OUTPUT -p tcp --tcp-flags FIN -j DROP

Еще один вариант — использовать сетевой инструмент низкого уровня с необработанными сокетами, такой как Scapy. Вот документация по Python для Scapy. Вы будете делать что-то похожее на сканирование TCP SYN, за исключением того, что вам нужно ACK SYN-ACK, который дает вам сервер. Это оставит сокет сервера в «подключенном» состоянии, и вы сможете продолжить и заняться другими делами. Сервер может время от времени подтверждать вам ACK, но вашей тестовой программе все равно. Он будет отправлять только SYN и отвечать на SYN-ACK.

person mattypiper    schedule 04.10.2012
comment
Мне нравится идея просто поддерживать клиент в рабочем состоянии, но я пытаюсь проверить функциональность проверки активности на стороне сервера, поэтому сервер будет отправлять SYN, и я бы хотел, чтобы клиенты действовали как мертвые и не отвечали вообще. . Это возможно, Мэтт? - person rdrey; 05.10.2012
comment
хммм, опять же, ядро ​​может взять на себя управление и отправить подтверждение SYN от имени клиентского процесса (да, эти процессы подключены и работают, сокеты открыты), и может не быть простого способа заставить его молчать. - person rdrey; 05.10.2012
comment
Я читал о проверках активности, замените все упоминания SYN на ACK в моих комментариях, пожалуйста. - person rdrey; 05.10.2012
comment
Хм, тогда вы захотите использовать необработанный сокет с помощью такого инструмента, как Scapy< /а>. Вот документация по Python для Scapy. Вы будете делать что-то похожее на сканирование TCP SYN, за исключением того, что вам нужно ACK SYN-ACK, который дает вам сервер. Это оставит сокет сервера в подключенном состоянии, и вы сможете продолжить и заняться другими делами. Сервер может время от времени подтверждать вам ACK, но вашей тестовой программе все равно. Он будет отправлять только SYN и отвечать на SYN-ACK. - person mattypiper; 05.10.2012
comment
Спасибо, Скапи выглядит довольно круто. Я бы хотел, чтобы в Unix был хороший инструмент для необработанных сокетов, который можно было бы использовать для создания разорванных TCP-соединений, но я поиграю со Scapy и сам создам проблему с мертвым сокетом клиента / фальшивой сетью. - person rdrey; 05.10.2012
comment
@rdrey может быть инструмент, который уже делает это, но для его поиска потребуется наш google-fu. Хорошая вещь в написании собственного инструмента scapy заключается в том, что вы можете полностью настроить его так, чтобы он работал именно так, как вам нужно. Это относится к области сетевых исследований, которыми, я думаю, вы и так занимаетесь. :) - person mattypiper; 05.10.2012

Вам нужно отключить машину от сети. «Отключение» процесса всегда приводит к тому, что ОС/машина должным образом закрывает сокет.

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

person Brian White    schedule 05.10.2012
comment
Я обсуждал это с коллегой сегодня. Как насчет того, чтобы добавить правило IP-таблиц/брандмауэра, чтобы мгновенно отсекать весь трафик на порт (на котором слушает клиент) на локальном хосте? - person rdrey; 05.10.2012
comment
Это тоже сработает. Все, что просто остановит поток пакетов для кортежа протокол/локальный-адрес/локальный-порт/удаленный-адрес/удаленный-порт, будет работать. - person Brian White; 05.10.2012
comment
Правило iptables — отличная идея. Может быть, просто отказаться от всех исходящих FIN? iptables -A OUTPUT -p tcp --tcp-flags FIN -j DROP. Мне грустно, что вы не используете scapy. :( - person mattypiper; 05.10.2012
comment
Извини, Мэтт. Я уверен, что когда-нибудь представится еще одна возможность попробовать scapy. Пожалуйста, обновите свой ответ своим правилом iptables, тогда я могу оставить его как принятый ответ;) - person rdrey; 06.10.2012