Write at first

来了,第二篇技术填充生活的文章终于被屎出来了,不过出现了个比较怪异的标题,什么内网外网咻咻咻的。。。哈哈,小学语文学的不太好,所以只能请大家见谅了。那就稍微解释一下这篇文章准备怎么让技术填充宅男的生活的。

首先,需要确认一个前提,在看这篇文章前确认有一些网络基础,最最起码的,要能分清楚啥是内网,啥是外网,这样有利于能比较快速的了解这篇文章所要分享的一些知识,当然,不是说不了解就直接放弃了,在看文章的过程中,对不了解的东西做拓展性学习,这也是技术宅好好成长的一部分,不是吗?

好了,一堆废话之后,该概括一下这篇文章要讲啥了,其实,说起来是很简单的东东,就是让内网的机器或者内网机器中的服务(比如WEB服务、FTP服务)分享到公网中去,这样在不同局域网中的机器就可以方便的访问到内网的机器了。

虽然说起来简单,但是这中间的方法包含着很多可学性的技术内容,相信对于刚刚要进行网络基础学习或者网络深度学习者都能从中学到好东西,当然,中间会穿插一点比如翻墙的技术,是不是感觉有点high了,那就Let’s begin吧。

What’s the problem

再次描述一下我生活中实际碰到的问题吧。在下爱搞一些杂七杂八的东西,不是个纯粹专注于软件的小鬼,软件+硬件才比较符合我的胃口,所以一直在玩着Raspberry pi这类玩具,不过在弄完一辆小车之后,Raspberry pi居然出了二代,看了看配置,哇噻,眼前一阵亮光,玩起来后感觉这速度,岗岗的。。。好想有一堆乱七八糟的话乱入了是不是,额,还是简单了之,就是我准备用Raspberry pi作为服务器来使用(那前面说毛废话,嘿嘿)。不过正如大家所料,我宿舍也就只有一个外网端口,作为一个屌丝,宿舍用路由来外接设备是必须的,然后咧,自然就出现问题了,树莓派也是接入在这个路由内部,那当毛毛的服务器啊,如果用内网地址的话,那就只能内网的设备才能访问的,这样的话。。。也太蠢了吧,当然,比如说高帅富一点的,要拿一台台式机、笔记本或者真的用一台服务器其实跟我的问题一样了,不过如果你申请了n个外网接口,那我们就再也不是朋友了。

对于所描述的这个问题,利用下图表述应该更清晰一点:

problem

怎么让computer A连接到computer B呢?

How to solve

对于上述的问题我这边的解决方法大类可以分为两种,我就先介绍一下简单的那种解决方法吧。

端口映射法

这个方法我想很多人都可以想到,当然,有个先决条件,这是一个家用网络,咱控制着这个外网接口的第一级网络设备,所以咱爱咋干咋干的,不过如果说在公司网络内这个方法就不适用了,就必须用我下面会提到的第二种方法,这个我呆会儿再详细介绍。

这种方法,需要在一级路由中做操作,就是说。。。你的路由器必须有这个功能,不然啥都是扯谈。当然,现在大部分路由器都是有这个转发功能的,除非是n年前的路由吧。

先通过一个图来说明一下这个方法吧,请看下图:

solve-0

在computer B开启了一个WEB服务,即开启了80端口,这个时候通过设置路由器的转发规则,将发送到路由器公网地址80端口的数据转发到computer B的内网IP中即可。

这个方法我想在不同的路由器给出的接口是不同的,在我所用的TP-link路由器中,通过转发规则->虚拟服务器,添加转发规则即可实现端口映射。

简单说明一下该功能的原理,在Linux下相信大部分人都能知道一个比较出名的网络应用,叫iptables,通过在内核中添加不同的数据转发表和链对从网络上接收到的数据进行转发和接收的工作,而端口映射正是使用了该应用规则,通过做一次的DNAT,改变数据发送的目的地址以及端口,在服务处理数据再进行返回时,路由器上再做一次反向DNAT即可将返回数据成功发送回真正的客户端中。

很简单吧,当然,这是有一个及其重要的前提条件,你需要能够控制路由,通过路由定制其转发规则,当路由达到两层或者更多的时候,这个规则将会更加的复杂。

这里补充一个小知识,对于用户来说,一般不通过记忆IP的形式来访问服务器,因为,大部分人对于数字都是比较不敏感的,还有一个更关键的原因,对于运营商分配给我们的IP地址是会不断变化的,所以通过记忆外网IP访问比如宿舍的内部网络是不靠谱的,那要通过啥来玩呢?那如果不访问IP,那肯定就是域名了。但是普通的域名需要固定IP来进行绑定,利用静态的DNS肯定也是不靠谱滴。最终这个纠结的问题就定位在DDNS上面了,所谓DDNS就是动态的DNS,简单这么理解着就行了,通过动态绑定IP,将不断变化的外网IP与一个固定的域名进行绑定,说起来也是挺简单的。我现在使用的其实也是最常用的花生壳服务,这个应该大多国内山寨路由都会内置这个玩意儿吧,反正用着也还凑会儿,而且不用钱,就先这么整了呗,如果谁有更棒的DDNS服务可以给我发个邮件告诉我下,大家一起学习进步嘿。

好了,端口映射法就介绍到这里了,如果有啥搞不清楚或者不明白的朋友,可以通过邮件联系我一起探讨哦。

ssh隧道法

