Sprawdź, czy port telnet jest aktywny w skrypcie powłoki


11

Próbuję utworzyć skrypt, aby sprawdzić, czy można zalogować się przez telnet. Nie chcę się naprawdę logować; dlatego oczekiwanie nie jest potrzebne. Chcę tylko sprawdzić, czy mogę uzyskać monit o zalogowanie. Odbywa się to z systemu Linux, więc próbowałem użyć nc:

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

Problem polega na tym, że powoduje to blokowanie się konsoli. Wygląda na -wto, że tak naprawdę nie porzuca połączenia.

Próbowałem także użyć telnet, ale nie jestem w stanie przerwać połączenia z poziomu skryptu. Próbować

\echo "\035" | telnet 192.168.10.5

pęka, zanim pojawi się monit o zalogowanie.


Odpowiedzi:


14

Bash zapewnia pseudo urządzenia, które prawdopodobnie znasz /dev/null. Istnieją jednak inne urządzenia, takie jak /dev/tcpi /dev/udpdo testowania połączeń sieciowych, których można również używać w skryptach Bash.

fragment strony podręcznika Basha

Bash obsługuje kilka nazw plików, zwłaszcza gdy są one używane w przekierowaniach, jak opisano w poniższej tabeli:

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

Przykład

Oto testuję połączenie z hostem w mojej domenie o nazwie skinner i sprawdzam, czy mogę połączyć się z jego portem 22.

UWAGA: Port 22 jest dla SSH, dla portu telnet użyj portu 23.

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

Świetnie, więc spróbujmy bez portu:

$ 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

Cóż, to działa, ale jest okropnie brzydkie. Nie martwić się. Możesz uruchomić echo > /dev/tcp/...podpowłokę i przekierować wszystkie dane wyjściowe, aby /dev/nullje trochę wyczyścić. Oto wzór, którego możesz użyć w skryptach powłoki:

$ (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

Jeśli szczególnie chcesz przetestować telnet, to domyślnie działa on na porcie 23, więc tam gdzie slm użył 22 i 223, użyj 23.
Warwick

@Warwick - dzięki, dodałem to jako notatkę w sekcji przykładów.
slm

@im dziękuję za komentarz. Widziałem to wcześniej, ale nie byłem w stanie zmusić go do pracy z tym. Mój problem polega na tym, że muszę być w stanie grep lub przetestować prośbę o zalogowanie się. W takim przypadku konsola jest zablokowana i nie pojawia się monit o zalogowanie. # 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 wyświetla monit o zalogowanie się, ale nie jestem w stanie się z niego wyrwać.
rleon

1
wow ... dużo przekierowań tam. # cat afile ^] po uruchomieniu, że to tylko echo przerwy na afile. Nadal się tym bawię, ale czuję, że już prawie jestem.
rleon

7

Używasz właściwej ścieżki nc, ale jeśli naprawdę chcesz po prostu sprawdzić, czy możesz nawiązać połączenie, użyj przełącznika nc-z :

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

to nie działa na wszystkich systemach, mój nc nie ma flagi -z
Shapeshifter

Ciekawy. Która to wersja nc?
DopeGhoti

Jestem na CentOS 7, a nc został zastąpiony przez nmap-ncat, który nie ma tej opcji :(
Shapeshifter

Jeśli dobrze pamiętam, pakiet, który chcesz w CentOS, jest po prostu nc.
DopeGhoti

nc to nmap-ncat w centos 7
Shapeshifter

2

Wiem, że odpowiedź jest nieco spóźniona, ale szukałem, jak to zrobić, a użycie nc nie było rozwiązaniem ze względów bezpieczeństwa, więc tutaj może pomóc komuś.

W początkowym echu brakowało przełącznika -e:

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

I nowa linia + polecenie quit, aby wyjść z Telnet po rozłączeniu. Takie jak:

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

Oczywiście to samo zadziała, jeśli użyjesz stylu blokowego, jeśli instrukcja i ocenisz $? tak jak na początku:

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

Chociaż jesteśmy przy tym, jeśli chodzi o nc, zależy to od tego, jaki masz smak nc (gnu ncat vs nmap-ncat). Gnu będzie miał przełącznik -z:

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

podczas gdy drugi nie chce i będziesz musiał poprowadzić pustą linię do swojego nc, aby się nie utknąć:

echo | nc 10.0.0.1 23
# (evaluate $? here)

1

uruchom nc -z 192.168.10.5 23w wierszu polecenia lub utwórz skrypt bash, aby uruchomić to polecenie.

Zwraca poniższą instrukcję, jeśli połączenie się powiodło.

Połączenie z portem 192.168.10.5 23 [tcp / *] powiodło się!

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.