133 votes

Fermeture manuelle d'un port à partir de la ligne de commande

Je veux fermer un port ouvert qui est en mode d'écoute entre mon application client et serveur.

Existe-t-il une option manuelle de ligne de commande sous Linux pour fermer un port ?

NOTE : J'ai appris que "seule l'application qui possède le socket connecté doit le fermer, ce qui se produit lorsque l'application se termine".

Je ne comprends pas pourquoi cela n'est possible que par l'application qui l'ouvre ... Mais je suis quand même désireux de savoir s'il existe un autre moyen de le faire.

164voto

Ryna Points 396

J'ai eu le même problème, le processus doit rester en vie mais le socket doit être fermé. Fermer un socket dans un processus en cours n'est pas impossible mais difficile :

  1. localiser le processus :

    netstat -np

    Vous obtenez un source/destination ip:port portstate pid/processname carte

  2. localise le descripteur de fichier de la socket dans le processus

    lsof -np $pid

    Vous obtenez une liste : nom du processus, pid, utilisateur, fileDescriptor, ... une chaîne de connexion.

    Recherchez le numéro de fileDescriptor correspondant à la connexion. Ce sera quelque chose comme "97u", ce qui signifie "97".

  3. Maintenant, connectez le processus :

    gdb -p $pid
  4. Fermez maintenant la prise :

    call close($fileDescriptor) //does not need ; at end.

    exemple :

    call close(97)

    Puis détachez gdb :

    quit

    Et la prise est fermée.

82voto

Vous posez en quelque sorte la mauvaise question ici. Il n'est pas vraiment possible de simplement "fermer un port" depuis l'extérieur de l'application qui a ouvert le socket qui l'écoute. La seule façon de le faire est de tuer complètement le processus qui possède le port. Ensuite, dans une minute ou deux, le port redeviendra disponible. Voici ce qui se passe (si cela ne vous intéresse pas, passez directement à la fin où je vous montre comment tuer le processus propriétaire d'un port particulier) :

Les ports sont des ressources allouées par le système d'exploitation à différents processus. Cela revient à demander au système d'exploitation un pointeur de fichier. Cependant, contrairement aux pointeurs de fichiers, seul UN processus à la fois peut posséder un port. Grâce à l'interface socket BSD, les processus peuvent demander à écouter un port, ce que le système d'exploitation leur accorde. Le système d'exploitation s'assurera également qu'aucun autre processus n'obtiendra le même port. À tout moment, le processus peut libérer le port en fermant le socket. Le système d'exploitation récupère alors le port. Alternativement, si le processus se termine sans libérer le port, le système d'exploitation finira par récupérer le port (bien que cela ne se produise pas immédiatement : cela prendra quelques minutes).

Maintenant, ce que vous voulez faire (simplement fermer le port à partir de la ligne de commande), n'est pas possible pour deux raisons. Premièrement, si cela était possible, cela signifierait qu'un processus pourrait simplement voler la ressource d'un autre processus (le port). Ce serait une mauvaise politique, sauf si elle est limitée aux processus privilégiés. La deuxième raison est qu'il n'est pas clair ce qui arriverait au processus qui possède le port si nous le laissons continuer à fonctionner. Le code du processus est écrit en supposant qu'il possède cette ressource. Si nous la lui enlevions simplement, il finirait par s'écraser tout seul, c'est pourquoi les systèmes d'exploitation ne vous laissent pas faire cela, même si vous êtes un processus privilégié. Au lieu de cela, vous devez simplement les tuer.

Quoi qu'il en soit, voici comment tuer un processus qui possède un port particulier :

sudo netstat -ap | grep :<port_number>

Cela produira la ligne correspondant au port de maintien du processus, par exemple :

tcp  0  0 *:8000   *:* LISTEN  4683/procHoldingPort

Dans ce cas, procHoldingPort est le nom du processus qui a ouvert le port, 4683 est son pid, et 8000 (notez que c'est TCP) est le numéro de port qu'il détient.

Ensuite, regardez dans la dernière colonne, vous verrez /. Puis exécutez ceci :

kill  <pid>

Si cela ne fonctionne pas (vous pouvez vérifier en relançant la commande netstat). Faites ceci :

kill -9 <pid>

En général, il est préférable d'éviter d'envoyer SIGKILL si vous le pouvez. C'est pourquoi je vous dis d'essayer kill avant kill -9 . Il suffit d'utiliser kill envoie le SIGTERM plus doux.

Comme je l'ai dit, il faudra encore quelques minutes pour que le port se rouvre si vous faites cela. Je ne connais pas de moyen d'accélérer le processus. Si quelqu'un d'autre le fait, je serais ravi de l'entendre.

23voto

RedBaron Points 339

L'unité de fusion peut également être utilisée

fuser -k -n *protocol portno*

Ici le protocole est tcp/udp et portno est le numéro que vous souhaitez fermer. Par exemple

fuser -k -n tcp 37

Plus d'informations sur page de manuel de l'unité de fusion

8voto

supercheetah Points 926

Vous pouvez également utiliser iptables :

iptables -I INPUT -p tcp --dport 80 -j DROP

Il accomplit essentiellement ce que vous voulez. Cela va supprimer tout le trafic TCP sur le port 80.

8voto

Apta Points 11

Vous pouvez fermer un socket en écoute en utilisant ss :

sudo ss --kill state listening src :1234

Où 1234 est votre numéro de port.

ss fait partie du paquet iproute2, il y a donc de fortes chances qu'il soit déjà installé sur un Linux moderne.

J'ai appris cela par une réponse à une question connexe .

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X