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

272

Antigamente, usamos 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?

    
por Steve HHH 19.07.2013 / 18:54

11 respostas

228

O Bash conseguiu acessar TCP e UDP por um tempo. Na página do manual:

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

    
por 22.07.2013 / 12:37
319

Agradável e detalhado! Das man pages.
Porta única:

nc -zv 127.0.0.1 80

Múltiplas portas:

nc -zv 127.0.0.1 22 80 8080

Intervalo de portas:

nc -zv 127.0.0.1 20-30
    
por 03.12.2013 / 22:34
96

O Netcat é uma ferramenta útil:

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

A saída 0 se a porta 123 estiver aberta e 1 se estiver fechada.

    
por 19.07.2013 / 20:07
51

O método mais simples, sem fazer uso de outra ferramenta, como socat , é como descrito na resposta do @lornix acima. Isso é apenas para adicionar um exemplo real de como se poderia usar o psuedo-device /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

O motivo pelo qual você deseja agrupar o echo > /dev/... entre parênteses, (echo > /dev/...) é porque, se você não o fizer, com os testes de conexões desativados, você verá esses tipos de mensagens aparecendo. / p>

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

Eles não podem ser simplesmente redirecionados para /dev/null , já que estão vindo da tentativa de gravar dados no dispositivo /dev/tcp . Então, nós capturamos toda a saída dentro de um subcomando, ou seja, (...cmds...) e redirecionamos a saída do subcomando.

    
por 02.09.2014 / 19:59
36

Descobri que curl pode fazer o trabalho de maneira semelhante a telnet e curl dirá a você qual protocolo o ouvinte espera.

Construa um URI HTTP a partir do nome do host e da porta como o primeiro argumento para curl . Se curl puder se conectar, ele informará uma incompatibilidade de protocolo e sairá (se o ouvinte não for um serviço da web). Se curl não puder se conectar, o tempo limite será esgotado.

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, em 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 ocorreu porque curl não pôde se conectar à porta. A segunda falha é um teste de sucesso, embora curl esperasse um ouvinte HTTP em vez de um ouvinte AMQP.

    
por 19.07.2013 / 19:05
8
[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 isso resolva seu problema:)

    
por 02.06.2015 / 08:27
7

Aqui está o one-liner:

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

usando a sintaxe do Bash explicada na resposta do @lornix .

Para mais informações, consulte: Guia avançado de script de bash: capítulo 29. /dev e /proc .

    
por 16.03.2016 / 12:21
6

Eu estava lutando por um dia inteiro porque nenhuma dessas respostas parecia funcionar para mim. O problema é que a versão mais recente de nc não possui mais o sinal -z , enquanto o acesso direto via TCP (conforme @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

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

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

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

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

    
por 31.05.2017 / 10:45
2

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

    
por 19.07.2013 / 19:01
0

Combinando as respostas de @kenorb e @Azukikuru, você pode testar a porta aberta / fechada / com firewall.

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

Outra abordagem com curl para alcançar qualquer porta

curl telnet://127.0.0.1:22
    
por 10.08.2018 / 14:20
0

Se você tiver que testar mais do que no sistema, use nossa ferramenta de teste dda-serverspec ( link ) para essas tarefas. Você pode definir sua expectativa

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

e teste essas expectativas contra host local ou contra hosts remotos (conecte por ssh). Para testes remotos, você precisa definir um alvo:

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

Você pode executar o teste com java -jar dda-serverspec.jar --targets targets.edn serverspec.edn

Sob o capô, estamos usando o netcat como proposto acima ...

    
por 26.10.2018 / 15:49