Question Teste si un port sur un système distant est accessible (sans telnet)


Autrefois, nous utilisions telnet pour voir si un port sur un hôte distant était ouvert: telnet hostname port tenterait de se connecter à n'importe quel port sur n'importe quel hôte et vous donner accès au flux TCP brut.

Telnet n'est plus installé sur les systèmes sur lesquels je travaille (pour des raisons de sécurité) et toutes les connexions sortantes vers tous les hôtes sont bloquées par défaut. Au fil du temps, il est facile de perdre la trace des ports ouverts à quels hôtes.

Existe-t-il un autre moyen de tester si un port sur un système distant est ouvert - en utilisant un système Linux avec un nombre limité de packages installés, et telnet n'est pas disponible?


251
2017-07-19 16:54


origine


En relation: vérifier l'état d'un port sur l'hôte distant chez SO - kenorb


Réponses:


Bash a pu accéder à TCP et UDP ports pendant un moment. De la page de manuel:

/dev/tcp/host/port
    If host is a valid hostname or Internet address, and port is an integer port number
    or service name, bash attempts to open a TCP connection to the corresponding socket.
/dev/udp/host/port
    If host is a valid hostname or Internet address, and port is an integer port number
    or service name, bash attempts to open a UDP connection to the corresponding socket.

Donc, vous pourriez utiliser quelque chose comme ceci:

xenon-lornix:~> cat < /dev/tcp/127.0.0.1/22
SSH-2.0-OpenSSH_6.2p2 Debian-6
^C pressed here

Taa Daa!


215
2017-07-22 10:37



Cela semble aussi fonctionner dans MinGW. Par exemple, une télécommande VNC le serveur sur 192.168.2.100 répond avec "RFB 003.008" en utilisant "cat </dev/tcp/192.168.2.100/5900". - Peter Mortensen
Cependant, sur les ports qui n'étaient pas ouverts, le délai expirait après 22 secondes (essayé Ubuntu 14.04 (Trusty Tahr) pour un serveur distant). Fait intéressant, le délai d'attente est beaucoup plus court que celui de nc (voir la réponse de thnee). - Peter Mortensen
@lornix, ok, mais dans ce cas, je dois obtenir le même résultat avec l'option nc sans l'option -z, mais cela ne fonctionne toujours pas: # nc -v -w5 127.0.0.1 18080 Connexion au port 180.0 127.0.0.1 [tcp / *] a réussi! # cat </dev/tcp/127.0.0.1/18080 se bloque sans résultat. Je veux juste comprendre quand je peux utiliser l'option "/ dev / tcp / host / port" - Alexandr
@Alexandr ... en fait, "se bloque sans aucun résultat" est un comportement assez attendu. chat est en attente de saisie. Caroline du Nord a des connaissances supplémentaires pour lui permettre de détecter l'absence de données en attente et d'arrêter d'essayer. chat n'est pas assez comme intelligent. Essayer cat < /dev/tcp/localhost/22, vous devriez obtenir votre en-tête sshd. Evidemment, votre processus sur le port 18080 attend que quelque chose vienne, avant d’envoyer quoi que ce soit. Port 22 (ssh) vous accueille avec sa version et ainsi de suite. Essaye le! - lornix
@lornix, merci beaucoup pour l'explication! Maintenant, la restriction est claire. Je pense que l'utilisation de nc devrait être un moyen privilégié de vérifier les ports. - Alexandr


Gentil et verbeux! A partir des pages de manuel.
Port unique:

nc -zv 127.0.0.1 80

Plusieurs ports:

nc -zv 127.0.0.1 22 80 8080

Gamme de ports:

nc -zv 127.0.0.1 20-30

295
2017-12-03 21:34



Semble être la meilleure réponse, merci. ;-) - lpapp
Ce pendu quand on l'a essayé Ubuntu 14.04 (Trusty Tahr) pour un serveur distant (même réseau local) pour les ports fermés (il a expiré après 127 secondes) - donc peu adapté aux scripts. Cela a fonctionné cependant pour un service qui avait un port ouvert. Utiliser l'option "-w2" pourrait être la solution. - Peter Mortensen
Utilisez l'option -u pour les ports UDP. - Efren
Sur version 6.4 de ncat -z n'est pas reconnu. J'ai pu faire sans z - smishra
Vous pouvez vérifier plusieurs plages avec: nc -zv 127.0.0.1 22,80,8080,20-30,443-446 (Version nc: 1.107-4). - bobbel


Netcat est un outil utile:

nc 127.0.0.1 123 &> /dev/null; echo $?

Va sortir 0 si le port 123 est ouvert et 1 si c'est fermé


96
2017-07-19 18:07



C'est une réponse beaucoup plus élégante et scriptable que la mienne. Il est regrettable pour moi que les administrateurs de la sécurité qui ont refusé telnet également retenu nc (mais - étrangement - pas curlou wget). - Steve HHH
Oui c'est complètement arbitraire et idiot. - thnee
Laisse le FOR les déclarations commencent! - Chad Harrison
Ce pendu quand on l'a essayé Ubuntu 14.04 (Trusty Tahr) pour un serveur distant (même réseau local) pour les ports fermés (il a expiré après environ 127 secondes) - donc peu adapté aux scripts. Cela a fonctionné cependant pour un service qui avait un port ouvert, renvoyant 0. L'utilisation de l'option "-w2" pourrait être la solution. - Peter Mortensen
je pense -G 2 serait plus approprié pour TCP timeout - A B


La méthode la plus simple, sans utiliser un autre outil, tel que socat, est décrit dans la réponse de @lornix ci-dessus. Ceci est juste pour ajouter un exemple réel de la façon dont on utiliserait le périphérique Psuedo /dev/tcp/... dans Bash, si vous souhaitez, par exemple, tester si un port donné est accessible par un autre serveur via la ligne de commande.

