這裡示範如何使用 bash 指令稿開啟 TCP/UDP 的 socket,進行各種網路診斷工作。
作為網管或是 Linux 系統管理者,使用 netcat
、wget
或 curl
這類的指令檢查遠端伺服器的網路服務應該算是基本技能,而且是時常會需要做的工作之一,但是如果遇到系統上沒有這類的工具可用時,我們就可以改用 bash shell 內建的一些功能來達到類似的效果。
/dev/tcp
與 /dev/udp
底下的設備檔來開啟 TCP 與 UDP 的網路連線,以下是一些開啟 TCP 與 UDP 連線的 bash 指令稿範例。
在 bash 中,我們可以使用以下這個語法來開啟 TCP 或是 UDP 的 socket:
# 開啟輸入與輸出的 socket exec FILE_DESCRIPTOR<>/dev/PROTOCOL/HOST/PORT
這個指令各部份的意義如下:
FILE_DESCRIPTOR
0
、1
與 2
分別代表系統的標準輸入(stdin
)、標準輸出(stdout
)與標準錯誤(stderr
),所以我們能使用的值是從 3
開始。<>
PROTOCOL
tcp
或是 udp
。HOST
PORT
若要關閉 socket,則執行:
# 關閉輸入 socket exec FILE_DESCRIPTOR<&- # 關閉輸出 socket exec FILE_DESCRIPTOR>&-
以下是一個實際的範例,這個範例會使用 bash 的只令開啟連線至 Google 網頁的 socket,下載網頁資料:
#!/bin/bash # 開啟連線至 Google 網頁的 socket exec 3<>/dev/tcp/www.google.com.tw/80 # 送出 HTTP 請求 echo -e "GET / HTTP/1.1\n\n" >&3 # 接收網頁內容,1 秒後自動停止接收資料 timeout 1 cat <&3 # 關閉輸入與輸出 socket exec 3<&- exec 3>&-
這個範例可分為四個部份:
www.google.com.tw
這台主機的 80
連接埠,將檔案代碼設定為 3
。echo
將 HTTP 請求的內容透過檔案代碼 3
送給 Google 網頁伺服器。3
讀取來自於 Google 網頁伺服器的網頁資料,用 cat
輸出。執行之後就會輸出 Google 網頁的原始 HTML 碼。
這是一個檢查 SSH 伺服器版本的範例,用法大同小異:
#!/bin/bash # 開啟 socket,連線至 192.168.0.1 的 SSH 伺服器 exec 3</dev/tcp/192.168.0.1/22 # 接收 SSH 的版本資訊,1 秒後自動停止接收資料 timeout 1 cat <&3 # 關閉輸入與輸出 socket exec 3<&- exec 3>&-
而上面這個檢查 SSH 版本的範例可以改寫為以下這個精簡的版本:
#!/bin/bash # 檢查 192.168.0.1 的 SSH 伺服器版本 timeout 1 cat </dev/tcp/192.168.0.1/22
這是一個透過 DAYTIME 協定,從伺服器取得目前時間的範例:
#!/bin/bash # 取的時間資訊 cat </dev/tcp/time.nist.gov/13
這個範例可以用來檢查網頁伺服器是否有正常運作,也就是測試伺服器的 80
連接埠是否可以正常連接:
#!/bin/bash # 伺服器資訊 HOST=www.mit.edu PORT=80 (echo >/dev/tcp/${HOST}/${PORT}) &>/dev/null if [ $? -eq 0 ]; then echo "伺服器連接成功。" else echo "伺服器連接失敗!" fi
這個範例可以用來掃描主機的連接埠(port),看看哪些服務有開啟:
#!/bin/bash # 要掃描的主機 HOST=192.168.0.1 # 要掃描的連接埠範圍 PORT_BEGIN=1 PORT_END=65535 for ((port=$PORT_BEGIN; port<=$PORT_END; port++)) do (echo >/dev/tcp/$HOST/$port) >/dev/null 2>&1 && echo "連接埠 $port 有開啟" done