各位都是程序员,工作中是不是遇到个类似情况。
在家里研究的一些开源代码或写的一些demo或试验代码,在工作中正好需要参考一下,但是在家里的电脑上。
虽然这些都可以用云盘/网盘之类的来完成,源代码也可以托管到源码平台。
但是这些都有一定局限性,先不说你不可能把所有东西都上传到云盘或git,就算你真的全上传了,在公司你也需要在重新部署一遍。
很多时候,我们只是想参考一下运行起来是很么样子而已,重新部署跟据环境差异的不同往往需要浪费很多时间,有的时候还得重新录入一些测试数据(因为数据库同步就更麻烦)
。
试想一下,如果我们可以
直接访问家里的电脑,而且可以直接连到家里电脑上数据库上是不是很爽。
我们知道,如果想通过互联网来访问家里的电脑,那么首先就得要知道家里电脑的公网 IP 地址。但是,家用宽带
一般
是没有固定IP地址的,每次连接上网后该地址都会随机改变,这样我们要在外访问家里的电脑就变得有些麻烦了。所以,这时候我们就需要用到 DDNS
(Dynamic Domain Name Server)
。
下面,我们就介绍一种利用 阿里云解析DNS服务来实现一个DDNS服务(腾讯云也有这个服务)。
在开始之前,大家先注意看一下下面这几个前提条件,免得浪费时间。因为不是所有网络都需要(或可以用到)DDNS的,而且DDNS也不能解决所有问题。
1.如果你的网络有固定IP或没有公网IP地址就不用看这篇文章了,前者没有必要,后者靠DDNS也解决不了。
2.在全球IP资源紧张的情况下(当然也有别的原因),目前大多数
ISP对家用宽带都不再提供公网IP,需要自己申请,目前已知的是电信/联通可以自己申请,但其他二级
ISP都不再提供公网IP地址了
。
所以,如果你用的是长城、艾普、移动之类的宽带也不用看了,实现不了。
3.目前全国所有家用宽带上传80端口都是被封了的,其它端口跟据运营商或地区也有被封的(21、8080之类常用的),注意自己测试,选可用的端口进行服务。
4.为什么不用花生壳或nat123之类的现成的DDNS服务?
这个扯到钱的问题了,当然
如果你是土豪,请随意(如果你真土豪的话,直接开通商业宽带用固定IP地址就行了)。
5.阿里云解析DNS服务是什么?
通过官方介绍我们知道,所谓云解析,其它就是让我们可以自己编写程序通过调用API来管理域名,包括解析(目前官方提供 JAVA、PHP、Python、C#的开发SDK)。
为了方便描述,我们在这里作一些名词约定,如果没有特殊说明,文章中都使用简称。
API 默认是指 云解析DNS服务API 的简称,
路由 是指 家庭环境的总路由器,
局域网 是指 家庭环境的局域网
,
公网IP 是指
家庭环境的公网IP
,
第三方服务 是指 一个能返回公网IP的服务真的第三方(例如:ip138)
,
“第三方服务”
(
带引号的
) 是指 你自己可随意控制的、能通过互联网进行访问,有固定访问地址的服务(例如:你自己购买了云服务器,一般都是有固定地址的)。
看完上面几点,如果没有问题的话,我们就可以正式搭建DDNS服务了。
首先
,我们需要一台在家庭网络下运行的设备来运行一个DDNS客户端。(不只局限于电脑,理论上只要是可以运行程序,能主动对外发出请求的设备都行,最好是可以24小时不间断的工作,断电或断网后可以自行恢复的。可以是电脑/服务器、
树莓派、可安装插件的智能路由器都可行
)
其次,针对不同设备,解决方案也略有不同,主要原因是:
a.
上面的设备除了路由器外,其他设备都需要借助
第三方
服务
才能取得公网IP地址。
b.既然需要用到
第三方
服务,那
由谁发
向API发送更新请求呢?
但总体来说也就两步:第一步,获取到公网IP地址。第二步,在IP变化时,向API发送更新请求。
跟据以上情况,我们可得到三种最优的解决方案(相对而言,更小的成本、最小的风险、
最快的解析生效时间
)。
方案1,路由 + API
方案2,局域网内设备 + 第三方能返回公网IP的
服务 +
API
方案3,局域网内设备 + “
第三方服务
” +
API
第一种方案是最完美的方案,因为路由器耗电少,可以24小时不间断工作,断电或断网都可以自动连接,可以第一时间检测到公网IP的变化。但是,目前还没见到市面上那款路由器集成这个的(有集成的花生壳的),所以你就需要一个智能路由器然后自己开发插件,大多数路由插件都是C/C++,但好在这个功能很简单,而且相关的SDK官方虽然没有提供,但开源社区里有。总体而言,这个方案相于而言要复杂些,但也是最理想的。
第二种方案,局域网内设备
上面运行一个DDNS客户端或插件
直接与API
交互,缺点就是需要借助第三方服务来获公网IP地址。我们知道,最大解析生效时间 = TTL + 获取IP的周期时间
,所以我们希望获取IP的周期当前是越短越好,但这样被封的几率就越大,增加了些不稳定的因数。
第三种方案,同样是
局域网内设备
上面运行一个DDNS客户端或插件,但不
直接与API
交互,只需要不停的向“第三方服务” 发送
心跳请求
就行
,然后“
第三方服务
”才
与API
交互
。
思路都介绍清楚了,下面我们就进入到实战阶段。
因为我是搞.net的,对.net最熟悉,所以代码都是C#的。其实,其它语言像go,php,node.js,python的解决方案都比.net的多,只是我不熟悉这些语言,不好修改,所以就准备自己动手。
当然,动手之前去github上搜一下有没有现成的,结果还真找到了一个,用的是上面第二种方案,代码是基于.net core的,并支付
docker,可以说
相当不错(github)。
不过
我使用的过程中遇到一些小问题。我家里服务器是windows server 2016的系统,虽然2016集成了
docker,但我折腾了好几天并没有在windows 2016上把docker跑起来,这样就不能以服务的方式运行,也没法开机启动。
所以我就把原代码修改了一下,改成windows服务了
。
还没完呢,对我这种追求完美的人来说,用第三方的服务来获取IP实现的还是有些不爽,而且我家里是台微服务器,还是乞丐版,配置很低(居然用了40多M内存),我自己在阿里云上也有服务器。
所以,我又动手把源码改成第三种方案了。
原先准备在家和阿里云之间用TCP或UDP来链接,这样实时性最好,最后一想太麻烦了,也没有必要。就
直接HTTP协议来多好,还可以把原先阿里云上的web网站利用起来,改一下就可以了。
这样家里这台微服务器只需要不断请求阿里云上的网站的一个地址就行了(也是写了一个
windows服务,1分钟请求一次,而且这个服务只会用到10几M内存
)。 oschina
代码说明:
1.代码分为两部分,有个叫aspnetCore的项目,是第三种方案中用在远程服务器上的,因为我是在已有的网站上改造的,所以单独写了一个示例代码,你可能将它集成到你自己的网站上。
2.src目录下的AliyunDDNS.Client项目是第二种方案的windows服务版,为了方便服务的安装和卸载,我写了两个叫Install.bat、Uninstall.bat的批处理文件,在项目的
bin/Debug目录下(注意:远行时可能需要用管理员权限运行)。
3.src目录下的AliyunDDNS.HeartbeatService的项目是第三种方案的客户端,也是一个
windows服务,用于不断的对外发出请求,同样在
bin/Debug目录下也有
Install.bat、Uninstall.bat
。
下面是远行起来的一些效果截图(有图有真相嘛,哈哈)
一些知识点
a.局域网内的计算机或设备直接从本地是获取不到公网IP地址的,必须借助于某个能够返回IP的第三方服务才行(网上的方案大多是借助ip138)。
b.服务端可以很容易获取到客户端的公网IP地址,如果服务器端和客户端不在同一个局域网,那么获取的就是公网IP地址(这里不考虑代理的情况)。
c.解析生效时间 = TTL + 获取IP的周期时间。阿里云解析免费版TTL为10分钟,收费的最高为1秒。所以
获取IP的周期时间应该尽量短小,路由器能直接监听到IP的变化,但其他设备就需要和第三方交互并通过不断轮询的方式来获取。
题外话
像花生壳这类的公司
(其他的都差不多)
,主打功能是内网穿透,就成本而言,
内网版和
公网版可以说一个是天上,一个是地下
。
但是,在前面1、2、3的大背景下,内网版更有商业价值,所以这类公司,对
内网版
和
公网版
定价相差并不大, 所以造成公网版价格虚高,所有有些不划算。(公网版才是DDNS服务,内网穿透功能其实上是代理)。
就以花生壳来说吧,以前花钱买了个花生壳专业版,都经常性访问不到。开始不知道原因,一直以为是自己网络环境的问题,一个偶然情况下,发现了花生壳商城有个测试页面没有关闭,0元就可以买到全套花生壳服务,果断下单买了一个“铂金版终身服务”,那速度就很快了,用起来就一点儿问题都没有。你想想,专业版都这样,你要花多少钱才能买到一个稳定的服务呢。当然了,如果你没有公网IP地址,这也不失为一个好的选择(花生壳这公司我也是醉了。1.犯这么低级的错误。2.没见过购买虚拟服务还要运费的。3.我把该BUG报告给他们管理员,他丫的招呼都不打就把订单取消就算解决问题了,而且10块钱运费也没退还)。