Système: identifier un processus monopolisant un port TCP

de | 2017-03-10

C’est un cas que l’on rencontre parfois: un processus mal arrêté empêche sa relance, ou bien un autre processus occupe le port que vous souhaitez ouvrir. Vous vous retrouvez alors bloqué sans savoir par qui ni quoi.

Nous l’admettons volontiers : ce n’est pas un sujet très original. Mais, comme nous venons d’avoir le cas récemment lors du lancement  d’un noeud CCM (Cassandra Cluster Manager, il y a un article sur le sujet, ici même), nous allons tenter de l’enrichir pour vous apporter des informations sur les différentes approches possibles sous Linux.

Prenons comme exemple ce message d’erreur. C’était nous, c’était hier, c’était sous Linux Fedora 24 :

$ccm node1 start

ccmlib.common.UnavailableSocketError: Inet address 127.0.0.1:9042 is not available: [Errno 98] Address already in use

Le « ps » ne montre aucun processus sous notre compte utilisateur. Pourtant, « netstat -ant » confirme que le port est occupé :


$netstat -ant
Connexions Internet actives (serveurs et établies)
Proto Recv-Q Send-Q Adresse locale          Adresse distante        Etat
tcp        0      0 127.0.0.1:9042          0.0.0.0:*               LISTEN

Le cas facile : sous Linux, avec les droits administrateurs

Le Saviez-vous : L'Utilisation Du Sudo Est Surveillée Par Le Chat Sévère

Le Saviez-vous : L’Utilisation Du Sudo Est Surveillée Par Le Chat Sévère

Si vous avez le « sudo », vous pouvez repérer directement l’identifiant du programme écoutant sur le port TCP avec « netstat -pln » :


# netstat -tlp
Connexions Internet actives (seulement serveurs)
Proto Recv-Q Send-Q Adresse locale          Adresse distante        Etat        PID/Program name
tcp        0      0 machine310:apani1 0.0.0.0:*               LISTEN      64764/java
tcp        0      0 0.0.0.0:ssh             0.0.0.0:*               LISTEN      28992/sshd
tcp        0      0 machine310:x11-ssh-offset 0.0.0.0:*               LISTEN      55237/sshd: root@pt
tcp        0      0 machine310:7199           0.0.0.0:*               LISTEN      64764/java
tcp6       0      0 machine310:9042   [::]:*                  LISTEN      64764/java

Dans cet exemple, le processus Java 64764 occupe déjà le port TCP 9042. Comme nous sommes connecté en « root », il est facile de retrouver son propriétaire : un autre compte ayant démarré un Cassandra V3.

Mais comment l’identifier sans les droits administrateurs ?

Le cas relativement facile : sous Linux, utilisateur normal, propriétaire du processus bloquant

Digression : « utilisateur normal » en opposition à « administrateur ». La simple logique permet de déduire que les administrateurs ne sont pas normaux, contrairement à ce qu’ils pourraient prétendre. Fin de la digression (1). 

La commande lsof vous permettra de retrouver le numéro de processus :


[user1@machine310 ~]$ lsof -i :9042
COMMAND   PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
java    64764 user1   83u  IPv6 410801      0t0  TCP machine310:9042 (LISTEN)

On retrouve bien le même numéro.

Sur les distributions récentes (Fedora, RedHAt Entreprise 7, Centos 7),  si vous voulez faire frais et pimpant, vous pouvez passer par la commande « ss » (« Socket Statistics ». Pas de point Goldwin ici), qui accepte les mêmes paramètres que « netstat » mais affiche plus d’informations. Prochainement, nous ferons un article avec les commandes Linux remplaçant les anciennes: ip, ss, etc. (« etc » n’est pas une commande (quoique, dans dbSQWare, c’est un alias) mais signifie « la liste continue ». (Fin des parenthèses (ce n’est pas du LISP))).

Exemple d’utilisation :


$ ss -tlpe

State      Recv-Q Send-Q       Local Address:Port            Peer Address:Port
LISTEN     0      128          ::ffff:127.127.127.127:9042       :::*                     users:(("java",pid=64764,fd=83)) uid:3505 ino:410801 sk:ffff880424e26b40 v6only:0

Si le processus ne vous appartient pas, vous ne verrez pas toutes les informations en bout de ligne mais vous aurez quand même le « uid », c’est à dire l’identifiant du compte ayant lancé le programme.

Exemple, même commande depuis un autre utilisateur :


[user2@machine310 ~]$ ss -tlpe | grep 9042
LISTEN     0      128       ::ffff:127.127.127.127:9042                    :::*                     uid:3505 ino:410801 sk:ffff880424e26b40 v6only:0

C’est toujours une information intéressante.

Et les autres systèmes ?

Bonne question.

Méfiez-Vous Des Chats Qui Lancent Des Serveurs Sur Les Ports Dont Vous Avez Besoin !

Méfiez-Vous Des Chats Qui Lancent Des Serveurs Sur Les Ports Dont Vous Avez Besoin !

Nous pensions traiter également Solaris mais y avons renoncé : pas suffisamment de droits ni de machines pour appliquer les mêmes tests. De plus, les différentes méthodes impliquent la commande « pfiles » or la documentation de celle-ci avertit clairement : elle stoppe le programme le temps de lire les informations et, sur des systèmes très chargés, risque de provoquer des engorgements. C’est sûr, cela aurait matière à un nouvel article mais nous avons préféré évité.

Pour Windows, nous n’en avions pas sous la main.  Si vous avez l’expérience de ce type de problème sur ce système, faites nous en part dans les commentaires :  nous compléterons.

En espérant vous avoir apporté quelques éclaircissement nouveau sur un thème portant fréquemment abordé, nous conclurons avec cette règle simple, facile à suivre comme à mémoriser : ne lancez pas deux fois le même serveur sur la même machine !

Des problèmes ? des questions ? Exprimez-vous ! Les commentaires sont ouverts. Coquilles et fautes de grammaires sont notre lot quotidien : signalez-les nous à m.capello@dbsqware.com

 

Crédit Photo : Wikicommon, par SlavaWikicommon, domaine public

(1) Soyons clairs : 1) c’est une boutade. 2) il n’y a pas d’opposition puisque qu’on parle des utilisateurs. La logique ne n’applique pas. Mais si, lors d’un débat avec un administrateur Unix, vous sortez cet argument, vous devrez réussir à le plonger dans la perplexité et vous enfuir avec le dernier mot.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*