原料
dnspod 域名解析服务
openwrt (不需要安装额外的DDNS软件)
实现原理
OpenWRT 的 hotplug 顾名思义,就是热拔插的意思。当设备的任意硬件出现变更时会引发事件自动执行 sh 脚本。其中 hotplug 的设备分为block、iface、net、switch、tty、usb以及wifi,具体可以SSH到路由器查看/etc/hotplug.d目录。关于 Linux 系统中的热拔插可以参见这篇文章。例如你使用PPPOE上网,当拨号成功之后则会引起ifup事件,属于iface分类下的事件,那么 iface 文件夹内的sh将会按顺序被执行。DDNS的目的就在于动态更新你的IP到对应域名之中。刚好,dnspod提供了API可以修改域名解析的数据,那么当一个WAN或者PPPOE成功获取到IP时,则会执行sh。那么我们通过在iface下编写sh请求dnspod的API即可实现DDNS。
配置DNSPOD API
- 登录到你的DNSPOD后台,定位到 用户中心->安全设置,开启 API Token功能并记录好你的 TOKEN。然后设定一个需要实现DDNS的域名。
- 请求 API 获取返回值可以使用 curl 或者使用 postman 工具请求,我们只需要获取到需要 DDNS 的域名ID即可。
- 首先获取域名列表,POST 请求 https://dnsapi.cn/Domain.List ,参数 login_token=token_id,token ,请求后将会接收到 JSON 数据,找到对应域名的ID,并记录下来,方便请求获取二级域名信息。
- 获取二级域名列表,即获取域名的解析记录。POST 请求 https://dnsapi.cn/Record.List,获取该二级域名的所有记录,找到需要DDNS的二级域名,并记录下ID
了解 OpenWRT 的 ubus 命令行工具
ubus 在 OpenWRT 中提供了进程间的通信功能,使得进程之间的通信变得非常简单。配合 call 指令,我们可以把需要调用的指令发送到相应进程中执行。
为了获得WAN的IP地址,我们需要查看 network.interface.wan 的详细信息。
在终端中执行以下指令,我们可以看到WAN口的详细信息
ubus call network.interface.wan status
返回的信息为JSON格式,IP地址就位于 ipv4-address 下 的 address 之中,由此我们可以使用 grep 方便地取出
ubus call network.interface.wan status | grep \"address\" | grep -oE '[0-9]{1,3}\.[0-9]{1
关于 ubus 的更多信息,可以查阅[OpenWRT官方文档]
编写 sh 实现 ddns
有了上面的过程,现在我们已经拿到需要实现DDNS的域名ID,知道如何取出本机IP地址。配合 hotplug,当 WAN 连接上之后,会执行一遍 iface 下的 sh 脚本,那么,我们只要编写一个请求DNSPOD修改记录信息的脚本即可实现DDNS。
#! /bin/sh
ip=$(ubus call network.interface.wan status | grep \"address\" | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')
curl -k -X POST https://dnsapi.cn/Record.Modify -d "login_token=ID,TOKEN&format=json&domain_id=DOMAIN_ID&record_id=RECORD_ID&sub_domai
echo $ip
exit 0
通过 vim 或者 sftp 在 /etc/hotplug.d/iface 下新建一个 sh 脚本,并拷贝上述脚本到文件中。由于不知道其他脚本的具体作用,所以新建的文件名使用 99- 开头,确保在执行本脚本之前,原先的脚本会被全部先执行一遍。 代码中 ID 就是 TOKEN ID,TOKEN 就是 Token 内容,DOMAIN_ID 为前面获取的域名ID,RECORD_ID即为二级域名的ID,替换好后保存起来。
手动执行该脚本,如果没有什么幺蛾子,就会看到当前 WAN 口的 IP 地址,然后查看 DNSPOD 后台,就可以看到二级域名的 A 记录的 IP 地址同时变更。