簡體   English   中英

在 Linux 上有效測試端口是否打開?

[英]Efficiently test if a port is open on Linux?

從 bash 腳本如何快速找出端口445是否在服務器上打開/偵聽。

我嘗試了幾個選項,但我想要一些快速的東西:
1. lsof -i :445 (需要幾秒鍾)
2. netstat -an |grep 445 |grep LISTEN (需要幾秒鍾)
3. telnet (不返回)
4. nmap , netcat在服務器上不可用

很高興知道一種不先枚舉然后不枚舉的方法。

我最近發現的一個驚喜是 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 是標准輸入、標准輸出和標准錯誤。 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

要確定是否有人在偵聽,請嘗試通過回送進行連接。 如果失敗,則端口已關閉或不允許我們訪問。 之后,關閉連接。

針對您的用例修改此設置,例如發送電子郵件、失敗時退出腳本或啟動所需的服務。

這里有一個非常簡短的“快速答案”: 如何測試是否從 Shell 腳本打開了遠程 TCP 端口?

nc -z <host> <port>; echo $?

我將它與 127.0.0.1 一起用作“遠程”地址。

如果端口打開則返回“0”,如果端口關閉則返回“1”

例如

nc -z 127.0.0.1 80; echo $?

-z指定 nc 應該只掃描監聽守護進程,而不向它們發送任何數據。 將此選項與 -l 選項結合使用是錯誤的。

您可以通過這種方式使用 netstat 以獲得更快的結果:

在 Linux 上:

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

在 Mac 上:

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

這將輸出偵聽端口的進程列表(在本例中為 445),或者如果端口空閑則不輸出任何內容。

您可以為此使用 netcat。

nc ip port < /dev/null

連接到服務器,直接再次關閉連接。 如果 netcat 無法連接,它會返回一個非零退出代碼。 退出代碼存儲在變量 $? 中。 舉個例子,

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

當且僅當 netcat 可以成功連接到端口時,才會返回 0。

基於 Spencer Rathbun 的回答,使用 bash:

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

它們列在 /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 等將其分開作為溫和讀者的練習......

ss -tl4 '( sport = :22 )'

2ms夠快嗎?

添加冒號,這適用於 Linux

這是一種適用於 Mac 和 Linux 的方法:

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

其中 8000 是端口號。 如果端口空閑,它將啟動一個您可以輕松關閉的服務器。 如果不是,它會拋出一個錯誤:

nc: Address already in use

我想檢查我們的一台 linux 測試服務器上是否打開了一個端口。 通過嘗試使用 telnet 從我的開發機器連接到測試服務器,我能夠做到這一點。 在您的開發機器上嘗試運行:

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

在這個例子中,我想檢查主機test2.host.com上的端口8080是否打開

tcping是一個很好的工具,開銷非常低。它還具有超時參數以使其更快:

[root@centos_f831dfb3 ~]# tcping 10.86.151.175 22 -t 1
10.86.151.175 port 22 open.
[root@centos_f831dfb3 ~]# tcping 10.86.150.194 22 -t 1
10.86.150.194 port 22 user timeout.
[root@centos_f831dfb3 ~]# tcping 1.1.1.1 22 -t 1
1.1.1.1 port 22 closed.

您也可以使用 netcat 命令

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

要么

nc -zv [ip] [port]

-z - 將 nc 設置為簡單地掃描監聽守護進程,而不實際向它們發送任何數據。
-v – 啟用詳細模式。

nmap是正確的工具。 只需使用nmap example.com -p 80

您可以從本地或遠程服務器使用它。 它還可以幫助您確定防火牆是否阻止訪問。

如果您使用的是 iptables,請嘗試:

iptables -nL

要么

iptables -nL | grep 445

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM