Проверьте, активен ли порт telnet в сценарии оболочки


10

Я пытаюсь создать скрипт для проверки возможности входа через telnet. Я не хочу, чтобы действительно войти в систему; следовательно, ожидать не нужно. Я просто хочу посмотреть, смогу ли я получить приглашение для входа в систему. Это делается из системы Linux, поэтому я пытался использовать nc:

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

Проблема в том, что это вызывает блокировку моей консоли. Кажется, что на -wсамом деле не разрывается соединение.

Я также пытался использовать telnet, но я не могу разорвать соединение внутри скрипта. Попытка

\echo "\035" | telnet 192.168.10.5

перерывы, прежде чем я получу приглашение на вход.


Возможный дубликат superuser.com/questions/621870/...
vschum

Ответы:


14

Bash предоставляет псевдо-устройства, с которыми вы, вероятно, знакомы, например /dev/null. Однако есть и другие устройства, такие как /dev/tcpи /dev/udpдля тестирования сетевых подключений, которые вы также можете использовать в скриптах Bash.

выдержка из справочной страницы Баша

Bash обрабатывает несколько имен файлов, особенно когда они используются в перенаправлениях, как описано в следующей таблице:

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

пример

Вот я тестирую соединение с хостом в моем домене с именем skinner и проверяю, могу ли я подключиться к его порту 22.

ПРИМЕЧАНИЕ. Порт 22 предназначен для SSH, для telnet используется порт 23.

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

Отлично, так что давайте попробуем не порт:

$ 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

Ну, это работает, но это ужасно уродливый вывод. Не беспокоиться. Вы можете запустить echo > /dev/tcp/...в подоболочке и перенаправить весь вывод, чтобы /dev/nullнемного его очистить. Вот шаблон, который вы можете использовать в своих сценариях оболочки:

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

Если вы специально хотите протестировать telnet, то по умолчанию он работает на порту 23, поэтому там, где slm использовал 22 и 223, используйте 23.
Warwick

@Warwick - спасибо, я добавил это в качестве примечания в разделе примеров.
СЛМ

@Sim спасибо за комментарий. Я видел это раньше, но я не смог заставить его работать с этим. Моя проблема в том, что мне нужно иметь возможность grep или проверить приглашение на вход в систему. В этом случае консоль заблокирована и нет запроса на вход. # 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 дает мне приглашение на вход в систему, но я не могу выйти из него.
rleon

1
вау .. много перенаправления там. # cat afile ^] после запуска это просто повторяет разрыв afile. Все еще играю с этим, но я чувствую, что почти там.
rleon

7

Вы на правильном пути, используя nc, но если вы действительно хотите просто проверить, можете ли вы установить соединение, используйте переключатель 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

это работает не на всех системах, у моего nc нет флага -z
Shapeshifter

Интересно. Какая версия ncэто?
DopeGhoti

Я нахожусь на CentOS 7, и nc был заменен на nmap-ncat, у которого нет этой опции :(
Shapeshifter

Если я правильно помню, пакет, который вы хотите в CentOS, просто nc.
DopeGhoti

nc - это nmap-ncat в сентосах 7
Shapeshifter

2

Я знаю, что ответ немного запоздал, но я искал, как это сделать, и использование nc не было вариантом по соображениям безопасности, так что вот оно, если оно может кому-то помочь.

Чего не хватало в вашем первоначальном эхо, так это ключа -e:

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

И новая строка + команда quit для выхода из telnet после отключения. В качестве таких:

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

Очевидно, то же самое сработает, если вы используете блочный стиль if и вычисляете $? как вы делали изначально:

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

Что касается nc, то это зависит от того, какой у вас nc (gnu ncat против nmap-ncat). У GNU будет ключ -z:

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

в то время как другой не будет, и вам придется передать пустую строку вашему nc, чтобы не застрять:

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

1

запустить nc -z 192.168.10.5 23в командной строке или создать сценарий bash для запуска этой команды.

Он возвращает оператор ниже, если соединение установлено успешно.

Подключение к 232 порту 192.168.10.5 [tcp / *] успешно завершено!

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.