Skip to content


Как закрыть сокет в состоянии TIME-WAIT

Иногда возникает необходимость прибить какое-то TCP-соединение. Часто для решения этой задачи с помощью lsof или netstat вычисляют процесс, который это соединение обслуживает и что-то с этим процессом делают (например, kill -9). Но вот для ситуации когда процесс найти не получается (например, он завершился аварийно и не закрыл после себя соединение) или прибивать процесс нельзя, уже задачка становиться не совсем тривиальной.

TCP state diagram

Состояния TCP-соединения и переходы между ними

Тут может пригодится perl-утилитка под названием killcx, которая должна помочь и в случае когда TCP-соединение пребывает в состоянии TIME-WAIT. Работает примерно так:

  1. # ./killcx 10.11.12.13:44034
  2. killcx v1.0.3 - (c)2009-2011 Jerome Bruandet - http://killcx.sourceforge.net/
  3.  
  4. [PARENT] checking connection with [10.11.12.13:44034]
  5. [PARENT] found connection with [10.10.10.10:22] (ESTABLISHED)
  6. [PARENT] forking child
  7. [PARENT] sending spoofed SYN to [10.10.10.10:22] with bogus SeqNum
  8. [CHILD]  interface not defined, will use [eth0]
  9. [CHILD]  setting up filter to sniff ACK on [eth0] for 5 seconds
  10. f[CHILD]  hooked ACK from [10.10.10.10:22]
  11. [CHILD]  found AckNum [1240626855] and SeqNum [301466544]
  12. [CHILD]  sending spoofed RST to [10.10.10.10:22] with SeqNum [1240626855]
  13. [CHILD]  sending RST to remote host as well with SeqNum [301466544]
  14. [CHILD]  all done, sending USR1 signal to parent [19312] and exiting
  15. [PARENT] received child signal, checking results...
  16.          => success : connection has been closed !

В качестве аргумента ей нужно передать IP-адрес и порт удаленной стороны TCP-соединения. В этом примере я подключился по SSH с клиента 10.11.12.13 на сервер с адресом 10.10.10.10. Команда выполнялась на сервере 10.10.10.10.

Для работы утилита требует наличия следующих perl-модулей:
* Net::RawIP (для создания spoofed packets, CPAN-ом он у меня просто так ставиться не захотел, жалуясь на тесты, пришлось сделать force install Net::RawIP)
* Net::Pcap (для перехвата TCP-пакетов).
* NetPacket::Ethernet (для декодирования TCP/IP-пакетов).

Также может потребоваться предварительная установка пакета libpcap-devel.

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

Попытка оборвать соединения с сервисом, запущенном на порту 62616 сервера 10.10.10.10, с клиента 10.20.20.20:

  1. [root@avz /tmp/cutter-1.04]# ./cutter 10.10.10.10 62616 10.20.20.20
  2. Error: The matching connection terminates on THIS computer.
  3.  
  4. Note:
  5.     cutter can only cut connections running over the router or firewall
  6.     on which it is run. It cannot cut connections that terminate locally.
  7.     So: you should run cutter on the firewall/router, not on the client
  8.     or server machine.

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

Также есть другой вариант избавиться от TIME-WAIT-ов, из разряда "из пушки по воробьям" – просто рестартануть сеть (service network restart или что там в Вашем дистрибутиве аналогичное).

А вот чтобы не доводить вообще до появления TIME-WAIT-ов или снизить их количество, может помочь установка следующих опций ядра:

  1. net.ipv4.tcp_tw_recycle = 1
  2. net.ipv4.tcp_tw_reuse = 1

При чем в случае с net.ipv4.tcp_tw_recycle, следует помнить, что ее включение может поломать работу клиентов за NAT-ом и в общем случае включать ее не рекомендуется.

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

Размещено в категории *nix, Howto. Теги: .

Комментариев: 1

Чтобы быть всегда в курсе здесь происходящего, Вы можете подписаться на RSS feed для комментариев на эту заметку.

  1. В стремлении избавляться от TIME-WAIT-ов важно не переусердствовать: http://developerweb.net/viewtopic.php?id=2941

    Там намекают, что их не зря придумали. Выждать таймаут от 1 до 4 минут (длительность пребывания соединения в состоянии TIME-WAIT) нужно для того, чтобы где-то задержавшийся в пути блуждающий сегмент-дубликат не смог создать новую инкарнацию уже закрытого ранее соединения.

Some HTML is OK

(required)

(required, but never shared)

, или ответить через trackback.

Страница 1 из 11