Skip to content


Как закрыть сокет в состоянии TIME_WAIT

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

TCP state diagram

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

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

# ./killcx 10.11.12.13:44034
killcx v1.0.3 - (c)2009-2011 Jerome Bruandet - http://killcx.sourceforge.net/
 
[PARENT] checking connection with [10.11.12.13:44034]
[PARENT] found connection with [10.10.10.10:22] (ESTABLISHED)
[PARENT] forking child
[PARENT] sending spoofed SYN to [10.10.10.10:22] with bogus SeqNum
[CHILD]  interface not defined, will use [eth0]
[CHILD]  setting up filter to sniff ACK on [eth0] for 5 seconds
f[CHILD]  hooked ACK from [10.10.10.10:22]
[CHILD]  found AckNum [1240626855] and SeqNum [301466544]
[CHILD]  sending spoofed RST to [10.10.10.10:22] with SeqNum [1240626855]
[CHILD]  sending RST to remote host as well with SeqNum [301466544]
[CHILD]  all done, sending USR1 signal to parent [19312] and exiting
[PARENT] received child signal, checking results...
         => 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:

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

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

Ещё есть третий вариант принудительного завершения TCP-соединения - использование утилиты tcpkill. Её преимущество в том, что ее намного проще установить (по сравнению с killcx) – достаточно просто установить пакет dsniff, в состав которого она входит. Какое именно соединение обрывать ей нужно указать с помощью BPF-выражения, формат которых знаком каждому, кто пользовался tcpdump-ом.

Пример использования:

[root@srv ~]# lsof -i -nP | grep ssh
sshd       1805      root    3u  IPv4    14341      0t0  TCP *:22 (LISTEN)
sshd       1805      root    4u  IPv6    14345      0t0  TCP *:22 (LISTEN)
sshd       9832      root    3r  IPv4 15780961      0t0  TCP 192.168.1.1:5224->192.168.1.51:34749 (ESTABLISHED)
sshd       9835       avz    3u  IPv4 15780961      0t0  TCP 192.168.1.1:5224->192.168.1.51:34749 (ESTABLISHED)
[root@srv ~]# tcpkill -i eth1.2 host 192.168.1.51 and port 34749
tcpkill: listening on eth1.2 [host 192.168.1.51 and port 34749]
Write failed: Broken pipe

Здесь я подключился по SSH с хоста 192.168.1.51 на сервер 192.168.1.1 и запустил сначала команду lsof чтобы узнать порт на стороне клиента (34749). Затем передал его в качестве аргумента tcpkill-у и соединение сразу было разорвано. Следует учитывать, что tcpkill сработает только для соединения, по которому передаются хоть какие-то данные. В противном случае он просто будет висеть в ожидании следующей порции трафика.

Еще один, пожалуй, самый изящный вариант с использованием отладчика gdb. Опять поключаемся по SSH с 192.168.1.51 на 192.168.1.1 и что-то там запускаем для красоты, например такой цикл:

[user@avz ~]$ ssh 192.168.1.1
Last login: Sat Aug 26 23:13:00 2017 from 192.168.1.51
 
[user@srv ~]$ for i in {1..100} ; do date ; sleep 1 ; done
Sat Aug 26 23:25:35 EEST 2017
Sat Aug 26 23:25:36 EEST 2017
Sat Aug 26 23:25:37 EEST 2017
Sat Aug 26 23:25:38 EEST 2017
Sat Aug 26 23:25:39 EEST 2017

В соседней консоли смотрим информацию о только что установленном соединении:

[root@avz]# lsof -i -nP | grep ssh | grep 192.168.1.1:22
ssh       19543    avz    3u  IPv4 830283369      0t0  TCP 192.168.1.51:37527->192.168.1.1:22 (ESTABLISHED)

Получаем PID (19543) и номер файлового дескриптора (3, см. 4-ое поле). Далее запускаем gdb и командой close говорим ему закрыть файловый дескриптор с номером 3:

[root@avz]# gdb -p 19543
(gdb) call close(3)
$1 = 0
(gdb) quit
A debugging session is active.
 
        Inferior 1 [process 19543] will be detached.
 
Quit anyway? (y or n) y
Detaching from program: /usr/bin/ssh, process 19543

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

Sat Aug 26 23:25:40 EEST 2017
Sat Aug 26 23:25:41 EEST 2017
Sat Aug 26 23:25:42 EEST 2017
Sat Aug 26 23:25:43 EEST 2017
Sat Aug 26 23:25:44 EEST 2017
Sat Aug 26 23:25:45 EEST 2017
Sat Aug 26 23:25:46 EEST 2017
Sat Aug 26 23:25:47 EEST 2017
Sat Aug 26 23:25:48 EEST 2017
Write failed: Bad file descriptor
[user@avz ~]$

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

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

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

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

