2013-07-19 16:54:10 +0000 2013-07-19 16:54:10 +0000
369
369

Тестирование того, доступен ли порт на удаленной системе (без telnet)

В старые времена мы использовали telnet для проверки того, открыт ли порт на удаленном хосте: telnet hostname port будет пытаться подключиться к любому порту на любом хосте и даст вам доступ к сырому TCP-потоку.

В наши дни системы, на которых я работаю, не имеют установленной telnet (из соображений безопасности), и все исходящие соединения со всеми хостами блокируются по умолчанию. Со временем легко потерять информацию о том, какие порты открыты на какие хосты.

Есть ли другой способ проверить, открыт ли порт на удаленной системе - используя Linux-систему с ограниченным количеством установленных пакетов, а telnet недоступен?

Ответы (13)

418
418
418
2013-12-03 21:34:41 +0000

Мило и многословно! Из руководства страниц. Один порт:

nc -zv 127.0.0.1 80

Несколько портов:

nc -zv 127.0.0.1 22 80 8080

Диапазон портов:

nc -zv 127.0.0.1 20-30
297
297
297
2013-07-22 10:37:11 +0000

В течение некоторого времени Бэш получил доступ к портам TCP и UDP . Из man-страницы:

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

Так что вы можете использовать нечто подобное:

xenon-lornix:~> cat < /dev/tcp/127.0.0.1/22
SSH-2.0-OpenSSH_6.2p2 Debian-6
^C pressed here

Taa Daa!

104
104
104
2013-07-19 18:07:26 +0000

Netcat является полезным инструментом:

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

Будет выводить 0, если порт 123 открыт, и 1, если он закрыт.

61
61
61
2014-09-02 17:59:36 +0000

Самый простой метод, без использования другого инструмента, такого как socat, описан выше в ответе @lornix. Это просто для того, чтобы добавить реальный пример того, как можно использовать psuedo-device /dev/tcp/... в Bash, если вы хотите, скажем, проверить, имеет ли другой сервер заданный порт, доступный через командную строку.

Примеры

Скажите, что у меня в сети есть хост с именем 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

Причина, по которой вы хотите обернуть echo > /dev/... в круглые скобки, (echo > /dev/...) заключается в том, что если вы этого не сделаете, то при тестировании соединений, которые не работают, вы получите такие типы сообщений.

Они не могут быть просто перенаправлены на /dev/null, так как они приходят от попытки переписать данные на устройство /dev/tcp. Поэтому мы перехватываем весь вывод внутри подкоманды, т.е. (...cmds...) и перенаправляем вывод подкоманды.

48
48
48
2013-07-19 17:05:30 +0000

Я обнаружил, что curl может выполнить работу подобно telnet, и curl даже скажет вам, какой протокол ожидает слушатель.

Конструируйте HTTP URI из имени хоста и порта в качестве первого аргумента к curl. Если curl может подключиться, он сообщит о несоответствии протокола и выйдет (если слушатель не является веб-службой). Если curl не может подключиться, то произойдет тайм-аут.

Например, порт 5672 на хосте 10.0.0.99 либо закрыт, либо заблокирован брандмауэром:

$ curl http://10.0.0.99:5672
curl: (7) couldn't connect to host

Тем не менее, из другой системы, порт 5672 на хосте 10. Доступ к версии 0.0.99 возможен, и, кажется, что на нем запущен слушатель AMQP.

$ curl http://10.0.0.99:5672
curl: (56) Failure when receiving data from the peer
AMQP

Важно различать разные сообщения: первый сбой был вызван тем, что curl не смог подключиться к порту. Второй сбой - это тест на успешность, хотя curl ожидала, что будет работать HTTP-прослушиватель, а не AMQP-прослушиватель.

13
13
13
2015-06-02 06:27:59 +0000
[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!

Надеюсь оно решает вашу проблему :)

11
11
11
2016-03-16 11:21:40 +0000

Вот один лайнер:

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

с использованием синтаксиса Бэша, объясненного в @lornix response .

Для получения дополнительной информации, проверьте: Расширенное руководство по написанию Bash-Scripting Guide: Chapter 29. /dev and /proc .

8
8
8
2017-05-31 08:45:09 +0000

Я целый день боролся, потому что ни один из этих ответов, казалось, не подошел мне. Проблема в том, что последняя версия nc больше не имеет флага -z, в то время как прямой доступ по TCP (согласно @lornix и @slm) не работает, когда хост недоступен. В конце концов, я нашел эту страницу , где я нашел не один, а two рабочих примеров:

  1. nc -w1 127.0.0.1 22 </dev/null

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

Тогда просто используйте && и/или || (или даже $?) для извлечения результата. Надеюсь, кто-нибудь найдет эту информацию полезной.

6
6
6
2018-08-10 12:20:04 +0000

Объединив ответы из @kenorb и @Azukikuru можно протестировать порт open/closed/firewalled.

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

Другой подход с curl для достижения любого порта

curl telnet://127.0.0.1:22
4
4
4
2019-02-12 20:21:11 +0000

Вот функция, которая выберет один из методов в зависимости от того, что установлено в вашей системе:

# Check_port <address> <port> 
check_port() {
if ["$(which nc)" != ""]; then 
    tool=nc
elif ["$(which curl)" != ""]; then
     tool=curl
elif ["$(which telnet)" != ""]; then
     tool=telnet
elif [-e /dev/tcp]; then
      if ["$(which gtimeout)" != ""]; then  
       tool=gtimeout
      elif ["$(which timeout)" != ""]; then  
       tool=timeout
      else
       tool=devtcp
      fi
fi
echo "Using $tool to test access to $1:$2"
case $tool in
nc) nc -v -G 5 -z -w2 $1 $2 ;;
curl) curl --connect-timeout 10 http://$1:$2 ;;
telnet) telnet $1 $2 ;;
gtimeout) gtimeout 1 bash -c "</dev/tcp/${1}/${2} && echo Port is open || echo Port is closed" || echo Connection timeout ;;
timeout) timeout 1 bash -c "</dev/tcp/${1}/${2} && echo Port is open || echo Port is closed" || echo Connection timeout ;;
devtcp) </dev/tcp/${1}/${2} && echo Port is open || echo Port is closed ;;
*) echo "no tools available to test $1 port $2";;
esac

}
export check_port
```.
2
2
2
2013-07-19 17:01:16 +0000

Его не должно быть на коробке, но попробуйте с nmap.

1
1
1
2019-08-07 23:17:13 +0000

для справки, расширяя на @peperunas ответ:

способ использования nmap для проверки, является:

nmap -p 22 127.0.0.1

(пример выше использует localhost для демонстрационных целей)

0
0
0
2018-10-26 13:49:54 +0000

Если вам нужно протестировать больше, чем на системе, вы можете использовать наш тестовый инструмент dda-serverspec https://github.com/DomainDrivenArchitecture/dda-serverspec-crate ) для таких задач. Вы можете определить ваше ожидание

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

и протестировать это ожидание либо на локальном хосте, либо на удаленных хостах (подключитесь по ssh). Для удаленных тестов вы должны определить цели:

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

Вы можете запустить тест с java -jar dda-serverspec.jar --targets targets.edn serverspec.edn

Под капотом мы используем netcat в качестве proprosed выше …

Похожие вопросы

6
10
3
5
36