Эффективно проверить, открыт ли порт в Linux? - PullRequest
188 голосов
/ 08 марта 2012

Из скрипта bash, как быстро узнать, открыт ли / прослушивается порт 445 на сервере.

Я попробовал несколько вариантов, но хочу что-то быстрое:
1. lsof -i :445 (занимает секунды)
2. netstat -an |grep 445 |grep LISTEN (занимает секунды)
3. telnet (не возвращается)
4. nmap, netcat недоступно на сервере

Было бы неплохо узнать способ, который не перечисляет сначала, а greps после этого.

Ответы [ 14 ]

151 голосов
/ 08 марта 2012

Недавно я обнаружил сюрприз, что Bash изначально поддерживает tcp соединения в качестве файловых дескрипторов .Чтобы использовать:

exec 6<>/dev/tcp/ip.addr.of.server/445
echo -e "GET / HTTP/1.0\n" >&6
cat <&6

Я использую 6 в качестве дескриптора файла, потому что 0,1,2 это stdin, stdout и stderr.5 иногда используется Bash для дочерних процессов , поэтому 3,4,6,7,8 и 9 должны быть безопасными.

Согласно приведенному ниже комментарию, для проверки прослушивания локальный сервер в сценарии:

exec 6<>/dev/tcp/127.0.0.1/445 || echo "No one is listening!"
exec 6>&- # close output connection
exec 6<&- # close input connection

Чтобы определить, слушает ли кто-то, попытайтесь подключиться с помощью обратной связи.Если это не удается, то порт закрыт или нам не разрешен доступ.После этого закройте соединение.

Измените это для своего варианта использования, такого как отправка электронного письма, выход из сценария при сбое или запуск требуемой службы.

103 голосов
89 голосов
/ 08 марта 2012

Вы можете использовать netstat таким образом, чтобы получить более быстрые результаты:

В Linux:

netstat -lnt | awk '$6 == "LISTEN" && $4 ~ /\.445$/'

на Mac:

netstat -anp tcp | awk '$6 == "LISTEN" && $4 ~ /\.445$/'

Это выведет список процессов, прослушивающих порт (445 в этом примере), или ничего не выведет, если порт свободен.

36 голосов
/ 11 сентября 2014

Для этого вы можете использовать netcat.

nc ip port < /dev/null

подключается к серверу и снова напрямую закрывает соединение.Если netcat не может подключиться, он возвращает ненулевой код завершения.Код выхода хранится в переменной $ ?.Например,

nc ip port < /dev/null; echo $?

вернет 0 тогда и только тогда, когда netcat сможет успешно подключиться к порту.

15 голосов
/ 08 марта 2012

они перечислены в /proc/net/tcp.

это второй столбец, после ":", в шестнадцатеричном:

> cat /proc/net/tcp
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode                                                     
   0: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 10863 1 ffff88020c785400 99 0 0 10 -1                     
   1: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 7983 1 ffff88020eb7b3c0 99 0 0 10 -1                      
   2: 0500010A:948F 0900010A:2328 01 00000000:00000000 02:00000576 00000000  1000        0 10562454 2 ffff88010040f7c0 22 3 30 5 3                   
   3: 0500010A:E077 5F2F7D4A:0050 01 00000000:00000000 02:00000176 00000000  1000        0 10701021 2 ffff880100474080 41 3 22 10 -1                 
   4: 0500010A:8773 16EC97D1:0050 01 00000000:00000000 02:00000BDC 00000000  1000        0 10700849 2 ffff880104335440 57 3 18 10 -1                 
   5: 0500010A:8772 16EC97D1:0050 01 00000000:00000000 02:00000BF5 00000000  1000        0 10698952 2 ffff88010040e440 46 3 0 10 -1                  
   6: 0500010A:DD2C 0900010A:0016 01 00000000:00000000 02:0006E764 00000000  1000        0 9562907 2 ffff880104334740 22 3 30 5 4                    
   7: 0500010A:AAA4 6A717D4A:0050 08 00000000:00000001 02:00000929 00000000  1000        0 10696677 2 ffff880106cc77c0 45 3 0 10 -1  

, так что я думаю, один из них:50 в третьем столбце должен быть stackoverflow: o)

для получения более подробной информации обратитесь к man 5 proc.и выбор этого с помощью sed и т. д. оставлен как упражнение для нежного читателя ...

14 голосов
/ 12 апреля 2017

На основании ответа Спенсера Рэтбуна, используя bash:

true &>/dev/null </dev/tcp/127.0.0.1/$PORT && echo open || echo closed
11 голосов
/ 23 февраля 2014
ss -tl4 '( sport = :22 )'

2 мс достаточно быстро?

Добавьте двоеточие, и это работает в Linux

6 голосов
/ 11 марта 2014

Вот тот, который работает как для Mac, так и для Linux:

netstat -aln | awk '$6 == "LISTEN" && $4 ~ "[\\.\:]445$"'
5 голосов
/ 03 октября 2016

Я хотел проверить, открыт ли порт на одном из наших тестовых серверов linux. Я смог сделать это, пытаясь соединиться с telnet с моей машины разработчика на тестовый сервер. На вашей машине dev попытайтесь запустить:

$ telnet test2.host.com 8080
Trying 05.066.137.184...
Connected to test2.host.com

В этом примере я хочу проверить, открыт ли порт 8080 на хосте test2.host.com

5 голосов
/ 17 декабря 2014
nc -l 8000

Где 8000 - номер порта.Если порт свободен, он запустит сервер, который вы можете легко закрыть.Если это не так, он выдаст ошибку:

nc: Address already in use
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...