Эффективно проверить, открыт ли порт в Linux?

Из bash script как я могу быстро узнать, открыт ли /< > на порту порт 445.

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

Хорошо бы узнать, как это сделать, и не перечислять сначала и greps после этого.

Ответ 1

Недавно я узнал, что 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 должны быть безопасными.

В соответствии с приведенным ниже комментарием, чтобы проверить прослушивание на локальном сервере в script:

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

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

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

Ответ 3

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

В Linux:

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

На Mac:

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

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

Ответ 4

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

nc ip port < /dev/null

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

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

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

Ответ 5

они перечислены в /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 и т.д. оставлен в качестве упражнения для нежного читателя...

Ответ 6

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

true &>/dev/null </dev/tcp/127.0.0.1/$PORT && echo open || echo closed

Ответ 7

ss -tl4 '( sport = :22 )'

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

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

Ответ 8

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

netstat -aln | awk '$6 == "LISTEN" && $4 ~ "[\\.\:]445$"'

Ответ 9

nc -l 8000

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

nc: Address already in use

Ответ 10

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

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

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

Ответ 11

tcping - отличный инструмент с очень низкими издержками. У него также есть аргумент времени ожидания, чтобы ускорить его:

[[email protected]_f831dfb3 ~]# tcping 10.86.151.175 22 -t 1
10.86.151.175 port 22 open.
[[email protected]_f831dfb3 ~]# tcping 10.86.150.194 22 -t 1
10.86.150.194 port 22 user timeout.
[[email protected]_f831dfb3 ~]# tcping 1.1.1.1 22 -t 1
1.1.1.1 port 22 closed.

Ответ 12

Вы также можете использовать команду netcat

[location of netcat]/netcat -zv [ip] [port]

или же

nc -zv [ip] [port]

-z - устанавливает nc для простого сканирования на предмет прослушивания демонов, без фактической отправки им данных.
-v - включает подробный режим.

Ответ 13

nmap - правильный инструмент. Просто используйте nmap example.com -p 80

Вы можете использовать его с локального или удаленного сервера. Это также помогает определить, блокирует ли брандмауэр доступ.

Ответ 14

Если вы используете iptables, попробуйте:

iptables -nL

или

iptables -nL | grep 445