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

Prova se una porta su un sistema remoto è raggiungibile (senza telnet)

Ai vecchi tempi, usavamo telnet per vedere se una porta su un host remoto era aperta: telnet hostname port tentava di connettersi a qualsiasi porta su qualsiasi host e ti dava accesso al raw TCP stream.

Oggigiorno, i sistemi su cui lavoro non hanno telnet installato (per ragioni di sicurezza), e tutte le connessioni in uscita verso tutti gli host sono bloccate di default. Con il tempo, è facile perdere la traccia di quali porte sono aperte a quali host.

C'è un altro modo per verificare se una porta su un sistema remoto è aperta - utilizzando un sistema Linux con un numero limitato di pacchetti installati, e telnet non è disponibile?

Risposte (13)

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

Bello e verboso! Dalle pagine man. Porta singola:

nc -zv 127.0.0.1 80
``` ```
nc -zv 127.0.0.1 22 80 8080

Porta multipla:

nc -zv 127.0.0.1 20-30
``` &001 

Gamma di porte: 


&001
297
297
297
2013-07-22 10:37:11 +0000

Bash ha potuto accedere alle porte TCP e UDP per un certo periodo. Dalla pagina man:

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

Quindi si potrebbe usare qualcosa del genere:

&001

Taa Daa!

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

Netcat è uno strumento utile:

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

emetterà 0 se la porta 123 è aperta, e 1 se è chiusa.

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

Il metodo più semplice, senza ricorrere ad un altro strumento, come socat, è quello descritto nella risposta di @lornix. Questo è solo per aggiungere un esempio concreto di come si potrebbe utilizzare il dispositivo psuedo-device /dev/tcp/... all'interno di Bash se si volesse, ad esempio, testare se un altro server ha una data porta accessibile tramite la riga di comando.

Esempi

Esempi

Diciamo che ho un host sulla mia rete chiamato 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
``` ```
$ (echo > /dev/tcp/skinner/223) && echo hi
bash: connect: Connection refused
bash: /dev/tcp/skinner/223: Connection refused

La ragione per cui si vuole avvolgere il echo > /dev/... tra parentesi come questa, (echo > /dev/...) è che se non lo si fa, allora con i test delle connessioni che sono inattive, si ottengono questi tipi di messaggi che appaiono.

&001 &001

Questi non possono essere semplicemente reindirizzati a /dev/null perché provengono dal tentativo di scrivere i dati al dispositivo /dev/tcp. Quindi catturiamo tutti questi output all'interno di un sottocomando, cioè (...cmds...) e reindirizziamo l'output del sottocomando.

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

Ho scoperto che curl può portare a termine il lavoro in modo simile a telnet, e curl vi dirà anche quale protocollo l'ascoltatore si aspetta.

Costruire un URI HTTP dal nome host e dalla porta come primo argomento a curl. Se curl può connettersi, segnalerà un errore di protocollo e uscirà (se l'ascoltatore non è un servizio web). Se curl non riesce a connettersi, si blocca in time out.

Per esempio, la porta 5672 sull'host 10.0.0.99 è chiusa o bloccata da un firewall:

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

Tuttavia, da un sistema diverso, la porta 5672 sull'host 10. 0.0.99 è raggiungibile, e sembra che sia in funzione un ascoltatore AMQP.

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


E' importante distinguere i diversi messaggi: il primo guasto è dovuto al fatto che `curl` non è riuscito a connettersi alla porta. Il secondo guasto è un test di successo, anche se `curl` si aspettava un ascoltatore HTTP invece di un ascoltatore 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!

Spero che risolva il vostro problema :)

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

Qui c'è una sola riga:

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


utilizzando la sintassi di Bash spiegata in [ @lornix risposta ](https://superuser.com/a/622641/87805). 


Per ulteriori informazioni, controllare: [ Guida avanzata alla scrittura Bash: Capitolo 29. `/dev` e `/proc` ](http://www.tldp.org/LDP/abs/html/devref1.html).
8
8
8
2017-05-31 08:45:09 +0000

Ho lottato per un giorno intero perché nessuna di queste risposte sembrava funzionare per me. Il problema è che la versione più recente di nc non ha più il flag -z, mentre l'accesso diretto via TCP (come secondo @lornix e @slm) fallisce quando l'host non è raggiungibile. Alla fine ho trovato questa pagina , dove alla fine ho trovato non uno ma due esempi funzionanti:

  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'

Poi, semplicemente usare && e/o || (o anche $?) per estrarre il risultato. Speriamo che qualcuno trovi utile questa informazione.

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

Combinando le risposte di @kenorb e @Azukikuru si possono testare le porte aperte/chiuse/avviate.

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

Un altro approccio con curl per raggiungere qualsiasi porta

&001

4
4
4
2019-02-12 20:21:11 +0000

Ecco una funzione che sceglierà uno dei metodi a seconda di ciò che è installato sul vostro sistema:

# 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

Non dovrebbe essere disponibile sulla vostra scatola, ma provate con nmap.

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

per riferimento, ampliando la risposta di @peperunas:

il modo di utilizzare nmap per i test, è:

nmap -p 22 127.0.0.1
``` &001 



(l'esempio sopra riportato utilizza localhost a scopo dimostrativo)
0
0
0
2018-10-26 13:49:54 +0000

Se si deve testare più che sul sistema si può utilizzare il nostro strumento di prova dda-serverspec https://github.com/DomainDrivenArchitecture/dda-serverspec-crate ) per tali compiti. Potete definire le vostre aspettative

{:netcat [{:host "mywebserver.com" :port "443"}
          {:host "telnet mywebserver.com" :port "80"}
          {:host "telnet mywebserver.com" :port "8443"}]}
``` ```
{: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"}}

e testare queste aspettative sia contro localhost che contro host remoti (connessione tramite ssh). Per i test remoti dovete definire un target:

&001 &001

Potete eseguire il test con java -jar dda-serverspec.jar --targets targets.edn serverspec.edn

Sotto il cofano stiamo usando netcat come proproseduto sopra …