-
Openwrt使用DNSPod服务做动态域名解析(ddns)–一些优化
一个基本的使用DNSPOD提供的API来实现ddns的脚本已经能够工作了,这是一个基础的脚本,实现的是最基本也是最直接的工作。 除了基础功能的需求,我的wr720n上运行脚本之后,发现了我还有一些其他的额外的需求,脚本需要针对这些需求j来做一些改进和优化。 这些额外的需求是: 我的wr720n上安装了多播的软件(我设置的是3播),所以wrt720上会同时获取3个外网地址。由于有负载均衡,每次访问api网页的时候,可能会从3个接口中的任意一个出去,这实际上是没必要的,因为这会导致多次调用脚本的时候,实际上是一直在三个ip中切来切去。我希望每次更新ip的时候,访问api网页都是通过同一个网络接口出去的。 脚本中使用的验证机制是用户名+密码的机制,这个机制比较的原始。而DNSPOD是支持使用token的机制的。使用token机制看起来会比较的更加安全一点。 执行脚本的时候,先检查一下当前的ip地址跟DNS解析出来的ip地址是否一致,如果不一致才更新ip地址。 每次向服务器更新ip的时候,都要通过调用两次api接口分别用于查询domain_id和record_id,而这其实是一个比较费时间的过程。实际上domain_id和record_id对于某个特定的域名来说是固定的,就是说只要查询一次,下次直接使用就可以了。可以做优化缓存domain_id和record_id。 针对第一个需求,其实使用的方法也很简单。因为脚本使用curl命令去访问DNSPOD的API的,而curl命令是支持指定特定的网络接口的,添加一个选项”–interface xxx”就可以了。wr720n上,比如我希望每次访问api去更新ddns的ip的时候使用”pppoe-VWAN1″接口,那么脚本中的dnspod_update_record_ip()函数可以修改为: dnspod_update_record_ip(){ options=”login_email=${ACCOUNT}&login_password=${PASSWORD}”; curl -k -s –interface pppoe-VWAN1 https://dnsapi.cn/Record.Ddns -d “${options}&domain_id=${DOMAIN_ID}&record_id=${RECORD_ID}&sub_domain=${RECORD_NAME}&record_line=${RECORD_LINE}”; 针对第二个需求,其实解决方法也很简单,参考DNSPOD的API的官方手册就可以了。首先要做的是在DNSPOD的账号里面申请一个token.申请成功之后,在DNSPOD的账户中能够察看到token_id和token.然后在脚本中将所有的使用login_email和login_password组合的地方改为下面的格式即可: login_token=token_id,token 针对第三个需求, 确定DNS解析出来的域名的ip地址的方法,可以使用”nslookup”命令查询,这个命令能够返回查询域名的当前解析出来的ip地址。 而确定当前路由器上的ip地址的方法主要有两种。 一种是网络上有一些提供检测ip地址的网页,只要访问这些网页,就能够返回当前访问者自己的ip地址。 一种是直接使用ifconfig(或者ip命令)命令直接查询openwrt本机上的外网ip地址。 这两种方法各有优势,第一种方法的优点是无论路由器的ip地址是怎么配置的,总能够得到路由器的ip地址,缺点是不能够保证网络上提供ip地址解析服务的网站一直都能提供服务,说不定哪一天就停止服务了。而且是通过网络查询,经过实际测试,速度比较慢。 第二种方法的优点是速度快。但是缺点是,在路由器上,必须配有外网地址。如果openwrt是二级路由器之类的,也就是只配有”192.168.x.x”这样的机器,那就不行了,使用本机的ifconfig命令不能够直接获取到外网的ip地址。 我的wr720n机器是直接通过pppoe连接到外网的,所以是能够通过本机命令获取ip地址的。所以我使用了第二种方法。在脚本中增加下面的一个函数dnspod_is_record_updated(): dnspod_is_record_updated(){ #Format is “Address 1: 117.89.152.129″ record_ip=`nslookup home.proudj.com |tail -n 1 |cut -d ” ” -f 3`; # #Format is ” inet 117.89.152.129 peer 61.155.116.217/32 scope…