介紹如何在 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