Teste se a porta telnet está ativa em um script de shell

10

Estou tentando criar um script para testar se é possível fazer login via telnet. Eu realmente não quero fazer login; portanto, não é necessário esperar. Eu só quero ver se consigo obter um prompt de login. Isso está sendo feito em um sistema Linux, então eu tenho tentado usar nc:

nc 192.168.10.5 23 -w 1 | grep -q login 
if [ $? -eq 1 ]
then
    echo "console is down"
fi

O problema é que isso está causando o bloqueio do meu console. Parece que o -wrealmente não está descartando a conexão.

Também tentei usar o telnet, mas não sou capaz de interromper a conexão no script. Tentando

\echo "\035" | telnet 192.168.10.5

quebras antes de eu receber uma solicitação de login.

rleon
fonte
Possível duplicata de superuser.com/questions/621870/…
vschum

Respostas:

14

O Bash fornece pseudo-dispositivos com os quais você provavelmente já conhece /dev/null. No entanto, existem outros dispositivos, como /dev/tcpe /dev/udppara testar conexões de rede, que você também pode usar nos scripts do Bash.

trecho da página de manual do Bash

O Bash lida com vários nomes de arquivos, especialmente quando eles são usados ​​em redirecionamentos, conforme descrito na tabela a seguir:

          /dev/fd/fd
                 If fd is a valid integer, file descriptor fd is duplicated.
          /dev/stdin
                 File descriptor 0 is duplicated.
          /dev/stdout
                 File descriptor 1 is duplicated.
          /dev/stderr
                 File descriptor 2 is duplicated.
          /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.

Exemplo

Aqui, estou testando a conexão com um host no meu domínio chamado skinner e vendo se consigo conectar à sua porta 22.

NOTA: A porta 22 é para SSH, para telnet use a porta 23.

$ echo > /dev/tcp/skinner/22 && echo "it's up" || echo "it's down"
it's up

Ótimo, então vamos tentar uma não porta:

$ echo > /dev/tcp/skinner/223 && echo "it's up" || echo "it's down"
bash: connect: Connection refused
bash: /dev/tcp/skinner/223: Connection refused
it's down

Bem, isso funciona, mas é uma saída terrivelmente feia. Não se preocupe. Você pode executar o echo > /dev/tcp/...subshell e redirecionar toda a saída /dev/nullpara limpá-la um pouco. Aqui está o padrão que você pode usar em seus scripts de shell:

$ (echo > /dev/tcp/skinner/22) > /dev/null 2>&1 \
    && echo "it's up" || echo "it's down"
it's up

$ (echo > /dev/tcp/skinner/223) > /dev/null 2>&1 \
    && echo "it's up" || echo "it's down"
it's down
slm
fonte
Se você deseja especificamente testar telnet, então, por padrão, é executado na porta 23; portanto, onde o slm usou 22 e 223, use 23.
Warwick
@ Warwick - obrigado, eu adicionei isso como uma observação na seção de exemplos.
slm
@ sim obrigado pelo comentário. Eu já vi isso antes, mas não consegui fazê-lo funcionar com isso. Meu problema é que preciso conseguir grep ou testar um prompt de login. Nesse caso, o console está bloqueado e não há solicitação de login. # telnet 192.168.10.5 Trying 192.168.10.5... Connected to 192.168.10.5 (192.168.10.5). Escape character is '^]'. Connection closed by foreign host.
rleon
# cat < /dev/tcp/192.168.10.12/23 me dá um prompt de login, mas não consigo sair dele.
rleon
1
uau .. colocar redirecionamento lá. # cat afile ^] depois de executar isso, está apenas ecoando a pausa para afile. Ainda estou brincando, mas sinto que estou quase lá.
rleon
7

Você está no caminho certo nc, mas se realmente deseja apenas testar se pode estabelecer a conexão, use o -zswitch da nc :

#!/bin/bash
REMOTEHOST=10.11.12.13
REMOTEPORT=1234
TIMEOUT=1

if nc -w $TIMEOUT -z $REMOTEHOST $REMOTEPORT; then
    echo "I was able to connect to ${REMOTEHOST}:${REMOTEPORT}"
else
    echo "Connection to ${REMOTEHOST}:${REMOTEPORT} failed. Exit code from Netcat was ($?)."
fi
DopeGhoti
fonte
isso não funciona em todos os sistemas, meu nc não tem a bandeira -z
Metamorfo
Interessante. Qual versão ncé essa?
DopeGhoti
Estou no CentOS 7, e nc foi substituído com o nmap-NCAT que não têm essa opção :(
Metamorfo
Se bem me lembro, o pacote que você deseja no CentOS é simples nc.
DopeGhoti
nc é nmap-ncat no centos 7
Shapeshifter
2

Eu sei que a resposta está um pouco atrasada, mas eu estava pensando em como fazer isso e usar o nc não era uma opção por razões de segurança, então aqui está, se ele puder ajudar alguém.

O que estava faltando no seu eco inicial era a opção -e:

   -e     enable interpretation of backslash escapes
   -E     disable interpretation of backslash escapes (default)

E uma nova linha + o comando quit para sair do telnet após desconectar. Assim sendo:

echo -e '\035\nquit' | telnet 10.0.0.1 23 && echo "success" || echo "failed"

Obviamente, o mesmo funcionará se você usar um estilo de bloco if e avaliar $? como você fez inicialmente:

echo -e '\035\nquit' | telnet 10.0.0.1 23
if [ $? -eq 1 ]
then
  echo "Console is down."
fi

Enquanto estamos nisso, no que diz respeito a nc, depende de qual sabor de nc você tem (gnu ncat vs nmap-ncat). O GNU terá a opção -z:

  -z                         Zero-I/O mode, report connection status only
nc -z 10.0.0.1 23
# (evaluate $? here)

enquanto o outro não e você terá que canalizar uma linha vazia para o seu nc para não ficar preso:

echo | nc 10.0.0.1 23
# (evaluate $? here)
Alex B
fonte
1

execute nc -z 192.168.10.5 23no prompt de comando ou crie um script bash para executar este comando.

Retorna a instrução abaixo se a conexão for bem-sucedida.

A conexão à porta 192.168.10.5 23 [tcp / *] foi bem-sucedida!

Joshua Waiswa
fonte