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

Testen, ob ein Port auf einem entfernten System erreichbar ist (ohne Telnet)

Früher verwendeten wir telnet, um zu sehen, ob ein Port auf einem entfernten Host offen war: telnet hostname port versuchte, eine Verbindung zu einem beliebigen Port auf einem beliebigen Host herzustellen und Ihnen Zugriff auf den rohen TCP-Stream zu geben.

Heutzutage ist auf den Systemen, auf denen ich arbeite, kein Telnet installiert (aus Sicherheitsgründen), und alle ausgehenden Verbindungen zu allen Hosts sind standardmäßig blockiert. Mit der Zeit verliert man leicht den Überblick, welche Ports zu welchen Hosts offen sind.

Gibt es eine andere Möglichkeit zu testen, ob ein Port auf einem entfernten System offen ist - mit einem Linux-System, auf dem eine begrenzte Anzahl von Paketen installiert ist, und telnet ist nicht verfügbar?

Antworten (13)

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

Nett und wortreich! Aus den Man Pages: Einzelner Port:

nc -zv 127.0.0.1 80

Mehrere Ports:

nc -zv 127.0.0.1 22 80 8080

Bereich von Ports:

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

Bash kann seit einiger Zeit auf die Ports TCP und UDP zugreifen. Aus der Manpage:

/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.

Also könnte man so etwas wie das hier verwenden:

Taa Daa!

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

Netcat ist ein nützliches Tool:

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

gibt 0 aus, wenn Port 123 offen ist, und 1, wenn er geschlossen ist.

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

Die einfachste Methode, ohne die Verwendung eines anderen Werkzeugs, wie z.B. socat, ist die in der Antwort von @lornix oben beschriebene. Dies ist nur, um ein tatsächliches Beispiel dafür hinzuzufügen, wie man das Psuedo-Gerät /dev/tcp/... innerhalb der Bash verwenden würde, wenn man z.B. testen wollte, ob ein anderer Server einen bestimmten Port über die Befehlszeile zugänglich hat.

Beispiele

Sagen wir, ich habe einen Host in meinem Netzwerk mit dem Namen 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

Der Grund, warum Sie die echo > /dev/... so in Klammern setzen wollen, (echo > /dev/...) ist, weil Sie sonst bei Tests von Verbindungen, die gestört sind, diese Art von Meldungen erhalten.

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

Diese können nicht einfach zu /dev/null umgeleitet werden, da sie von dem Versuch kommen, Daten auf das Gerät /dev/tcp auszuschreiben. Wir erfassen also die gesamte Ausgabe innerhalb eines Unterbefehls, d.h. (...cmds...), und leiten die Ausgabe des Unterbefehls um.

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

Ich habe festgestellt, dass curl die Aufgabe auf ähnliche Weise erledigen kann wie telnet, und curl wird Ihnen sogar sagen, welches Protokoll der Hörer erwartet.

Konstruieren Sie eine HTTP-URI aus dem Hostnamen und dem Port als erstes Argument für curl. Wenn curl eine Verbindung herstellen kann, meldet es eine Protokollabweichung und beendet sich (wenn der Listener kein Webdienst ist). Wenn curl keine Verbindung herstellen kann, wird ein Timeout durchgeführt.

Zum Beispiel ist Port 5672 auf Host 10.0.0.99 entweder geschlossen oder durch eine Firewall blockiert:

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

Jedoch von einem anderen System aus, Port 5672 auf Host 10. 0.0.99 erreicht werden kann, und scheint einen AMQP-Listener zu betreiben:

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

Es ist wichtig, zwischen den verschiedenen Meldungen zu unterscheiden: Der erste Fehler war, dass curl keine Verbindung zu dem Port herstellen konnte. Der zweite Fehlschlag ist ein Erfolgstest, obwohl curl einen HTTP-Listener statt eines AMQP-Listeners erwartete.

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!

Hoffentlich löst es Ihr Problem :)

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

Hier ist ein Einzeiler:

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

unter Verwendung der Bash-Syntax, die in @lornix answer erklärt wird.

Weitere Informationen finden Sie hier: Erweiterte Bash-Skripting-Anleitung: Kapitel 29. /dev und /proc .

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

Ich hatte einen ganzen Tag lang zu kämpfen, weil keine dieser Antworten für mich zu funktionieren schien. Das Problem ist, dass die neueste Version von nc nicht mehr das Flag -z hat, während der direkte Zugriff über TCP (wie nach @lornix und @slm) fehlschlägt, wenn der Host nicht erreichbar ist. Schließlich fand ich diese Seite , wo ich schließlich nicht nur ein, sondern zwei Arbeitsbeispiele fand:

  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'

Dann benutze einfach && und/oder || (oder sogar $?), um das Ergebnis zu extrahieren. Hoffentlich findet jemand diese Informationen nützlich.

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

Kombiniert man die Antworten von @kenorb und @Azukikuru, könnte man Port offen/geschlossen/firewalled testen

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

Ein anderer Ansatz mit Curl, um jeden Port zu erreichen

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

Hier ist eine Funktion, die eine der Methoden auswählt, je nachdem, was auf Ihrem System installiert ist:

# 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

Es sollte nicht auf Ihrer Box verfügbar sein, aber versuchen Sie es mit nmap.

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

zur Referenz, erweitert auf @peperunas’ Antwort:

die Art und Weise, wie man nmap zum Testen verwendet, ist:

nmap -p 22 127.0.0.1

(obiges Beispiel verwendet localhost zu Demonstrationszwecken)

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

Wenn Sie mehr als auf dem System testen müssen, können Sie für solche Aufgaben unser Testwerkzeug dda-serverspec https://github.com/DomainDrivenArchitecture/dda-serverspec-crate ) verwenden. Sie können Ihre Erwartung

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

definieren und diese Erwartung entweder gegen localhost oder gegen entfernte Hosts (connect by ssh) testen. Für Remote-Tests müssen Sie ein Ziel definieren:

{: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"}}

Sie können den Test mit java -jar dda-serverspec.jar --targets targets.edn serverspec.edn

ausführen. Unter der Haube verwenden wir netcat wie oben beschrieben …