Tuer la connexion TCP sous Linux

49

J'ai une connexion morte dans une application qui est à l'état suspendu si la machine cliente est morte.

->192.168.1.214:49029 (ESTABLISHED)

Existe-t-il un moyen de mettre fin à ces options à partir de la ligne de commande linux sans redémarrer le serveur?

Après la recherche, j’ai trouvé la solution appelée tcpkill. Mais cela ne fonctionnera pas pour moi. Comme il bloque en permanence cette ip.

Vivek Goel
la source
La réponse à l’utilisation de la sscommande est beaucoup plus simple et plus générale que les autres.
nealmcb

Réponses:

35

Originaire de: http://rtomaszewski.blogspot.sk/2012/11/how-toforcibly-kill-established-tcp.html

Pour "tuer" une socket, vous devez envoyer un paquet de réinitialisation TCP. Pour l'envoyer (et être accepté par l'autre partie), vous devez connaître le numéro de séquence TCP actuel.

1) La tcpkillméthode déjà mentionnée apprend le numéro SEQ en reniflant de manière passive sur le réseau et en attendant que des paquets valides de cette connexion arrivent. Ensuite, il utilise le numéro de SEQ appris pour envoyer des paquets RSET aux deux côtés. Cependant, si la connexion est inactive / suspendue et qu’aucun flux de données n’est transmis, il ne fera rien et attendra pour toujours.

2) Une autre méthode utilise un script perl appelé killcx( lien vers Sourceforge ). Ceci envoie activement des paquets SYN falsifiés et apprend le numéro SEQ de la réponse. Il envoie ensuite les paquets RSET de la même manière que tcpkill.

L’approche alternative (basée sur ce que vous voulez réaliser) consiste à utiliser le gdbdébogueur pour s’attacher à un processus possédant ce socket / connexion et émettre un close()appel système en son nom - comme détaillé dans cette réponse .

Si vous souhaitez traiter uniquement les connexions suspendues (l'autre côté est mort), il existe différents délais (TCP keepalive par exemple), qui doivent automatiquement fermer ces connexions si elles sont configurées correctement sur le système.

Marki555
la source
Cela fonctionnerait-il si nous fermions simplement le socket TCP avec son descripteur de fichier (fd)? exec fd> & -
Alexander Gonchiy
@AlexanderGonchiy pour les connexions actives, cela empêcherait le processus de répondre aux paquets, ce qui entraînerait l'expiration du délai de connexion. Pour les connexions inactives rien ne se passerait. Je ne sais pas si le noyau enverrait quoi que ce soit au réseau lors de la fermeture du fd.
Marki555
J'ai reniflé le numéro de séquence. Que dois-je faire alors?
user3132194
18

tcpkillpourrait le faire pour vous. Dans Ubuntu, c'est dans le dsniffpackage.

Quelque chose comme:

$ sudo tcpkill -i wlan0 host 192.168.1.214

(ou une autre tcpdumpexpression similaire pour quelle connexion tuer).

jcv
la source
4
Cela ne fonctionne que si la connexion transmet quoi que ce soit. Cela ne fonctionnera pas pour les connexions TCP
suspendues
17

Sur le noyau Linux> = 4.9, vous pouvez utiliser la sscommande de iproute2 avec la clé-K

ss -K dst 192.168.1.214 dport = 49029

le noyau doit être compilé avec l' CONFIG_INET_DIAG_DESTROYoption activée.

Pavel
la source
1
Pour linux, c’est vraiment le meilleur moyen et pratiquement le seul moyen si vous avez des connexions inactives ( tcpkillcela ne fonctionne pas). Cependant, je vous avouerai que je n’ai pas inspecté le site, killcxmais j’ai l’ impression qu’un grand nombre de logiciels de sécurité l’empêcheraient de fonctionner à moins que vous ne modifiiez vos iptables afin de permettre l’acheminement de ces paquets spoofés.
Seth Robertson
Merci! Travaillé comme un charme avec sudo ss -K ....Ubuntu Bionic 18.04 LTS. J'ai eu un tmuxprocessus qui était bloqué à une petite taille d'écran en raison d'une connexion distante, mais morte, mais pas dépassée. Tout est réglé!
nealmcb
6

Faites - en tant que root netstat -tunp|grep 49029. La dernière colonne de la sortie devrait vous montrer le PID et le nom du programme responsable du processus responsable de cette connexion.

Si vous êtes chanceux, il existe un seul processus pour cette connexion.

Si vous êtes malchanceux, cela devient plus compliqué (le PID est responsable de plus d'une connexion). Quel genre de service est-ce?

Pourquoi voulez-vous mettre fin à cette session?

Nils
la source
8
Je ne peux pas tuer ce processus. C'est un serveur d'engrenage. Je veux juste fermer la connexion.
Vivek Goel
0

tcpkillne peut pas fermer une connexion morte (pendue). Il est basé libpcap, il construit un paquet à envoyer un FINpaquet. Si la connexion est déjà morte, il ne peut pas obtenir le bon numéro de séquence.

Le seul moyen est de fermer le processus, donc rend partout n'est pas SPOF.

alswl
la source