今年撸的内部工具比较多,其中比较有用的我认为Socket Pipe绝对算一个。如果你有如下需求
- 需要做端口转发(udp or tcp)又懒得去配置复杂的iptables规则甚至还要用到nginx这种牛刀
- 需要把内网的某个监听端口反向穿透复杂的路由影射到一个固定的外网端口上(我知道有ngork,但是使用上限制较多而且还要收费不是吗)
- 你的茫茫多内网http服务需要在外网也能访问
那么我开发的这款小工具就再适合你不过了,它究竟有什么功能呢?我们先从最简单的说起
对了,忘了说如何安装了,这款工具是基于node.js的,所以你要先有它的运行环境,然后直接用npm安装即可
npm install -g socket-pipe
端口转发
这个理解起来很简单,就是把源地址的某个端口映射到当前运行 socket-pipe 这台机器的指定端口上,相当于做了一个透明的网络代理。比如我要把 192.168.1.100
的 80
端口映射到本地的 80
端口,那么直接运行
socket-pipe -l 127.0.0.1@80 -r 192.168.1.100@80 -t tcp
它同时支持 tcp 和 udp 协议,只要把 -t
参数改成 udp
即可
tcp 反向代理
这个在我们平时的开发需求中也很大,比如我们在内网已经开发好了一套网络服务,现在要放到公网上调试,以前你可能还要在公网上搭一套环境,然后运行程序,调试出错起来特别麻烦。而使用 socket-pipe 可以让公网的访问流量直接到达你的本机,并且不需要在路由器上做任何设置
首先你需要一个拥有公网ip的服务器(在这里比如 ip 地址是 123.123.123.123
),安装好 socket-pipe 以后,假如我们要求外网访问它的 8888
端口那么
socket-pipe -l 123.123.123.123@18888 -r 123.123.123.123@8888 -t tserver
注意这里的 -r
参数指定了能被任意访问的监听地址,而 -l
参数则指定了一个接受局域网里的服务器反向代理网络请求的地址,后面我们会用到这个地址
然后我们在本地局域网的服务器上同样运行 socket-pipe,假如本地(192.168.1.100
)要调试的这个网络服务端口是 7777
那么
socket-pipe -l 192.168.1.100@7777 -r 123.123.123.123@18888 -t tclient
这样我们就把本地 192.168.1.100
的 7777
端口,完全透明地映射到远程 123.123.123.123
的 8888
端口上了。
http 反向代理
可能你也注意到了,上面的 tcp 反向代理也可以用来代理 http 协议,因为其本身就是基于 tcp 的。确实是可以的,但是你如果只有一台服务器需要代理还好说,如果你有非常多的 http 服务需要暴露在公网上,你可能还要在公网服务器的 socket-pipe 前端加一台 nginx 之类的,把它的每个域名分配给每个连接上来的端口,然后还要启动茫茫多的 socket-pipe 进程来代理每台内网服务器,并且每次新增一台还要手动去改 nginx 配置。
这显然成本太高,但 ngork
不就是解决这个问题的么。确实可以解决,但首先 ngork
网络流量不可控,涉及到一些敏感信息的会有泄密的可能,其次它速度比较慢,我们自己有更快的服务器为什么不能用自己的,最后,它的一些高级服务或者更多的数量需要收费。
所以 socket-pipe 的最后这一个功能可以彻底干掉 ngork 了,它可以把无限多的内网 http 反向映射到外网去
同样我们先在外网服务器上运行,既然是代理 http 服务,那我们就直接监听 80
端口好了
socket-pipe -l 123.123.123.123@10080 -r 123.123.123.123@80 -t hserver
同样我们指定了一个 10080
端口来接受反向代理请求。然后在局域网的服务器上
socket-pipe -l 192.168.1.100@80 -r 123.123.123.123@10080 -t hclient -x git.dev.com -s git
在这里多了两个可选参数
-x
这个参数可以将外网请求的Host
头转化为指定的地址,比如你在外网访问的域名是www.example.com
,到本地http服务器上的时候就被 socket-pipe 转换为了git.dev.com
。如果你不填这个参数,那么就不会转换任何地址-s
指定了一个外网访问的二级域名。因为我们上面说了,有一堆 http 都被映射到了同一台外网服务器上,那么如何区分并单独访问他们呢,就是二级域名。比如你把*.example.com
的泛域名全部解析到了123.123.123.123
上,那么通过-s git
参数,你访问git.example.com
这个地址,流量就会被转发到当前指定的地址上。如果这个参数不填,socket-pipe 会自动创建一个随机字符串作为二级域名,并且会输出告诉你。
写在最后
目前这个工具已经在我们内部使用了一段时间,使用起来还是非常舒爽的,还有几个小问题需要解决
- udp的反向代理,虽然我没有这个需求,但我了解到有人需要这个
- 连接的稳定性,目前我们有心跳和自动重连机制,但是在某些情况下会失效,我正在处理这个问题
欢迎大家给我提bug和需求
https://github.com/joyqi/socket-pipe
终于能访问啦~原来这两年博客也没动静0.0 上来就给如此牛B的大福利!我有ss就不贪了嘿嘿。。(其实是node盲- -)
很好用,谢谢博主!
请问能实现多个端口转发吗?
目前多个端口转发只能用起不同的进程来实现
试了半天,一直不成功。浏览器显示“Not found”。服务器上显示:
C:\Users\Administrator\AppData\Roaming\npm>socket-pipe -l 60.205.161.*@10090 -
r 60.205.161.*@8011 -t hserver
Piping 60.205.161.@10090 to 60.205.161.@8011 via hserver
connected 223.20.195.196:61243 = d67d1250-1e74-11e7-ba67-c7ab42fb63dd null
accept 60.205.161.*:56358
request 60.205.161.*:8011
close socket 0
accept 60.205.161.*:56359
request 60.205.161.*:8011
你需要使用 -s 指定子域名来访问,要不然只能用 d67d1250-1e74-11e7-ba67-c7ab42fb63dd 来做子域名
如何保证在一直在服务器后台运行?
用nohup即可
阿里云centos服务器无法打开监听: Error: listen EADDRNOTAVAIL xxx.xxx.xxx.xxx:10080
在vultr中的centos是可以代理的
你用ifconfig看看ip地址,顺别贴一下你的命令是什么
监听命令:socket-pipe -l ip@10080 -r ip@80 -t hserver
ifconfig信息:
[root@jdu4e00u53f7 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
[root@jdu4e00u53f7 ~]#
按你给出的信息,-l 监听的本地ip应该是192.168.0.3
和SSH端口转发比较怎么样?
请问云服务器80端口被nginx占用的话怎么处理啊,换成88的话用域名:88能进来,但是本地没反应,只提示NotFound
云服务器里是用的内网ip,外网无法配置生效,本地访问的云服务器外网ip,这样不行吧?
你好,感谢提供这个工具,但是在使用的过程中有问题
1.数据的传输会有以下错误
Error: read ECONNRESET
errno: 'ECONNRESET',
code: 'ECONNRESET',
syscall: 'read'
}
Error [ERR_STREAM_DESTROYED]: Cannot call write after a stream was destroyed
code: 'ERR_STREAM_DESTROYED'
}
Error [ERR_STREAM_DESTROYED]: Cannot call write after a stream was destroyed
code: 'ERR_STREAM_DESTROYED'
}
Error: read ECONNRESET
errno: 'ECONNRESET',
code: 'ECONNRESET',
syscall: 'read'
}
2多连几次后不能再连接了,只能重新输入命令运行才行
谢谢