Exemples

Disons que j'ai un hôte sur mon réseau nommé skinner.

$ (echo > /dev/tcp/skinner/22) >/dev/null 2>&1 \
    && echo "It's up" || echo "It's down"
It's up

$ (echo > /dev/tcp/skinner/222) >/dev/null 2>&1 && \
    echo "It's up" || echo "It's down"
It's down

La raison pour laquelle vous voulez envelopper le echo > /dev/... entre parenthèses comme ceci, (echo > /dev/...) C'est parce que si vous ne le faites pas, alors avec les tests de connexions qui sont en panne, vous obtiendrez ces types de messages apparaissant.

$ (echo > /dev/tcp/skinner/223) && echo hi
bash: connect: Connection refused
bash: /dev/tcp/skinner/223: Connection refused

Ceux-ci ne peuvent pas simplement être redirigés vers /dev/null puisqu'ils proviennent de la tentative d'écrire des données sur l'appareil /dev/tcp. Donc, nous capturons toute cette sortie dans une sous-commande, c'est-à-dire (...cmds...) et rediriger la sortie de la sous-commande.


48
2017-09-02 17:59



C'est excellent. J'aimerais qu'il soit voté jusqu'au sommet. Je ne lis que très loin en bas de la page parce que je fais défiler accidentellement avant de le fermer. - Still.Tony
@ Okuma.Tony - oui c'est toujours un problème avec les Q qui ont beaucoup de réponses 8-). Merci pour les commentaires cependant, c'est apprécié. - slm


Je l'ai trouvé curl peut faire le travail d'une manière similaire à telnet, et curl va même vous dire quel protocole attend l'auditeur.

Construire un URI HTTP à partir du nom d’hôte et du port comme premier argument de curl. Si curl peut se connecter, il signalera une incompatibilité de protocole et quittera (si l’auditeur n’est pas un service Web). Si curl ne peut pas se connecter, il va expirer.

Par exemple, le port 5672 sur l'hôte 10.0.0.99 est fermé ou bloqué par un pare-feu:

$ curl http://10.0.0.99:5672
curl: (7) couldn't connect to host

Cependant, à partir d'un système différent, le port 5672 sur l'hôte 10.0.0.99 peut être atteint et semble exécuter un écouteur AMQP.

$ curl http://10.0.0.99:5672
curl: (56) Failure when receiving data from the peer
AMQP

Il est important de distinguer les différents messages: le premier échec était dû au fait que curl impossible de se connecter au port. Le deuxième échec est un test de réussite, bien que curl attend un écouteur HTTP au lieu d'un écouteur AMQP.


35
2017-07-19 17:05



Si curl n'est pas disponible, wget pourrait être. wget -qS -O- http://ip.add.re.ss:port devrait effectivement faire la même chose. - Michael Kjörling
Cela fonctionne même avec un nom d'hôte, ex. curl myhost:22. - 에이바
Cela peut être incorrect. J'ai un service Tomcat en cours d'exécution, mais j'obtiens l'erreur 404. # curl -k 192.168.194.4:6443 <html> <head> <title> Apache Tomcat / 7.0.34 - Rapport d'erreur </ title> <style> <! - H1 --- HR {color: # 525D76;} -> </ style> </ head> <body> <h1> Statut HTTP 404 - / </ h1> <HR size = "1" noshade = "noshade"> <p> <b> tapez </ b> État du rapport </ p> <p> <b> message </ b> <u> / </ u> </ p> <p> <b> description </ b> <u> La ressource demandée n’est pas disponible. </ u> </ p> < HR size = "1" noshade = "noshade"> <h3> Apache Tomcat / 7.0.34 </ h3> </ body> </ html> - Mohammad Shahid Siddiqui
Voir mon poster avec une approche similaire. - kenorb


[admin@automation-server 1.2.2]# nc -v -z -w2 192.168.193.173 6443
nc: connect to 192.168.193.173 port 6443 (tcp) failed: Connection refused

[admin@automation-server 1.2.2]# nc -v -z -w2 192.168.194.4 6443
Connection to 192.168.194.4 6443 port [tcp/sun-sr-https] succeeded!

J'espère que cela résout votre problème :)


8
2018-06-02 06:27



Oui, cela vaut mieux - expirer presque immédiatement pour les ports fermés. - Peter Mortensen
Est-ce que cela utilise toujours le protocole TCP ou existe-t-il un moyen de le faire vérifier UDP? - kmoe


Voici un one-liner:

</dev/tcp/localhost/11211 && echo Port is open || echo Port is closed

en utilisant la syntaxe Bash expliquée dans @lornix réponse.

Pour plus d'informations, vérifiez: Guide avancé de script Bash: Chapitre 29. /dev et /proc.


7
2018-03-16 11:21





Je me débattais toute la journée car aucune de ces réponses ne semblait fonctionner pour moi. Le problème est que la version la plus récente de nc n'a plus le -z flag, alors que l'accès direct via TCP (selon @lornix et @slm) échoue lorsque l'hôte n'est pas accessible. J'ai finalement trouvé cette page, où j'ai finalement trouvé non pas un mais deux exemples de travail:

  1. nc -w1 127.0.0.1 22 </dev/null

    (la -w flag s'occupe du timeout, et le </dev/null remplace le -z drapeau)

  2. timeout 1 bash -c '(echo > /dev/tcp/127.0.0.1/22) >/dev/null 2>&1'

    (la timeout commande prend en charge le délai d'attente, et le reste provient de @slm)

Ensuite, utilisez simplement && et / ou || (ou même $?) pour extraire le résultat. J'espère que quelqu'un trouvera cette information utile.


5
2018-05-31 08:45