DualWAN+PHP+DNSPOD实现域名自动解析
去年折腾的一个小玩意, 出发点是电脑上搭了一个php程序, 需要实现外网实时访问然后路由是用的dualwan, tomato的固件, 其实固件里已经内置了解析功能, 可以直接解析3322和花生壳,
但是由于几个动态域名服务商都不太稳定的原因 (其实就是他妈闲的蛋疼瞎折腾), 所以就想用用dnspod来动态解析.
首先dnspod自己就提供了一套动态解析的服务端, (地址:https://support.dnspod.cn/Kb/showarticle/tsid/19)
但是由于是软件模式的, 你还得搞个开机启动, 还得装个服务才能用, 还是很不爽, 如果直接在路由上实现就不会有这些问题了.
好了不废话了, dnspod官方有提供域名解析相应的api (地址: https://www.dnspod.cn/docs/records.html#record-modify)
接口地址: https://dnsapi.cn/Record.Modify
HTTP请求方式: POST
请求参数:
公共参数
domain_id 域名ID,必选
record_id 记录ID,必选
sub_domain 主机记录,默认@,如 www,可选
record_type 记录类型,通过API记录类型获得,大写英文,比如:A,必选
record_line 记录线路,通过API记录线路获得,中文,比如:默认,必选
value 记录值, 如 IP:200.200.200.200, CNAME: cname.dnspod.com.,
MX: mail.dnspod.com.,必选
mx {1-20} MX优先级, 当记录类型是 MX 时有效,范围1-20, mx记录必选
ttl {1-604800} TTL,范围1-604800,不同等级域名最小值不同,可选
响应代码: 共通返回
-15 域名已被封禁
-7 企业账号的域名需要升级才能设置
-8 代理名下用户的域名需要升级才能设置
6 域名ID错误
7 不是域名所有者或没有权限
8 记录ID错误
21 域名被锁定
22 子域名不合法
23 子域名级数超出限制
24 泛解析子域名错误
25 轮循记录数量超出限制
26 记录线路错误
27 记录类型错误
29 TTL 值太小
30 MX 值错误,1-20
31 URL记录数超出限制
32 NS 记录数超出限制
33 AAAA 记录数超出限制
34 记录值非法
35 添加的IP不允许
36 @主机的NS纪录只能添加默认线路
82 不能添加黑名单中的IP
也不想手动的去装他, 所以就另辟蹊径, curl不能用, 我用wget还不行嘛! 所以就有了后面结合php的想法
好了开始说正题吧, api有两个比较重要的参数需要获取, 那就是
domain_id 域名ID,必选
record_id 记录ID,必选
第一, 安装dnspod官方的动态解析软件 (https://www.dnspod.cn/client/DNSPodClientLite.zip), 登录你的帐号 如图
然后选择要解析的域名点击"动态解析", 之后选择对应的记录添加到启动动态解析:
设置好以后再看软件目录下的config.xml文件就可以找到你域名的id(domain_id)和记录id(record_id):
有了这些参数以后再用php来提交就可以了, 这里用了一个dnspod开发人员写的api类, 直接调用一下就可以了,
index.php里修改一下对应的参数即可:
classh.php(api提交类), index.php(功能) 两个文件代码文末会贴出
之后放到web目录下, 比如我本地访问地址为 http://127.0.0.1/DNSPOD/index.php
而我本机对应的内网ip为192.168.1.210
然后进入"tomato - 系统管理 - 定时任务", 开启一个脚本, 命令代码如下:
rm -rf /tmp/dnspod/
mkdir /tmp/dnspod/
wget "http://192.168.1.210/DNSPOD/?ip=$(nvram get wan_ipaddr)|^$(nvram get wan2_ipaddr)|^$(nvram get wan3_ipaddr)|^$(nvram get wan4_ipaddr)" -O /tmp/dnspod/log.txt
rm -rf /tmp/dnspod/log.txt
设置完成后保存设置就大功告成了!
最后说一下为什么我这里是提交的4个ip, 因为我是设置的4条多拨, 入过没有设置多拨就是单拨的黑客直接把wget地址修改成
http://192.168.1.210/DNSPOD/?ip=$(nvram get wan_ipaddr)
两拨:
http://192.168.1.210/DNSPOD/?ip=$(nvram get wan_ipaddr)|^$(nvram get wan2_ipaddr)
三拨
http://192.168.1.210/DNSPOD/?ip=$(nvram get wan_ipaddr)|^$(nvram get wan2_ipaddr)|^$(nvram get wan3_ipaddr)
四拨:
http://192.168.1.210/DNSPOD/?ip=$(nvram get wan_ipaddr)|^$(nvram get wan2_ipaddr)|^$(nvram get wan3_ipaddr)|^$(nvram get wan4_ipaddr)
其实很简单, 这个问题也有很多人在各种地方问, 大部分人就卡在不能用curl那了, 各种不能安装, 其实有时候多转转脑子问题就解决了
最后贴代码 index.php:
<?php
require './class.php';
$dnspod = new dnspod();
$ip = explode("|^",$_GET['ip']);
if( count($ip) >= 1 && is_array($ip) ){
foreach($ip as $k=>$v){
if(ip_check($v)){
$value = $v;
break;
}
}
}else
{
if(ip_check($v)){
$value = $v;
break;
}else{
exit();
}
}
$dnspod->api_call("Record.Modify",
array('login_email'=>'DNSPOD登录名',
'login_password'=>'DNSPOD密码',
'format'=>'json',
'domain_id'=>'看文中先获取',
'record_id'=>'看文中先获取',
'value'=>$value,
'record_type'=>'A',
'record_line'=>'默认')
);
function ip_check($value){ //验证ip是否非法
preg_match_all("/[.]/i",$value,$matches); //取点号
if(count($matches[0])==3 && strlen($value)<=15){ //判断IP是否正确
if(is_numeric(substr($value, strlen($value)-1, 1)) && is_numeric(substr($value, 0, 1))){ //判断IP是否正确
return true;
}
}else{
return false;
}
}
?>
<?php
/*
* DNSPod API PHP Web 示例
* [url=http://www.zhetenga.com/]http://www.zhetenga.com/[/url]
*
* Copyright 2011, Kexian Li
* Released under the MIT, BSD, and GPL Licenses.
*
*/
class dnspod {
public function api_call($api, $data) {
if ($api == '' || !is_array($data)) {
exit('内部错误:参数错误');
}
$api = 'https://dnsapi.cn/' . $api;
//$data = array_merge($data, array('login_email' => $_SESSION['login_email'], 'login_password' => $_SESSION['login_password'], 'format' => 'json', 'lang' => 'cn', 'error_on_empty' => 'no'));
$result = $this->post_data($api, $data);
if (!$result) {
exit('内部错误:调用失败');
}
$results = @json_decode($result, 1);
if (!is_array($results)) {
exit('内部错误:返回错误');
}
if ($results['status']['code'] != 1) {
exit($results['status']['message']);
}
return $results;
}
private function post_data($url, $data) {
if ($url == '' || !is_array($data)) {
return false;
}
$ch = @curl_init();
if (!$ch) {
exit('内部错误:服务器不支持CURL');
}
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_USERAGENT, 'DNSPod API PHP Web Client/0.1 ([url=mailto:[email protected]][email protected][/url])');
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
}
?>
评论11次
点赞,才发现dnspod有这功能
好评啊。
极路由上装个插件更方便..
哇!强大啊,软件官网把那软件也共享了就好啊
@Rices 你写的php类的文章 哪里能看到全部 学xi下~~
很不错有用mark
这个思路很不错。。不过普通的路由能不能自己diy的固件,像内此内置的一样,搞自己的域名解析。。那几家真不稳定,还经常删号。。
花生壳坏掉了。后来玩金万维,都是用别人的三级,现在才知道pod也可以做了
都是路由上直接绑个花生壳,dnspod还真没玩过,学xi了,感谢分享
mark一下,一直想研究一个自己的动态域名
貌似很强大~~你的这个定时任务是依赖于Linux的环境还是win环境就可以了~~
理论上可以设置定时任务的路由基本上都可以这样搞
貌似很强大~~你的这个定时任务是依赖于Linux的环境还是win环境就可以了~~