А вот для закрытия соединений в состоянии CLOSE_WAIT может пригодится вот эта штука: https://github.com/rghose/kill-close-wait-connections или свежие версии штатной утилиты ss из пакета iproute:

ss --tcp state CLOSE-WAIT '( dport = 22 or dst 1.1.1.1 )' --kill

Posted in *nix, Howto.

Tagged with .


Традиционным банкам скоро придет конец

2016 - the year of blockchain

Будущее финансовых сервисов будет плотно связано с технологией blockchain

Еще одно подтверждение точки зрения Криса Скиннера, о том, что у нецифровых банков нет будущего. Если даже такие гиганты, как Intel, инвестируют в финтех, то старые модели обслуживания клиентов через отделения скоро уйдут в прошлое. И банкам, которые хотят остаться в игре, придется адаптировать свои бизнес-процессы под набирающие всё большую популярность дистанционное обслуживание клиентов и P2P-кредитование.

Корпорация Intel объявила об открытии в Тель-Авиве финтех-лаборатории для разработчиков, основным направлением работы которой станут эксперименты в области инновационных финансовых технологий, включая приложения на основе блокчейна. Помимо блокчейна, новая лаборатория будет работать над устройствами для Интернета вещей (IoT), облачной обработкой данных и биометрическими приложениями, сообщает The Jerusalem Post.

Открытие лаборатории состоялась в сотрудничестве с The Floor, израильской финтех-организацией, которая размещена на Фондовой бирже Тель-Авива и ранее в этом году привлекла $2 млн инвестиций от китайской венчурной фирмы Pando Group. «Благодаря этому партнерству Intel вместе с The Floor возглавит разработку в этой области в Израиле и расширит влияние технологии в финансовом секторе», — сказал Шарон Путерман-Зафрир, руководитель направления IoT израильского подразделения Intel.

В феврале этого года Intel присоединился к Hyperledger, проекту по созданию блокчейна с открытым кодом, представив через некоторое время модульную блокчейн-платформу Sawtooth Lake. Напомним, на прошлой неделе об создании новой блокчейн-лаборатории, главным направлением деятельности которой станет разработка приложений для индустрии финансовых услуг, объявила консалтинговая фирма Deloitte. Лаборатория получила название EMEA Financial Services Blockchain Lab и находится в столице Ирландии Дублине.

Кто использует blockchain

Кто использует blockchain

Небольшой ликбез, для тех, кто еще не в теме:

Принципы работы bitcoin и blockchain

Как работает blockchain

Posted in Money.

Tagged with .


P..nhub шутить изволят

Cегодня тот редкий день когда pornhub.com выглядит вполне себе family-friendly:

pornhub 1-st of april

cornhub.com

Всех с 1-ым апреля :)

Posted in Fun.


О пользе irqbalance

Однажды приключилась неприятная фигня. Симптомы:

  • Потери ICMP-пакетов
  • Пинг 130 мс при норме 30мс
  • top выглядит крайне скверно (особое внимание на 70% у ksoftirqd/0):
    PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
    16763 catalina  20   0 33.3g  13g  13m S 938.0 21.2  36335:28 java
        4 root      20   0     0    0    0 R 70.3  0.0 188:10.66 ksoftirqd/0
    10362 haproxy   20   0 1411m 1.3g 1784 R 66.3  2.1   3:24.43 haproxy
    10361 haproxy   20   0 1255m 1.1g 1800 R 61.4  1.8   3:14.30 haproxy
    10360 haproxy   20   0 1163m 1.1g 1780 R 56.8  1.7   3:04.97 haproxy
    10359 haproxy   20   0 1032m 951m 1796 S 48.6  1.5   2:51.85 haproxy
    10358 haproxy   20   0  995m 916m 1800 S 43.7  1.4   2:44.77 haproxy
    10357 haproxy   20   0  915m 836m 1776 R 33.5  1.3   2:33.69 haproxy
    10356 haproxy   20   0  841m 764m 1776 D 32.5  1.2   2:27.62 haproxy
    10355 haproxy   20   0  800m 724m 1800 R 29.5  1.1   2:20.10 haproxy
  • Все прерывания от сетевой карты обслуживаются только одним ядром (из 24-ех):
    # cat /proc/interrupts | grep -E "CPU|em1" | sed -r "s/ +/  /g" | sed -r "s/CPU//g"
                     0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19 20 21 22 23
      125:   146771849  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  IR-PCI-MSI-edge  em1-0
      126:  2740374640  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  IR-PCI-MSI-edge  em1-1
      127:  2693791925  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  IR-PCI-MSI-edge  em1-2
      128:  2693712466  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  IR-PCI-MSI-edge  em1-3
      129:  2695319407  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  IR-PCI-MSI-edge  em1-4

