介紹如何在 Linux 上使用 socat 雙向資料流轉接工具,串接兩個資料管道。
socat 指令是一個多功能的雙向資料轉接工具,可連接 Linux 系統上任意兩個資料管道,支援檔案(files)、管線(pipes)、設備(devices)、網路 sockets 與各種應用程式等,可以說是進階版的 netcat 工具。
socat若在 Ubuntu Linux 中,可用 apt 安裝 socat 工具:
# 安裝 socat 套件
sudo apt install socat
socat 基本語法socat 指令的基本語法如下:
socat [選項] 位置一 位置二
執行 socat 指令之後,會將 位置一 與 位置二 以類似管線的方式串接起來,讓資料流可以雙向傳遞。
位置一 與 位置二 的格式是以一個協定名稱開頭,接著以冒號分隔主要參數,接著與逗號分隔細部選項:
協定:參數一:參數二,選項一,選項二
例如一個 TCP 網路的 80 連接埠就會寫成:TCP4:www.example.com:80。
以下是一些 socat 指令的基本使用範例。
telnet將目前終端機的標準輸出入(stdio)連接遠端伺服器的 80 連接埠:
# 連接標準輸出入(stdio)與遠端伺服器的 80 連接埠 socat - TCP:www.example.com:80
這行指令的作用就跟使用 telnet 連接至 www.example.com 的 80 連接埠很類似。
將連線至 8080 連接埠的連線轉接至遠端 80 連接埠:
# 將 8080 連接埠重新導向至遠端 80 連接埠(單一連線) socat TCP-LISTEN:8080 TCP:192.168.1.123:80 # 將 8080 連接埠重新導向至遠端 80 連接埠(同時多條連線) socat TCP-LISTEN:8080,fork,reuseaddr TCP:192.168.1.123:80 # 將 8080 連接埠重新導向至遠端 80 連接埠(以 nobody 權限 fork 行程) socat TCP-LISTEN:8080,fork,reuseaddr,su=nobody TCP:192.168.1.123:80
在這個範例中,當 client 連線至伺服器的 3334 連接埠時,會建立新的子行程(fork 選項),所有傳送至伺服器的資料都會以附加的方式寫入 /tmp/archive.log 檔案中(append 選項),若該檔案不存在的話,socat 會自動建立檔案(creat 選項)。
# 從網路接收資料,儲存至檔案 socat -u TCP4-LISTEN:3334,reuseaddr,fork OPEN:/tmp/archive.log,creat,append
以下是將連線至 3307 連接埠的網路連線導向至 /var/lib/mysql/mysql.sock 這個 UNIX socket:
# 將 3307 連接埠重新導向至 /var/lib/mysql/mysql.sock 這個 UNIX Socket socat TCP-LISTEN:3307,reuseaddr,fork UNIX-CONNECT:/var/lib/mysql/mysql.sock
這個例子是使用 socat 自動以密碼認證方式,連線至 SSH 伺服器並執行 ls 指令:
# 自動連線至 SSH 伺服器並執行指令 (sleep 5; echo PASSWORD; sleep 5; echo ls; sleep 1) |\ socat - EXEC:'ssh USER@SERVER',pty,setsid,ctty
這是簡易版的 HTTP/1.0 伺服器,可做為程式開發測試或除錯用:
# 簡易 HTTP/1.0 伺服器 socat TCP-LISTEN:8000,crlf SYSTEM:"echo HTTP/1.0 200; echo Content-Type\: text/plain; echo; cat"
以下是一個專門用於除錯用網頁伺服器:
# 除錯用網頁伺服器 socat -T 1 -d -d TCP-LISTEN:8000,reuseaddr,fork,crlf system:"echo -e \"\\\"HTTP/1.0 200 OK\\\nDocumentType: text/html\\\n\\\n<html>date: \$\(date\)<br>server:\$SOCAT_SOCKADDR:\$SOCAT_SOCKPORT<br>client: \$SOCAT_PEERADDR:\$SOCAT_PEERPORT\\\n<pre>\\\"\"; cat; echo -e \"\\\"\\\n</pre></html>\\\"\""
以 chroot 限制環境執行 /bin/sh:
# 以 chroot 限制環境執行 /bin/sh socat -d -d - EXEC:/bin/sh,chroot=/home/sandbox,su=sandbox,pty
透過網路存取 chroot 環境下的程式:
# 透過網路存取 chroot 環境下的程式 socat -lm -d -d TCP-LISTEN:5555,fork EXEC:/bin/myscript,chroot=/home/sandbox,su=sandbox,pty,stderr # 對應的 Client 指令 socat -,icanon=0,echo=0 tcp:target:5555; reset