Questão Teste se uma porta em um sistema remoto é alcançável (sem telnet)


Antigamente, usávamos telnet para ver se uma porta em um host remoto estava aberta: telnet hostname port tentaria se conectar a qualquer porta em qualquer host e fornecer acesso ao fluxo TCP bruto.

Atualmente, os sistemas em que eu trabalho não têm o telnet instalado (por questões de segurança) e todas as conexões de saída para todos os hosts são bloqueadas por padrão. Com o tempo, é fácil perder o controle de quais portas estão abertas para quais hosts.

Existe outra maneira de testar se uma porta em um sistema remoto está aberta - usando um sistema Linux com um número limitado de pacotes instalados, e telnet não está disponível?


251


origem


Relacionado: verifique o status de uma porta no host remoto no SO - kenorb


Respostas:


Bash conseguiu acessar TCP e UDP portas por um tempo. Na página 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.

Então você poderia usar algo assim:

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

Taa Daa!


214



Isso também parece funcionar em MinGW. Por exemplo, um controle remoto VNC servidor em 192.168.2.100 responde com "RFB 003.008" usando "cat </dev/tcp/192.168.2.100/5900". - Peter Mortensen
No entanto, em portas que não estavam abertas, expirou após 22 segundos (testado Ubuntu 14.04 (Trust Tahr) para um servidor remoto). Curiosamente, o período de tempo limite é muito menor do que o de nc (ver a resposta é). - Peter Mortensen
@lornix, ok, mas neste caso eu tenho que obter o mesmo resultado com o uso nc sem a opção -z, mas ainda assim não funciona: # nc -v -w5 127.0.0.1 18080 Conexão com 127.0.0.1 porta 18080 [tcp / *] sucedeu! # cat </dev/tcp/127.0.0.1/18080 Apenas trava sem nenhum resultado. Só quero entender quando eu posso usar a opção "/ dev / tcp / host / port" - Alexandr
@Alexandr ... na verdade, "trava sem nenhum resultado" é praticamente o comportamento esperado. gato está esperando por entrada. nc tem inteligência extra para permitir que ele detecte nenhum dado pendente e pare de tentar. gato não é bastante tão inteligente. Experimentar cat < /dev/tcp/localhost/22, você deve obter o seu cabeçalho sshd. Evidentemente, o seu processo na porta 18080 aguarda que algo entre antes de enviar qualquer coisa. Port 22 (sshcumprimenta você com sua versão e outros enfeites. Experimente! - lornix
@lornix, muito obrigado pela explicação! Agora a restrição é clara. Acho que usar o nc deve ser uma maneira preferida de verificar portas. - Alexandr


Bom e detalhado! Das man pages.
Única porta:

nc -zv 127.0.0.1 80

Várias portas:

nc -zv 127.0.0.1 22 80 8080

Gama de portas:

nc -zv 127.0.0.1 20-30

294



Parece ser a melhor resposta, obrigado. ;-) - lpapp
Este enforcado quando experimentado Ubuntu 14.04 (Trusty Tahr) para um servidor remoto (mesma LAN) para portas fechadas (o tempo limite expirou após 127 segundos) - portanto, não é muito adequado em scripts. Entretanto, funcionou para um serviço que tinha uma porta aberta. Usando a opção "-w2" poderia ser a solução. - Peter Mortensen
Use a opção -u para portas UDP. - Efren
Na versão 6.4 do ncat -z não é reconhecido. Eu era capaz de fazer sem z - smishra
Você pode verificar vários intervalos com: nc -zv 127.0.0.1 22,80,8080,20-30,443-446 (nc Versão: 1.107-4). - bobbel


O Netcat é uma ferramenta útil:

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

Saída 0 se a porta 123 estiver aberta e 1 se está fechado.


96



Esta é uma resposta muito mais elegante e roteirizável do que a minha. É lamentável para mim que os administradores conscientes da segurança que retiveram telnettambém retido nc (embora - estranhamente - não curl ou wget). - Steve HHH
Sim, isso é completamente arbitrário e bobo. - thnee
Deixe o FOR as declarações começam! - Chad Harrison
Este enforcado quando experimentado Ubuntu 14.04 (Trusty Tahr) para um servidor remoto (mesma LAN) para portas fechadas (o tempo limite expirou após cerca de 127 segundos) - portanto, não é muito adequado em scripts. Ele funcionou para um serviço que tinha uma porta aberta, retornando 0. Usando a opção "-w2" poderia ser a solução. - Peter Mortensen
eu acho que -G 2 seria mais apropriado para o tempo limite do TCP - A B


