208 votes

Tester efficacement si un port est ouvert sous Linux ?

À partir d'un script bash, comment puis-je savoir rapidement si un port 445 est ouvert/écouté sur un serveur.

J'ai essayé plusieurs options, mais je veux quelque chose de rapide :
1. lsof -i :445 (Prend des secondes)
2. netstat -an |grep 445 |grep LISTEN (Prend des secondes)
3. telnet (il ne revient pas)
4. nmap , netcat ne sont pas disponibles sur le serveur

Ce serait bien de connaître une méthode qui n'énumère pas d'abord et qui n'effectue pas de recherche ensuite.

1 votes

Netcat est-il disponible ? Il a un chemin d'échec rapide IIRC. netcat.sourceforge.net

5 votes

netstat -lnt (avec -t et sans -a ) limitera la sortie aux seules connexions TCP en écoute. Cela peut accélérer un peu les choses. Vous pouvez ajouter -4 pour IPv4 seulement si vous n'avez pas besoin d'IPv6.

0 votes

Lsof -i est un favori personnel.

169voto

Spencer Rathbun Points 6171

Une surprise que j'ai découverte récemment est que Bash supporte nativement connexions tcp comme descripteurs de fichiers . A utiliser :

exec 6<>/dev/tcp/ip.addr.of.server/445
echo -e "GET / HTTP/1.0\n" >&6
cat <&6

J'utilise 6 comme descripteur de fichier car 0,1,2 sont stdin, stdout, et stderr. 5 est parfois utilisé par Bash pour les processus enfants donc 3, 4, 6, 7, 8 et 9 devraient être sûrs.

Selon le commentaire ci-dessous, pour tester l'écoute sur une serveur local dans un script :

exec 6<>/dev/tcp/127.0.0.1/445 || echo "No one is listening!"
exec 6>&- # close output connection
exec 6<&- # close input connection

Pour déterminer si quelqu'un est à l'écoute, essayez de vous connecter par loopback. Si cela échoue, alors le port est fermé ou l'accès n'est pas autorisé. Ensuite, fermez la connexion.

Modifiez ceci pour votre cas d'utilisation, comme l'envoi d'un courriel, la sortie du script en cas d'échec, ou le démarrage du service requis.

0 votes

@AmanJain Le chat attend EOF ou Ctrl-C pour quitter. Vous devrez adapter cela à votre protocole. BTW, est-ce que vous exécutez ceci sur un serveur distant ?

0 votes

Je veux intégrer le code de vérification de port dans un script sur le serveur, sous /etc/init.d/

0 votes

@AmanJain Je l'ai mis à jour pour un système local. Vous voulez juste vérifier s'il écoute, n'est-ce pas ? Il n'y a pas de vérification de protocole, comme la demande d'une page via http ?

133voto

Yosemite Sam Points 342

Il y a une très courte "réponse rapide" ici : Comment tester si un port TCP distant est ouvert à partir du Shell script ?

nc -z <host> <port>; echo $?

Je l'utilise avec 127.0.0.1 comme adresse "distante".

ceci renvoie "0" si le port est ouvert et "1" si le port est fermé

par exemple

nc -z 127.0.0.1 80; echo $?

-z Spécifie que nc doit juste rechercher les démons en écoute, sans leur envoyer de données. C'est une erreur d'utiliser cette option en conjonction avec avec l'option -l.

2 votes

Cela semble être le moyen le plus simple, merci. Le lien vers l'exemple de script ne fonctionne plus cependant, mais il est assez explicite de toute façon.

0 votes

Joli ! C'est beaucoup plus rapide que les autres réponses sur un serveur avec de nombreux ports ouverts. Retourne en <0.01 secondes pour moi alors que netstat / lsof prennent 1s+.

2 votes

Le drapeau -z n'est pas disponible dans le ncat basé sur nmap qui est livré avec la plupart des distros récentes : Fedora, Centos, etc. (nmap-ncat-6.01-9.fc18.x86_64)

