端口转发是一个你不常会遇到的情况,但是一旦他来了,手头的工具要么太重,要么不趁手。举个简单的例子,你可能需要外网流量转发到本地内网,也有可能需要把IPv6流量转移到外网的IPv4,甚至可能需要UDP转发,面对这多样的情况,iptables的性能上不去,配置太麻烦,后期维护不方便等等问题很容易成为阻碍。
面对这样的情况,我们需要socat来解决这一切。
介绍&安装
netcat是网络领域非常经典的软件,用来对网络连线TCP或者UDP进行读写。socat是netcat较复杂的姊妹程式。它比起netcat更大更复杂,并且有更多的选项得在给定作业前先设定。事实上socat的功能非常强大,能做到的不仅仅是端口转发这样简单的事情。安装没什么好说的
apt-get install socat实践
要注意,socat只是一个命令行工具,要守护运行你可能需要nohup或者supervisor,这里着重介绍socat的参数与功能。socat的上手难度并不高,你只需要记住这个固定的语法,就可以把参数和变量套进去,即
socat [options] <address> <address>不要把address仅仅想成网络地址,由于Linux的万物皆文件,这里的address也可以是某个pipe或者某个文件。一般来说,address有这么几个常用的类型-TCP/UDP:建立一个TCP/UDP连接作为数据流-TCP-LISTEN/UDP-LISTEN:监听一个端口-文件:任意路径的文件在地址后面可以加一些选项,这个我们放在后面详细说。对于端口转发,我们需要监听一个地址,同时把监听到的数据发送给另外一个地址,这里就有了两个address类型,举例来说,就好比这样
socat TCP-LISTEN:8080 TCP:192.168.1.2:8080这样我们就实现了监听本地8080端口,并将该端口的数据转发到192.168.1.2的对应端口上,socat会自己帮我们把反向的链路建立,所以不需要类似iptables的多余操作。正如前面所说,socat是一个命令行程序,这就意味着他不能在同一个终端下建立多个进程,这对于高并发场景来说意味着多条TCP抢socat,延迟也会因此有着不可忍受的波动,所以我们使用reuseaddr参数绑定一个本地端口,同时使用fork参数将socat转变为多链接模式,即当一个链接建立后,自动复制一个同样的端口监听,这样就能有效提高高并发场景下的性能表现。但是在实际的生产场景中,为了避免root用户执行某些程序,我们还要给socat指定一个运行权限。所以,最终是这个样子的
socatTCP-LISTEN:8080,reuseaddr,fork,su=nobodyTCP:192.168.1.2:8080这里你可以把TCP换成UDP或者简单的变为TCP6/UDP6,可以指定对应的协议进行监听和转发,或者可以只用TCP或者UDP,在option中使用-4或-6参数来指定偏好的协议。特别的,对于UDP这样的链接来说,最好在命令中加入-T参数,尽快关闭不活跃的链接。
socat -T 120 UDP-LISTEN:8080,reuseaddr,fork,su=nobodyUDP:192.168.1.2:8080这样,在UDP链路不活跃120s之后,这个fork出来的子进程就会被关闭,但是主进程仍然保留。##进阶由于address的变化性,我们甚至可以把socat作为WebServer或者一个文件服务器,
socat -d -d /dev/sda1,rawer,nonblock,ignoreeof,cr,echo=0TCP-LISTEN:55555,reuseraddr这样,一个监听在55555端口上的文件服务器就有了,其中--d-d:输出调试信息-rawer:直接读取/写入,这样可以提升速度。-nonblock:使用non-blockIO模式防止拥塞-ignoreeof:忽略EOF,这让这台文件服务器一直在线,而不是每传输完一个文件后就关闭-cr:换行符转换-ehco=0:关闭echo(根据rawer的要求)总之,你可以使用做端口转发,做文件服务器,做任何有关两点间通信的任何事情。