socat
http://www.dest-unreach.org/socat/。
提示:如下翻译来自 man 1 socat,未完待续……
概述
socat 是一个命令行工具,用以建立一个双向字节流交换数据。该字节流又可以被构造成不同地址类型,大量的地址选项也同样可以被作用于该流,因此socat非常强大。
filan 是一个打印文件描述符的工具,已经被重构用以调试socat,当然,也可以另做它用。
procan 是一个打印进程信息的工具,同样被重构用以调试socat。
socat 实例包含如下生命周期。
init 阶段解析命令参数,初始化日志打印;
open阶段打开第一个地址并且转发到第二个地址字节流,此阶段可能会阻塞,因此类似socks的复杂地址选项,需要在连接请求或认证对话框完成后才会开始下一阶段。
transfer阶段通过select 参数观察源地址流的读写操作,当可读或者可写时,socat完成到目的流数据转发。
当任意一方流eof,closing阶段开始,socat 主动发送eof操作到对等需要关闭的另外一方尝试优雅的关闭它的写操作的字节流,在运行的时间范围内,socat也可能会继续传输数据到另外一个方向,直到所有的通道被关闭。
I. 地址规范
命令的地址参数为用户给socat 建立字节流的必要信息。
一个地址规范通常包含一个地址类型的关键词,零或者多个地址参数通过":"间隔,零或者多个地址选项通过","间隔。
关键词指定地址类型(tcp4、open、exec),而对于一些关键字存在同义词(例如 “-”代表stdio,tcp默认为tcp4),这里的地址类型关键字不区分大小写。对于一些特殊地址类型,关键字可能会被省略,
地址关键字
socket-connect:<domain>:<protocol>:<remote-address>
tcp:<host>:<port>
通过tcp/ip 4或者6,连接由host、port指定的地址。由地址标准决定ip版本,域名解析。
选项组:FD,SOCKET,IP4,IP6,TCP,RETRY
有用的选项:crnl, bind, pf, connect-timeout, tos, mtudiscover, mss, nodelay, nonblock, sourceport, retry, readbytes
tcp-listen:<port>
监听由port 指定的端口,并接收(accept)TCP/IP连接,ip版本为4或者地址选项pf指定,对应选项(socat -4、-6),也可通过环境变量CAT_DEFAULT_LISTEN_IP配置,注意,打开该地址后通常会阻塞进程,直到一个客户端连接。
选项组:FD,SOCKET,LISTEN,CHILD,RANGE,IP4,IP6,TCP,RETRY;
有用的选项: crnl, fork, bind, range, tcpwrap, pf, max-children, backlog, mss, su, reuseaddr, retry, cool-write;
unix-connect:<fille_name>
指定地址file_name的unix domain socket,如果未指定地址,或者该地址不是一个unix 域亦或者或者没有进程绑定此地址,则报错。
选项组: FD,SOCKET,NAMED,RETRY,UNIX。
有用的选项:bind。
unix-listen:<fille_name>
监听file_name指定地址的unix socket,并且接受(accept)新的连接,同样地,如果指定了地址但不是一个unix domain地址则报错。当然尽管指定了一个unix 域地址,也有可能会因为某个原因(比如前一个连接未unlink)导致绑定(bind)失败。注意,打开该地址后通常会阻塞进程,直到一个客户端连接。从socat 1.4.3 开始,关闭socket后会自动删除对应的文件系统条目(同样地,建议查看unlink-close选项)。
选项组:FD,SOCKET,NAMED,LISTEN,CHILD,RETRY,UNIX;
有用的选项:UNIX-CONNECT, UNIX-RECVFROM, UNIX-RECV, TCP-LISTEN;
unix-sendto:<file_name>
同file_name指定 unix 域socket通信,从对等的socket发送和接收包。注意可能需要绑定本地socket到一个地址(例如,/tmp/sock1该地址需要不存在)。
地址选项
fork
在建立一个连接后,通过子进程通道完成数据处理,让其同父进程保持尝试产生更多连接,不管是监听还是循环接收。
OPENSSL-CONNECT
和 OPENSSL-LISTEN
reuseaddr
运行其他sockets绑定(bind)某个地址,即使该地址(比如本地的某个端口)已经被socat使用。
type
socket type,详细参考 man socket。
name | Linux | FreeBSD | NetBSD | OpenBSD | Solaris | AIX | Cygwin | Mac OS X | HP-UX |
---|---|---|---|---|---|---|---|---|---|
PF_LOCAL | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
PF_INET | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
PF_APPLETALK | 5 | 16 | 16 | 16 | 16 | 16 | 16 | 16 | 16 |
PF_INET6 | 10 | 28 | 24 | 24 | 26 | 24 | - | 30 | 22 |
PF_PACKET | 17 | - | - | - | - | - | - | - | - |
SOCK_STREAM | 1 | 1 | 1 | 1 | 2 | 1 | 1 | 1 | 1 |
SOCK_DGRAM | 2 | 2 | 2 | 2 | 1 | 2 | 2 | 2 | 2 |
SOCK_RAW | 3 | 3 | 3 | 3 | 4 | 3 | 3 | 3 | 3 |
SOCK_SEQPACKET | 5 | 5 | 5 | 5 | 6 | 5 | 5 | 5 | 5 |
SOCK_DCCP | (6) | - | - | - | - | - | - | - | - |
SOCK_PACKET | 10 | - | - | - | - | - | - | - | - |
IPPROTO_IP | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
IPPROTO_TCP | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 |
IPPROTO_UDP | 17 | 17 | 17 | 17 | 17 | 17 | 17 | 17 | 17 |
IPPROTO_DCCP | 33 | - | - | - | - | - | - | - | - |
IPPROTO_SCTP | 132 | 132 | - | - | 132 | 132 | - | - | - |
IPPROTO_RAW | 255 | 255 | 255 | 255 | 255 | - | - | - | - |
SOL_SOCKET | 1 | 65535 | 65535 | 65535 | 65535 | 65535 | 65535 | 65535 | 65535 |
SOL_IP | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
SOL_TCP | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 |
SOL_UDP | 17 | - | - | - | - | - | 17 | - | - |
SOL_IPV6 | 41 | 41 | 41 | 41 | 41 | 41 | - | 41 | 41 |
SOL_PACKET | 263 | - | - | - | - | - | - | - | - |
SOL_DCCP | 269 | - | - | - | - | - | - | - | - |
II. 样例
远程访问目标机器的unix-domain socket
调试需求,这里把目标机器的unix domain socket(/tmp/agent.socket)通过socat 映射到调试的主机上面。
# netstat -lp
Active UNIX domain sockets (only servers)
Proto RefCnt Flags Type State I-Node PID/Program name Path
unix 2 [ ACC ] SEQPACKET LISTENING 15143198 13519/agent /tmp/agent.socket
目标机器连接改unix socket,并且通过tcp socket 在局域网监听
socat unix-connect:/tmp/agent.socket,type=5 tcp-listen:54328
调试主机从局域网连接如上端口,然后存放在本地同名的unix socket
socat unix-listen:/tmp/agent.socket,type=5 tcp-connect:192.168.28.153:54328
提示:如上的socket type 参考socket type章节,type=5对应
SOCK_SEQPACKET
,如果type不一致socat会提示错误的协议类型(the wrong protocol type)。注意:如上通过tcp(默认 SOCK_STREAM )按照字节流转发unix socket(SEQPACKET)有序包会tcp 这端会出现粘包,所以更改成了udp(
SOCK_DGRAM)转发。socat unix-connect:/tmp/agent.socket,type=5 udp-listen:54328 socat unix-listen:/tmp/agent.socket,type=5 udp-connect:192.168.28.153:54328
监听unix socket
ln real.sock real.sock~
socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CONNECT:real.sock~
socat UNIX-LISTEN:fake.sock,fork TCP-CONNECT:127.0.0.1:6000
mv fake.sock real.sock
重定向串口
重定向到终端
socat /dev/ttyUSB0,b115200,raw,echo=0,crnl -
重定向到tcp server
socat TCP-LISTEN:2002 PTY,link=ttyV2,raw,crnl
还不快抢沙发