Вспомнилась картинка:

Как правильно копать яму

Team work.


И, конечно же, возникла идея поправить это безобразие. Но ждал облом:

# service irqbalance start
Starting irqbalance: irqbalance: symbol lookup error: irqbalance: undefined symbol: g_list_free_full
                                                           [FAILED]

Небольшое гугление подсказало, что, возможно, имеем дело с устаревшей версией пакета glib2. Пробуем обновить:

# yum update glib2
Setting up Update Process
Resolving Dependencies
--> Running transaction check
---> Package glib2.x86_64 0:2.26.1-7.el6_5 will be updated
---> Package glib2.x86_64 0:2.28.8-4.el6 will be an update
--> Finished Dependency Resolution
 
# tail -n 1 /var/log/yum.log
Nov 20 16:19:34 Updated: glib2-2.28.8-4.el6.x86_64

После этого случилось чудо и irqbalance таки запустился:

# service irqbalance start
Starting irqbalance:                                       [  OK  ]

И получаем вот такую красоту (прерывания стали распределяться и по другим ядрам тоже):

# cat /proc/interrupts | grep -E "CPU|em1" | sed -r "s/ +/  /g" | sed -r "s/CPU//g"
                 0  1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23
  125:   146771849  0  0  0  0  0  0  0  2964882  0  0  0  39242  0  75507  0  0  0  0  0  0  0  0  0  IR-PCI-MSI-edge  em1-0
  126:  2740374640  0  7566544  0  0  0  0  0  0  0  0  0  10004  0  0  0  162137  0  0  0  0  0  0  0 IR-PCI-MSI-edge  em1-1
  127:  2693791925  0  0  0  0  0  0  0  0  0  0  0  8771  0  7319795  0  0  0  157178  0  0  0  0  0  IR-PCI-MSI-edge  em1-2
  128:  2693712466  0  0  0  0  0  0  0  0  0  0  0  7369768  0  0  0  0  0  0  0  158210  0  0  0     IR-PCI-MSI-edge  em1-3
  129:  2695319407  0  0  0  0  0  0  0  0  0  0  0  77028  0  0  0  0  0  7301320  0  0  0  158271  0 IR-PCI-MSI-edge  em1-4

Далее пинг падает до со 130 до 30 мс, ICMP-потери прекращаются, nagios перестаёт вопить про периодически недоступные сервисы, ksoftirqd из top-а пропадает:

top - 16:39:53 up 79 days,  2:41, 18 users,  load average: 40.03, 35.48, 27.67
Tasks: 446 total,   9 running, 437 sleeping,   0 stopped,   0 zombie
Cpu(s): 54.0%us, 16.9%sy,  0.0%ni, 19.8%id,  0.0%wa,  0.0%hi,  9.4%si,  0.0%st
Mem:  65920820k total, 40078188k used, 25842632k free,   261184k buffers
Swap:  8290296k total,        0k used,  8290296k free, 11422368k cached
 
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
16763 catalina  20   0 32.6g  13g  13m S 1452.3 21.0  36642:46 java
15460 haproxy   20   0  702m 627m 2276 R 60.3  1.0   9:55.44 haproxy
15464 haproxy   20   0  758m 679m 2276 R 59.4  1.1  10:26.81 haproxy
15459 haproxy   20   0  729m 653m 2272 R 58.0  1.0   9:53.93 haproxy
15463 haproxy   20   0  729m 652m 2268 R 58.0  1.0  10:23.88 haproxy
15462 haproxy   20   0  725m 649m 2308 R 57.4  1.0  10:13.97 haproxy
15466 haproxy   20   0  771m 693m 2296 R 54.8  1.1  10:33.94 haproxy
15468 haproxy   20   0  722m 645m 2308 R 51.8  1.0  10:26.30 haproxy
15461 haproxy   20   0  737m 661m 2308 R 51.5  1.0  10:05.91 haproxy
26785 avz       20   0 15296 1600  988 R  1.0  0.0   0:00.07 top
15539 root      20   0 15296 1624  988 S  0.7  0.0   0:13.21 top
   73 root      20   0     0    0    0 S  0.3  0.0   6:55.14 ksoftirqd/17

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

Posted in *nix.

Tagged with .