Излизане от клиент на localhost, без прекъсване на TCP връзка към сървър на localhost (без FIN пакет)

Оригинален въпрос

Свързвам се към node.js TCP сървър (на localhost) с telnet и се опитвам да проуча сонди за поддържане на активност.

Като първи тест бих искал да се свържа със сървъра с telnet и да прекратя telnet сесията по начин, който не изпраща FIN пакет. (Оставяйки сървъра да мисли, че TCP сокетът все още е „здрав“.) За съжаление не мога да намеря умен начин да тествам това.

  • Когато изляза от telnet от подканата за telnet, събитието end на сокета се задейства във възела. Очевидно е получил FIN пакет.
  • Когато kill процесът на telnet, той също чисто прекъсва връзката с FIN пакет, преди процесът да умре.

Знаете ли за начин да излезете от telnet, без да изпращате FIN пакет (за предпочитане да не включва мрежов кабел, който е прекъснат / създаващ физическа грешка в мрежата.)

Подобрен въпрос

Искам да симулирам мрежова повреда, като използвам само localhost / loopback (без всъщност да изключвам интерфейси / мрежови кабели). Искам да отворя TCP връзка между клиент и сървър, и двата на localhost. Тогава искам клиентът да умре, без да уведоми сървъра, че го няма. (Т.е. без изпращане на FIN пакет.) Това може да се случи в реална мрежа, ако рутерът се повреди например.

Благодарение на коментарите по-долу научих, че ядрото ще събира всички отворени портове/сокети, притежавани от процес, когато процесът умре (или бъде принудително убит), като моя telnet по-горе, и ще ги затвори за процеса, като изпрати FIN пакет. Така че трябва да подмами ядрото да не затвори съществуваща връзка.

И така, как мога да създам клиентски процес, да го поддържам жив, но да го оставя да се държи като напълно мъртва 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 и оставете процесите да работят във фонов режим. В bash:

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
Благодаря, Scapy изглежда страхотно. Иска ми се 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 таблици/правило за защитна стена за незабавно прекъсване на целия трафик към порт (на който клиентът слуша) на localhost? - person rdrey; 05.10.2012
comment
Това също ще свърши работа. Всичко, което просто ще спре потока от пакети за кортежа protocol/local-addr/local-port/remote-addr/remote-port, ще свърши работа. - 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