90voto

anubhava Points 172509

Vous pouvez utiliser netstat de cette façon pour obtenir des résultats beaucoup plus rapides :

Sous Linux :

netstat -lnt | awk '$6 == "LISTEN" && $4 ~ /\.445$/'

Sur Mac :

netstat -anp tcp | awk '$6 == "LISTEN" && $4 ~ /\.445$/'

Ceci produira une liste de processus écoutant sur le port (445 dans cet exemple) ou ne produira rien si le port est libre.

1 votes

Votre syntaxe netstat est incorrecte. netstat -ln --tcp fonctionne, mais reste lent

6 votes

En fait, la syntaxe est correcte, mais vous utilisez probablement Linux et moi Mac. Pour Linux, utilisez ceci : netstat -lnt | awk '$6 == "LISTEN" && $4 ~ ".445"'

0 votes

Les fenêtres. J'ai essayé 32 avec la commande ci-dessus, php -S localhost:32

40voto

Tony Points 6793

Vous pouvez utiliser netcat pour cela.

nc ip port < /dev/null

se connecte au serveur et referme directement la connexion. Si netcat ne parvient pas à se connecter, elle renvoie un code de sortie non nul. Le code de sortie est stocké dans la variable $ ?. Par exemple,

nc ip port < /dev/null; echo $?

retournera 0 si et seulement si netcat a pu se connecter avec succès au port.

2 votes

Cette réponse a besoin de plus de upvotes. nc fonctionne parfaitement pour ce cas. l'astuce /dev/tcp est intelligente, mais semble difficile à mettre en œuvre un script avec des interruptions de signal.

6 votes

nc a le -z à cette fin, ce qui ne nécessite pas l'utilisation de l'indicateur /dev/null . Il y a déjà une réponse en utilisant le -z drapeau ci-dessus.

2 votes

@AbeVoelker Toutes les versions de nc ne prennent pas en charge l'option -z. Je suis sur CentOS 7 et j'ai trouvé que la solution de Tony était ce dont j'avais besoin.

17voto

andrew cooke Points 20902

Ils sont listés dans /proc/net/tcp.

c'est la deuxième colonne, après le " :", en hexadécimal :

> cat /proc/net/tcp
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode                                                     
   0: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 10863 1 ffff88020c785400 99 0 0 10 -1                     
   1: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 7983 1 ffff88020eb7b3c0 99 0 0 10 -1                      
   2: 0500010A:948F 0900010A:2328 01 00000000:00000000 02:00000576 00000000  1000        0 10562454 2 ffff88010040f7c0 22 3 30 5 3                   
   3: 0500010A:E077 5F2F7D4A:0050 01 00000000:00000000 02:00000176 00000000  1000        0 10701021 2 ffff880100474080 41 3 22 10 -1                 
   4: 0500010A:8773 16EC97D1:0050 01 00000000:00000000 02:00000BDC 00000000  1000        0 10700849 2 ffff880104335440 57 3 18 10 -1                 
   5: 0500010A:8772 16EC97D1:0050 01 00000000:00000000 02:00000BF5 00000000  1000        0 10698952 2 ffff88010040e440 46 3 0 10 -1                  
   6: 0500010A:DD2C 0900010A:0016 01 00000000:00000000 02:0006E764 00000000  1000        0 9562907 2 ffff880104334740 22 3 30 5 4                    
   7: 0500010A:AAA4 6A717D4A:0050 08 00000000:00000001 02:00000929 00000000  1000        0 10696677 2 ffff880106cc77c0 45 3 0 10 -1  

donc je suppose que l'un d'entre eux :50 dans la troisième colonne doit être stackoverflow :o)

regarder man 5 proc pour plus de détails. et le fait de le décortiquer avec sed etc. est laissé comme un exercice pour le gentil lecteur...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X