2013-07-19 16:54:10 +0000 2013-07-19 16:54:10 +0000
369
369

Tester 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 essayait de se connecter à n'importe quel port sur n'importe quel hôte et vous donnait accès au flux TCP brut.

De nos jours, les systèmes sur lesquels je travaille n'ont pas de telnet installé (pour des raisons de sécurité), et toutes les connexions sortantes vers tous les hôtes sont bloquées par défaut. Avec le temps, il est facile de perdre la trace des ports qui sont ouverts à tel ou tel hôte.

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

Réponses (13)

418
418
418
2013-12-03 21:34:41 +0000

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

nc -zv 127.0.0.1 80

Ports multiples :

nc -zv 127.0.0.1 22 80 8080

Gamme de ports :

nc -zv 127.0.0.1 20-30
297
297
297
2013-07-22 10:37:11 +0000

Bash a pu accéder aux ports TCP et UDP pendant un certain temps. Depuis 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 !

104
104
104
2013-07-19 18:07:26 +0000

Netcat est un outil utile :

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

produira 0 si le port 123 est ouvert, et 1 s'il est fermé.

61
61
61
2014-09-02 17:59:36 +0000

La méthode la plus simple, sans faire appel à un autre outil, tel que socat, est celle décrite dans la réponse d’@lornix ci-dessus. Ceci est juste pour ajouter un exemple réel de la façon dont on utiliserait le psuedo-device /dev/tcp/... dans Bash si vous vouliez, par exemple, tester si un autre serveur avait un port donné accessible 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 mettre le echo > /dev/... entre parenthèses comme ceci, (echo > /dev/...) est que si vous ne le faites pas, alors avec les tests de connexions qui sont en panne, vous obtiendrez ce type de messages.

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

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

48
48
48
2013-07-19 17:05:30 +0000

J'ai découvert que curl peut faire le travail de manière similaire à telnet, et curl vous dira même quel protocole l'auditeur attend.

Construit 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 inadéquation de protocole et sortira (si l'auditeur n'est pas un service web). Si curl ne peut pas se connecter, il y aura un temps mort.

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

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

Cependant, depuis un système différent, le port 5672 sur l'hôte 10. 0.0.99 peut être atteint, et semble exécuter un auditeur 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 ne pouvait pas se connecter au port. Le deuxième échec est un test de réussite, bien que curl s'attendait à un auditeur HTTP au lieu d'un auditeur AMQP.

13
13
13
2015-06-02 06:27:59 +0000
[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ésoudra votre problème :)

11
11
11
2016-03-16 11:21:40 +0000

Voici une ligne :

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

utilisant la syntaxe Bash expliquée dans @lornix answer .

Pour plus d'informations, consultez : Guide avancé de script Bash : chapitre 29. /dev et /proc .

8
8
8
2017-05-31 08:45:09 +0000

J'ai lutté pendant toute une journée parce qu'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 drapeau -z, alors que l'accès direct via TCP (comme selon @lornix et @slm) échoue lorsque l'hôte n'est pas joignable. 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

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

Ensuite, il suffit d'utiliser && et/ou || (ou même $?) pour extraire le résultat. Nous espérons que ces informations seront utiles à quelqu'un.

6
6
6
2018-08-10 12:20:04 +0000

En combinant les réponses de @kenorb et @Azukikuru, vous pourriez tester les ports ouverts/fermés/firewalled.

timeout 1 bash -c '</dev/tcp/127.0.0.1/22 && echo Port is open || echo Port is closed' || echo Connection timeout

Une autre approche avec le curl pour atteindre n'importe quel port

curl telnet://127.0.0.1:22
4
4
4
2019-02-12 20:21:11 +0000

Voici une fonction qui permet de choisir une des méthodes en fonction de ce qui est installé sur votre système :

# Check_port <address> <port> 
check_port() {
if ["$(which nc)" != ""]; then 
    tool=nc
elif ["$(which curl)" != ""]; then
     tool=curl
elif ["$(which telnet)" != ""]; then
     tool=telnet
elif [-e /dev/tcp]; then
      if ["$(which gtimeout)" != ""]; then  
       tool=gtimeout
      elif ["$(which timeout)" != ""]; then  
       tool=timeout
      else
       tool=devtcp
      fi
fi
echo "Using $tool to test access to $1:$2"
case $tool in
nc) nc -v -G 5 -z -w2 $1 $2 ;;
curl) curl --connect-timeout 10 http://$1:$2 ;;
telnet) telnet $1 $2 ;;
gtimeout) gtimeout 1 bash -c "</dev/tcp/${1}/${2} && echo Port is open || echo Port is closed" || echo Connection timeout ;;
timeout) timeout 1 bash -c "</dev/tcp/${1}/${2} && echo Port is open || echo Port is closed" || echo Connection timeout ;;
devtcp) </dev/tcp/${1}/${2} && echo Port is open || echo Port is closed ;;
*) echo "no tools available to test $1 port $2";;
esac

}
export check_port
2
2
2
2013-07-19 17:01:16 +0000

Il ne devrait pas être disponible sur votre boîte, mais essayez avec nmap.

1
1
1
2019-08-07 23:17:13 +0000

pour référence, en développant la réponse de @peperunas :

la façon d'utiliser nmap pour tester, est :

nmap -p 22 127.0.0.1

(l'exemple ci-dessus utilise localhost à des fins de démonstration)

0
0
0
2018-10-26 13:49:54 +0000

Si vous devez tester plus qu'un système, vous pouvez utiliser notre outil de test dda-serverspec https://github.com/DomainDrivenArchitecture/dda-serverspec-crate ) pour ces tâches. Vous pouvez définir vos attentes

{:netcat [{:host "mywebserver.com" :port "443"}
          {:host "telnet mywebserver.com" :port "80"}
          {:host "telnet mywebserver.com" :port "8443"}]}

et tester ces attentes soit par rapport à localhost soit par rapport à des hôtes distants (connexion par ssh). Pour les tests à distance, vous devez définir une cible :

{:existing [{:node-name "test-vm1"
             :node-ip "35.157.19.218"}
            {:node-name "test-vm2"
             :node-ip "18.194.113.138"}]
 :provisioning-user {:login "ubuntu"}}

Vous pouvez effectuer le test avec java -jar dda-serverspec.jar --targets targets.edn serverspec.edn

Sous le capot, nous utilisons netcat comme indiqué ci-dessus …