跟上个方法不同,我认为接下去介绍的这个方法有更大的通用性,跟修改路由器来比较,其实这个方法感觉上更复杂一点,需要动点脑筋,不过其实稍微动动脑筋就可以理解其中的奥妙,同时还能更好的体会到ssh强大的存在性。

在开始介绍之前,需要先确认几个东西。首先,用的系统最好是nix、linux或者bsd,这几个系统我想应该能有最完整的ssh功能支持吧,如果是windows或者mac os,这两个系统的话,就靠自己去折腾和尝试了。然后,确保自己有一个外网公开的vps,vps必须开启ssh服务。简单说下啥是vps,vps其实就是云服务分层中的PAAS(至于啥是PAAS就自己查一下吧,这个范围有点广了),在公网上部署了一台可用服务器提供给你使用,通过比如ssh等工具连接成功后可以类似于使用自己电脑系统一样使用云端服务器。我使用的是亚马逊的EC2服务,这个vps服务在第一年使用是免费的,当然别以为是纯免费就瞎用哦,超过它给的免费范围还是要扣你钱的,至于如何申请和使用aws,那靠自己了嘿,这里就不涉及了。当然,国内几个大的流氓公司也有很多这类服务,而且因为服务器部署在国内,速度会快于亚马逊。那咱为啥要用亚马逊的呢,首先,国内的公司大部分都比较流氓呗;再次,亚马逊是老牌子这个不用说,亚马逊最大的服务不是www.amazon.com,是aws.amazon.com哦,稳定不在话下;再再次,亚马逊都是国外服务器,而且GFW还没有进行封阻,没事还可以拿来翻翻墙,而且可以直接用ssh隧道进行翻墙,一会儿会补充涉及到。

在确认完以上先决条件之后,先来讲讲ssh隧道实现内网服务端口访问的原理,这是一个逆向思维的方式,所以确定你的脑袋瓜子能倒过来想问题。首先,公网数据发送到一个公网IP,但是没有做数据转发是没办法到达内网的,这个应该大家都是清楚的,但是反过来呢,内网IP要访问公网IP上的某个端口服务可以吗?这他丫的不是废话吗,不然手机怎么能打开网址呢,真是棒棒的聪明啊。不过这里面的原理其实也是通过路由器的NAT功能,只不过内网穿外网是默认开启的罢了。那这样子vps就此登场了。比如上图,computer B通过ssh连接到vps上,这个时候是否就建立了一条ssh的隧道呢,当然,但是普通的ssh连接所建立的隧道是无法做数据转发的,所以需要建立一条ssh的反向隧道,在建立ssh隧道的同时,在vps开启一个新的固定端口,这个端口与隧道在vps的端点连接(即ssh服务),然后ssh隧道在computer B的端点与computer B的80端口连接(假设现在也是要开启80端口服务),这样就建立了一条完整的转发隧道,同时vps是开放到公网中的,只要开启在vps中新的固定端口的访问权限,那么computer A就可以毫无压力的访问到computer B对应的服务中了。

看了原理感觉绕吗?其实也是一个简单的原理,只不过是利用了一个逆向思维,让映射的端口放到了另外一个网络中,也不得不说这个方法的巧妙性阿,特别是vps服务现在大量流行的情况下,这个方法不失为一种吊炸天的方法,不单单可以映射你的家庭网络内网机器服务,就算在公司的电脑希望映射出来也难不倒你了吧。还是通过图来稍微再瞧一下这个巧妙的方法吧:

solve-1

通过箭头所在的直线,即产生了一条隧道,而且该隧道是一个应用层面上的隧道,无需设置路由,更方便。当然,好像貌似听说会产生一些安全问题,要不要用,要怎么用就看个人需要了。

说了这么多,也没说明白这个隧道应该怎么建立是吧,来来来,小伙伴们都瞧过来吧。

首先,要先配置一下vps上的ssh服务,在/etc/ssh/sshd_config底部增加GatewayPorts yes选项,重启sshd服务。这个配置的目的是让在vps上做映射的端口可以映射到外网地址中,即本地的0.0.0.0地址,否则,建立起的ssh反向隧道只能映射到回环地址上,就无法被外部所用了。

接下来就只需要一条命令了:

ssh -i .ssh/×××.pem -fNR 0.0.0.0:8080:127.0.0.1:80 ubuntu@××××.××××.××××.××××

其中,×××.pem是vps颁发的公钥,这个在申请vps并建立instance时会颁发给你用于做ssh连接使用的,另外××××.××××.××××.××××为vps的IP地址或者域名。简单解释一下该命令,-i -f -N这几个ssh应用的选项不多做解释,直接查阅man文档,-R选项就是建立ssh反向隧道,将本地的127.0.0.1地址80端口映射到对端8080端口,并且映射在对端的0.0.0.0的IP地址中。很简单吧,一条命名就搞定了这看似很复杂的功能了,接下去随便利用python或者什么启动一个简单web服务,然后利用公司电脑访问vps的8080端口就可以看到实现效果了。

在ssh隧道中,还会被用到比较广泛的一点就是在于翻墙,当然vps也是一样必不可少的,在本机上执行下面命令即可:

ssh -i .ssh/×××.pem -f -N -D 8000 ubuntu@××××.××××.××××.××××

执行完该指令后可通过socks协议连接本地开启的8000端口进行应用局部翻墙了,其原理与ssh反向隧道类似,不做更多的解释,大家可自我参悟嘿。

这篇内容咋样,还可以吧,希望今天写的这篇文章能在技术宅生活中产生大用处嘿,技术让生活更精彩,精彩完咱就该睡觉了嘿,大家晚安!