远程办公何时了,网络打洞帮你搞!喝茶!

2,570 阅读7分钟

远程办公何时了,网络打洞帮你搞。网之重器,猛虎出笼。

原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处。

最近,有位像诗一样的朋友,充满了罗曼蒂克一样的堕落主义思想。他不想上班,不想工作,就想翘着腿躺在床上刷手机。作为又一个被优美的生活所摧残的青年,我深刻理解他的想法,他爱上了远程办公。他的电脑在公司,人在家,可以用类似TeamView一类的软件去做。另外,他还精通网络打洞技术,能够远程控制很多网络环境很复杂的机器。

什么叫打洞呢?其实就是内网穿透。

你可能有这样的需求:

  • 调试一些支付回调接口,但是又想在本地的Idea中接受请求进行debug;
  • 家里有一台性能非常霸道的机器,想要在上班时能够连上它,做一些不可告人的操作
  • 手里有一大批broiler chicken,但对方在各种防火墙之内,你想要集中控制它
  • 廉价的远程办公
  • 远程控制手机打卡签到!
  • 给客户做演示,懒得再搭建环境,想要直接访问自己机器上的程序...

不要着急,你所能想到的这些,看完本篇文章,都可以搞定。而且,不需要你亲自动手编码。

这些需求,有的是正当的,有的是邪恶的,这也体现了技术的两面性。工具在不同的人手里,会有不同的功效。比如到了xjjdog手里,它仅仅变成了一篇水文。

重回正题,为了让你能够上手应用这种内网穿透技术,你需要一台能够上网的云主机。要最便宜的那种就可以,它将作为我们的流量转发中枢。

1. 这是什么原理?

我们当然要拿一个比较正当的用途,来说明一下它的基本原理。打洞方式有很多,我们只介绍一种最直观、最简单的(严格来说,下面的介绍只属于隧道,为了描述方便,我们统称为打洞)。

要明白一个事实:“网络连接,是双向的。” 请铭记这个看起来再自然不过的特点,它将是我们接下来介绍的这种方式的根本。

拿支付例子来说。程序调用了微信或者支付宝的api进行支付后,平台会将支付结果通过回调地址通知我。

由于我的386机器在内网中,加上层层的路由器和交换机防火墙,再加上ipv4的珍贵性,微信根本找不到我。大隐隐于市,也不过如此吧。

幸运的是,我能上网!这可以说是公司对我的最大恩赐了。

遇到网络问题,最好的解决方式就是加上一个中间层。这和nginx有异曲同工之处。nginx通过加入一个配置,就可以把服务端的资源暴露到公网上。我们也使用类似的思路去解决,但这次,我希望的是把自己本地的386,暴露到公网上。

不能用nginx做反向代理,因为nginx同样访问不了处于墙内的我(淦)。

这时候,我们上面提到的基本事实,就起作用了。

加入一个中间层墙内翻译,再加入一个中间层墙外翻译。一旦它们连接上,不管是谁连接上谁,都能够相互进行流量转发。注意我们的箭头,正向的数据流动,和反向的数据流动,对于一个连接来说,并没有什么区别。

为了更明白的看一下这个过程。我画了两组端口图。红色防火墙左边的,就是本地机器;右边的,就是转发服务器。

刚开始的时候,转发服务器监听在7000端口。在本地机器上,进行了一个配置,告诉服务端:麻烦您再监听一个9090端口,当有数据请求到来的时候,麻烦通过你的客户端,转发到我的8080端口上。

这就是整个内网穿透的基本思路。

2. 实践一下

原理,只是赠送给对内网穿透有好奇心的同学。对于大部分人来说,直接用就对了! 谁有闲工夫去搞明白为啥发动机是怎么设计的。

需求催生工具。目前常用的开源工具,有很多比如zerotierngrokfrp等。下面以frp为例,来说明一下它的使用方式。

https://github.com/fatedier/frp/

如果你看过上面的原理,就会发现它的配置,实在是很简单的。

首先,准备一台云主机。我们叫它server。

在server上,下载frp,解压。然后配置frps.ini。好家伙,只有两行,就是一个绑定端口。这证明了我们要在客户端的配置上下点功夫。

[common]
bind_port = 14000

接下来,在本地机器上操作,我们记做386。

在386上,下载相应平台版本的frp,解压。这次要修改的是frpc.ini文件。

[common]
server_addr = 139.202.186.135
server_port = 14000

[springboot-1]
type = tcp
local_ip = 127.0.0.1
local_port = 8080
remote_port = 9090

在这里,我们指定连上了server的14000。并告诉它,启动一个9090端口。当有请求的时候,转发到我386的8080端口。

在386上,已经用idea启动了一个springboot项目。当微信的支付回调,调到server的9090端口时,我就可以在idea里打断点进行调试了。

3. 两个小案例

我们再来看两种常见的操作系统完全控制。

对于Linux服务器来说,对外开放的一般是22端口。我们可以通过ssh来连接它。

[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000

在本地,通过下面命令即可连接放在家里的机器。

ssh -oPort=6000 test@x.x.x.x

同样的,要想远程控制windows,还是得首先把远程连接功能给打开。

在windows机器上,简单的配置一下端口就可以。因为它是通用的tcp连接,所以我们并不需要配置什么额外的东东。

[RDP]
type = tcp
local_ip = 127.0.0.1
local_port = 3389
remote_port = 33891

可以看到,由于22和3389都是基于tcp协议的,所以这种转发配置,也简单的像是吃饭一样。

End

市面上的一些打洞软件,难的并不是技术,而是从业资格证书。毕竟,别人用你的服务,向外传输的内容,都是不得而知的。这时候如果没有运营证书或者严格的内容审查,就只能背锅。

讲完了打洞的原理和简单使用案例,我们有必要着重提一下它的安全性。

温馨提示:打洞请尤其注意它的安全。如果你是打通的ssh或者3389,请确保打了相关的补丁,并且采用了强密码。一般公司会采用VPN的方式管理远程访问,打洞可以说是直接绕过了VPN,是非常危险的行为。

如果你打的洞,被其他别有用心的人获得,通常会造成内网的崩溃。如果你的公司并不允许这种行为,就不要把公司内网的服务暴露到外面。

打洞还通常与泄密有关。一个被严格保密的内网系统,由于其中的一台机器能够上网,就可以把服务暴露出去供外部人员访问参考。

建议在打洞之前,先了解一下什么叫做“面向法律编程”。演示一类的打洞,需要经过公司授权;拒绝一切公司内网类的ssh和3389打洞。

否则,出了事情,被请到局子里喝茶去,就不太好了。

作者简介:小姐姐味道 (xjjdog),一个不允许程序员走弯路的公众号。聚焦基础架构和Linux。十年架构,日百亿流量,与你探讨高并发世界,给你不一样的味道。我的个人微信xjjdog0,欢迎添加好友,​进一步交流。​