Probar si el puerto telnet está activo dentro de un script de shell

10

Estoy tratando de crear un script para probar si es posible iniciar sesión a través de telnet. No quiero realmente iniciar sesión; por lo tanto, esperar no es necesario. Solo quiero ver si puedo obtener un mensaje de inicio de sesión. Esto se está haciendo desde un sistema Linux, así que he estado tratando de usar nc:

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

El problema es que esto está causando que mi consola se bloquee. Parece que -wrealmente no está cayendo la conexión.

También intenté usar telnet pero no puedo romper la conexión desde el script. Molesto

\echo "\035" | telnet 192.168.10.5

se rompe antes de recibir un mensaje de inicio de sesión.

rleon
fuente
Posible duplicado de superuser.com/questions/621870/...
vschum

Respuestas:

14

Bash proporciona pseudo dispositivos con los que probablemente esté familiarizado, como /dev/null. Sin embargo, existen otros dispositivos como /dev/tcpy /dev/udppara probar las conexiones de red, que también puede usar desde los scripts de Bash.

extracto de la página de manual de Bash

Bash maneja varios nombres de archivo especialmente cuando se usan en redirecciones, como se describe en la siguiente tabla:

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

Ejemplo

Aquí estoy probando la conexión a un host en mi dominio llamado skinner y viendo si puedo conectarme a su puerto 22.

NOTA: El puerto 22 es para SSH, para telnet use el puerto 23.

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

Genial, así que intentemos con un no puerto:

$ 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

Bueno, eso funciona, pero es una salida muy fea. No es para preocuparse. Puede ejecutarlo echo > /dev/tcp/...en una subshell y redirigir toda la salida /dev/nullpara limpiarlo un poco. Aquí está el patrón que puede usar dentro de sus 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
fuente
Si desea probar específicamente telnet, entonces, de forma predeterminada, se ejecuta en el puerto 23, por lo que donde slm ha usado 22 y 223, use 23.
Warwick
@Warwick: gracias, lo he agregado como una nota en la sección de ejemplos.
slm
@sim gracias por el comentario. Vi esto antes pero no pude hacerlo funcionar. Mi problema es que necesito poder grep o probar un inicio de sesión. En este caso, la consola está bloqueada y no se solicita inicio de sesión. # 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 da un inicio de sesión pero no puedo salir de él.
rleon
1
wow ... mucha redirección allí. # cat afile ^] después de ejecutar eso, solo está haciendo eco del descanso afile. Sigo jugando con eso pero siento que ya casi estoy allí.
rleon
7

Estás en el camino correcto usando nc, pero si realmente quieres probar si puedes establecer la conexión, usa el -zinterruptor de 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
fuente
esto no funciona en todos los sistemas, mi nc no tiene la bandera -z
Shapeshifter
Interesante. ¿Qué versión de nces esta?
DopeGhoti
Estoy en CentOS 7, y nc fue reemplazado por nmap-ncat que no tiene esa opción :(
Shapeshifter
Si recuerdo correctamente, el paquete que desea en CentOS es simplemente nc.
DopeGhoti
nc es nmap-ncat en centos 7
Shapeshifter
2

Sé que la respuesta es un poco tarde, pero estaba buscando cómo hacer esto y usar nc no era una opción por razones de seguridad, así que aquí está si puede ayudar a alguien.

Lo que faltaba en su eco inicial era el interruptor -e:

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

Y una nueva línea + el comando de salida para salir de Telnet después de desconectar. Como tal:

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

Obviamente, lo mismo funcionará si usa un estilo de bloque if enunciado y evalúa $? como lo hiciste inicialmente:

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

Mientras estamos en ello, en lo que respecta a nc, depende del sabor de nc que tenga (gnu ncat vs nmap-ncat). GNU tendrá el modificador -z:

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

mientras que el otro no lo hará y tendrá que canalizar una línea vacía a su nc para no quedarse atascado:

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

ejecutar nc -z 192.168.10.5 23en el símbolo del sistema o crear un script bash para ejecutar este comando.

Devuelve la siguiente declaración si la conexión es exitosa.

¡Conexión al puerto 192.168.10.5 23 [tcp / *] exitosa!

Joshua Waiswa
fuente