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

Test of een poort op een extern systeem bereikbaar is (zonder telnet)

Vroeger gebruikten we telnet om te zien of een poort op een externe host open was: telnet hostname port probeerde verbinding te maken met elke poort op elke host en gaf u toegang tot de ruwe TCP-stream.

Tegenwoordig hebben de systemen waar ik op werk geen telnet geïnstalleerd (om veiligheidsredenen) en worden alle uitgaande verbindingen met alle hosts standaard geblokkeerd. Na verloop van tijd is het gemakkelijk om bij te houden welke poorten openstaan voor welke hosts.

Is er een andere manier om te testen of een poort op een systeem op afstand open is - met behulp van een Linux systeem met een beperkt aantal geïnstalleerde packages, en telnet is niet beschikbaar?

Antwoorden (13)

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

Lekker verveeld! Van de man pagina’s. Enkele poort:

nc -zv 127.0.0.1 80

Meerdere poorten:

nc -zv 127.0.0.1 22 80 8080

Bereik van poorten:

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

Bash heeft al een tijdje toegang tot TCP en UDP -poorten. Vanaf de man pagina: /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.

. Dus je zou zoiets als dit kunnen gebruiken:

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 is een nuttig hulpmiddel:

nc 127.0.0.1 123 &> /dev/null; echo $? Geeft 0 weer als poort 123 open is, en 1 als deze gesloten is.

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

De eenvoudigste methode, zonder gebruik te maken van een ander instrument, zoals socat, is zoals beschreven in het antwoord van @lornix hierboven. Dit is alleen maar om een actueel voorbeeld toe te voegen van hoe men gebruik zou maken van het psuedo-apparaat /dev/tcp/... binnen Bash als je bijvoorbeeld wilt testen of een andere server een bepaalde poort toegankelijk heeft via de commandoregel.

Voorbeelden

Zeg dat ik een host heb op mijn netwerk met de naam 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

De reden dat je de echo > /dev/... tussen haakjes wilt omwikkelen, (echo > /dev/...) is omdat als je dat niet doet, dan krijg je met tests van verbindingen die down zijn, dit soort berichten te zien.

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

Deze kunnen niet eenvoudigweg worden omgeleid naar /dev/null omdat ze komen van de poging om data uit te schrijven naar het apparaat /dev/tcp. Dus we leggen al die uitvoer vast binnen een subcommando, d.w.z. (...cmds...) en sturen de uitvoer van het subcommando om.

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

Ik vond dat curl de klus op een soortgelijke manier als telnet kan klaren, en curl zal je zelfs vertellen welk protocol de luisteraar verwacht.

Construeer een HTTP URI van de hostnaam en de poort als eerste argument naar curl. Als curl verbinding kan maken, zal het een protocol mismatch rapporteren en zal het afsluiten (als de luisteraar geen webservice is). Als curl geen verbinding kan maken, zal het time out gaan.

Bijvoorbeeld, poort 5672 op host 10.0.0.99 wordt ofwel gesloten ofwel geblokkeerd door een firewall:

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

echter, vanaf een ander systeem, poort 5672 op host 10. 0.0.99 kan worden bereikt, en lijkt een AMQP luisteraar te draaien.

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

Het is belangrijk om onderscheid te maken tussen de verschillende berichten: de eerste storing was omdat curl geen verbinding kon maken met de poort. De tweede storing is een succestest, maar curl verwachtte een HTTP listener in plaats van een AMQP listener.

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!

Hoop dat het uw probleem oplost :)

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

Hier is one-liner:

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

met behulp van Bash syntaxis uitgelegd in @lornix antwoord .

Voor meer info, check: Geavanceerde Bash-Scripting Gids: Hoofdstuk 29. /dev en /proc .

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

Ik heb een hele dag geworsteld omdat geen van deze antwoorden voor mij leek te werken. Het probleem is dat de meest recente versie van nc niet meer de -z vlag heeft, terwijl directe toegang via TCP (zoals volgens @lornix en @slm) faalt wanneer de host niet bereikbaar is. Uiteindelijk vond ik deze pagina , waar ik uiteindelijk niet één maar twee werkende voorbeelden vond:

  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'

Dan gebruik je gewoon && en/of || (of zelfs $?) om het resultaat te extraheren. Hopelijk vindt iemand deze informatie nuttig.

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

Door de antwoorden van @kenorb en @Azukikuru te combineren kunt u open/gesloten/gefileerde poorten testen.

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

Een andere benadering met curl voor het bereiken van een willekeurige poort

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

Hier is een functie die een van de methoden zal kiezen, afhankelijk van wat er geïnstalleerd is op uw systeem:

# 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

Het zou niet op je doos moeten staan, maar probeer het met nmap.

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

ter referentie, voortbouwend op het antwoord van @peperunas:

de manier om nmap te gebruiken om te testen, is:

nmap -p 22 127.0.0.1

(bovenstaand voorbeeld gebruikt localhost voor demonstratiedoeleinden)

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

Als u meer moet testen dan op het systeem, kunt u onze testtool dda-serverspec https://github.com/DomainDrivenArchitecture/dda-serverspec-crate ) voor dergelijke taken gebruiken. U kunt uw verwachting

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

definiëren en deze verwachting testen tegen de localhost of tegen externe hosts (connect by ssh). Voor tests op afstand moet je een doelwit definiëren:

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

Je mag de test uitvoeren met java -jar dda-serverspec.jar --targets targets.edn serverspec.edn

Onder de motorkap gebruiken we netcat als proprosed hierboven …