O método mais simples, sem fazer uso de outra ferramenta, como socat, é como descrito na resposta do @ lornix acima. Isto é apenas para adicionar um exemplo real de como se faria uso do dispositivo psuedo /dev/tcp/... no Bash se você quisesse, por exemplo, testar se outro servidor tinha uma porta específica acessível através da linha de comando.

Exemplos

Digamos que eu tenha um host na minha rede chamado 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

A razão pela qual você quer envolver o echo > /dev/... entre parênteses assim, (echo > /dev/...) é porque, se você não fizer isso, com testes de conexões que estão inativos, você verá esses tipos de mensagens aparecendo.

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

Estes não podem simplesmente ser redirecionados para /dev/null desde que eles estão vindo da tentativa de escrever dados para o dispositivo /dev/tcp. Então, capturamos toda essa saída em um subcomando, ou seja, (...cmds...) e redirecionar a saída do subcomando.


48



Isto e excelente. Queria que fosse votado até o topo. Eu só li até aqui na página porque acidentalmente rolei antes de fechá-lo. - Still.Tony
@ Okuma.Tony - sim, isso é sempre um problema com os Q's que têm muitas respostas 8-). Obrigado pelo feedback, é apreciado. - slm


eu achei aquilo curl pode fazer o trabalho de forma semelhante ao telnete curl até lhe dirá qual protocolo o ouvinte espera.

Construa um URI HTTP a partir do nome do host e porta como o primeiro argumento para curl. E se curl pode se conectar, ele relatará uma incompatibilidade de protocolo e sairá (se o ouvinte não for um serviço da web). E se curl não pode se conectar, vai expirar.

Por exemplo, a porta 5672 no host 10.0.0.99 está fechada ou bloqueada por um firewall:

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

No entanto, de um sistema diferente, a porta 5672 no host 10.0.0.99 pode ser acessada e parece estar executando um ouvinte AMQP.

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

É importante distinguir entre as diferentes mensagens: a primeira falha foi porque curl não pôde se conectar à porta. A segunda falha é um teste de sucesso, embora curl esperava um ouvinte HTTP em vez de um ouvinte AMQP.


35



Se o curl não estiver disponível, o wget poderá estar. wget -qS -O- http://ip.add.re.ss:port deve efetivamente fazer a mesma coisa. - Michael Kjörling
Isso funciona mesmo com um nome de host, ex. curl myhost:22. - 에이바
Isso pode estar incorreto. Eu estou tendo um serviço de tomcat em execução, mas recebendo erro 404. # curl -k 192.168.194.4:6443 <html> <head> <title> Apache Tomcat / 7.0.34 - Relatório de erros </ title> <style> <! - H1 --- HR {color: # 525D76;} -> </ style> </ head> <body> <h1> Estado HTTP 404 - / </ h1> <HR size = "1" noshade = "noshade"> <p> <b> escreva </ b> Relatório de estado </ p> <p> <b> message </ b> <u> / </ u> </ p> <p> <b> descrição </ b> <u> O recurso solicitado não está disponível. </ u> </ p> < Tamanho da FC = "1" noshade = "noshade"> <h3> Apache Tomcat / 7.0.34 </ h3> </ body> </ html> - Mohammad Shahid Siddiqui
Ver meu postar com abordagem semelhante. - 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!

Espero que resolva o seu problema :)


8



Sim, isso é melhor - tempo limite quase que imediatamente para portas fechadas. - Peter Mortensen
Isso sempre usa TCP ou existe uma maneira de obtê-lo para verificar o UDP? - kmoe


Aqui está o one-liner:

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

usando a sintaxe Bash explicada em @lornix resposta.

Para mais informações, verifique: Guia Avançado de Roteiro de Roteiro: Capítulo 29. /dev e /proc.


7





Eu estava lutando por um dia inteiro porque nenhuma dessas respostas parecia funcionar para mim. O problema é que a versão mais recente do nc não tem mais -z flag, enquanto o acesso direto via TCP (como de acordo com @lornix e @slm) falha quando o host não está acessível. Eu finalmente encontrei esta página, onde eu finalmente encontrei não um, mas dois exemplos de trabalho:

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

    (a -w flag cuida do tempo limite, e o </dev/null substitui o -z bandeira)

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

    (a timeout comando cuida do tempo limite, e o resto é de @slm)

Então, simplesmente use && e / ou || (ou até mesmo $?) para extrair o resultado. Espero que alguém ache esta informação útil.


5





Não deve estar disponível na sua caixa, mas tente com nmap.


2



nmap é uma boa ferramenta, mas não está disponível nesses sistemas. Em vez de baixar nmap, compilá-lo, instalá-lo no meu diretório home, copiá-lo para todos os outros sistemas, eu estava esperando encontrar uma maneira de usar as ferramentas existentes disponíveis na maioria das instalações do Linux. - Steve HHH