作者 | 梁唐
大家好,我是梁唐。
周末闲着无聊,在家又捣鼓起了树莓派。
树莓派有一个很大的好处,就是体积很小,价格很便宜但五脏俱全,相当于一台微型计算机,什么都能干。一般来说,大家都会将它放在家里,当做一个小型的服务器,存储文件、数据,或者是跑一些简单的任务之类的。
但是这当中有一个很大的问题,就是我们的树莓派只能在家里访问,一旦出了局域网的范围就无法连上了。这显然不符合我们随时随地可以连入的要求。
好在,周末折腾了两天之后成功解决了这个问题,就和大家简单分享一下。
问题分析
出了家就连不上树莓派的原因很简单,因为树莓派并不是公网当中的一个节点,我们当然不能访问。
可能这么说还是有同学有点蒙,再说明白一些,就是树莓派没有自己的ip。我们打个不恰当的比方,树莓派没有ip就相当于孙悟空在生死簿上没有姓名,那牛头马面(dns域名解析)自然也就无法找到它。
可能又会有同学疑惑,不对啊,我们既然能上网就可以接收消息才对, 不然微信怎么收到消息的?网页怎么打开的?为什么可以上网也可以接收消息,就不能接收外界连接吗?
这个问题也很简单,因为我们在本地打开微信的时候,本质上是和微信服务器建立了一个连接。因为微信服务器的地址是明确的,写在了微信程序里了,上网也是一样,网站的服务器地址也是很明确的。连接建立了之后,通信自然是双向的。
而我们在图书馆、咖啡厅这些场所想要连接我们的树莓派则不同,因为我们不知道树莓派的地址,根本无从建立连接。尤其是使用ssh协议连接,必须要知道对方的ip地址。
所以核心的问题就是得替树莓派搞到ip地址。
真假ip
到这里,估计又有人会说,ip地址还不简单,打开网络设置看一下不就知道了?
网络设置里是可以看到ip地址不假,但问题是这个ip地址是有问题的,是一个假ip。我这里贴一下我电脑上的结果给大家看下:
我估计很多同学的结果和我差不多,看到的都是这样一个192.168开头的数字。这是怎么回事,难道大家的ip重了?
原因很简单,因为这样查到的ip并不是公网ip,而是在路由器里的ip。
举个很简单的例子,如果我们把从网络接收消息比喻成收发快递。快递员根据ip地址送货上门,但有一天快递员告诉你他们的地址簿不够了,写不下那么多地址了。所以大家就只能将就一下,不再送货上门了,只送到小区,由小区的保安送上门。
这里的小区就是一个一个的局域网,小区的保安自然就是路由器。对于路由器来说,每个业主的地址从xx市xx区xx小区xxx,直接简化成门牌号码xxx。我们通过设置看到的ip就是这样一个路由器内部的ip,知道这个ip毫无卵用。
就好像你想要寄个快递到502室,但却不知道小区名,显然这个快递是没法寄的。
想要寄快递,我们必须要知道地址的全名,这个全名就是公网ip。
公网ip怎么来?
想要知道当前的公网ip很简单,基本上每个查询ip的网站都能查到。
这里以比较著名的ip138举例,我们打开ip138这个网站就能看到我们当前的公网ip了。
你看不仅能显示ip,还能显示归属地。
但有了这个ip依然解决不了问题,我们不能直接用。因为国内的公网ip并不是以家庭为单位分配的,原因很简单,因为ip地址不够用。所以运营商们为了解决这个问题设计了很多策略。
比如说共享ip,可能你家和另外的几户人家共享同一个ip,并且这个共享可能也是动态的。你用的比较多,就和少一点的人共享,用得少可能就和多一些的人共享。另外为了防止有人偷偷霸占不多的ip地址,国内宽带的ip也是动态的。每隔一段时间就变动一下,不让你霸占。
我查了一下,针对这个问题没啥特别好的办法,主要解决策略有两个。一个是打电话给运营商要求他们为你提供一个固定公网ip,据说只要有合理原因(办公需要、学习需要)等就可以得到。还有一个办法是写脚本实时查询,动态修改树莓派绑定的DNS地址,这个我们之后再说。
我个人感觉要一个ip最简单,也最直接,如果要不到,可以再尝试其他方法。
但不管怎么说,我们通过ip138就可以得到我们当前的公网ip了。即使它之后会变,但也不影响我们继续实验。
配置路由
有了公网ip,我们就可以来配置路由了。
配置路由的原因也很简单,因为公网ip是路由器的ip,并不是我们树莓派的ip。我们想要连接到树莓派,还少不了路由器的转发。
路由器也不是人,它又不知道什么时候该转发,转发给谁,这都需要我们配置。
配置的方法很简单,首先我们登陆路由器,一般来说网址都是192.168.1.1,各个路由器可能会有所不同,大家查看路由器上的说明即可。
登陆成功之后,我们可以继续查看路由器中连接的设备,找到树莓派,可以看到它在路由器的ip地址。
有了ip地址之后,我们继续配置一个单端口转发就齐活了。
我这里配置了一堆,我们只要看第一条就行。我们绑定的端口是22,然后转发的目标ip是1.148,这是因为ssh协议走的是22端口,树莓派的地址是1.148。
配置好了之后我们就可以测试连接了,测试的方法也很简单,在配置完ssh之后,使用命令:
代码语言:javascript复制ssh pi@27.xxx.xxx.xxx
这里的pi是树莓派ssh连接的账号名,@后面跟的是路由器公网的ip地址。ssh怎么设置这是另外一个话题,这里就不展开说了。
顺利的话就可以看到已经连接成功了。
进阶
理论上来说,这样就OK了,我们即使离开家里的局域网也一样可以连上树莓派了。
但是还不够完美,一个是我们需要记住公网ip,往往比较难记,另外一个是这个ip可能会变化,比如被运营商改了。
这两种情况也有办法,我用的办法是域名 DDNS,也就是购买一个域名,然后通过远程修改域名DNS配置的方式来解决。
比如我在GoDoggy中买了一个域名,它支持我们配置DNS,也就是做域名和ip的绑定。我们将它绑定到路由器的公网ip,这样我就可以直接访问域名,而不是通过ip来访问树莓派了。
至于路由器公网ip变化的问题,也有绕开的办法。比较推荐的方法是在树莓派中定时运行Python脚本检查公网ip是否发生变化,一旦变化,就修改GoDoggy中的DNS配置。
当然这需要一定的Python编码能力,不过网上也能找到类似的代码,拿过来稍微改改就行。
除此之外还有一些其他的方法,比如搞一个个人服务器(VPS),然后将服务器的某个端口和树莓派的22端口绑定。这样我们访问服务器的端口就相当于远程连接到了树莓派。
域名和VPS虽然都有一定的成本,但好在价格不是很贵,学生党也完全能承受。但其实反过来想想,既然都能搞到VPS了,其实也不差这块树莓派,直接用云服务器显然更香。但相比于捣鼓成的结果,这个捣鼓的过程才是精髓。比如这一套捣鼓下来肯定会对域名、DNS、ssh协议有着更深刻的认识。
好了,就说这么多吧,感谢大家的阅读。