主页 > 原创 | 整理 | 学习笔记 > ddwrt路由/linux动态解析ip(ddns)到dnspod配置

ddwrt路由/linux动态解析ip(ddns)到dnspod配置

dnspod域名解析服务有提供出来api,可以通过curl命令与dnspod交互。需要在dnspod先绑定一个域名,并设置一个二级域名(A记录),如我的test.xdty.org指向到了127.0.0.1。而dnspod对动态域名的解析相同ip有一小时5次的限制,所以我只在ip改变后才会更新dns的解析。
使用busybox的ash解析sh脚本,内容如下:

1.保存脚本dnspod.sh和dnspod.conf到ddwrt /jffs/ddns路径下
可自行定义路径,但要保证在重启后还在。
使用ssh或putty登陆到路由后,运行如下命令

cd /jffs
mkdir ddns
cd ddns
curl -k -s https://raw.githubusercontent.com/xdtianyu/scripts/master/ddns/dnspod.sh >dnspod.sh
chmod +x dnspod.sh
curl -k -s https://raw.githubusercontent.com/xdtianyu/scripts/master/ddns/dnspod.conf >dnspod.conf

修改dnspod.conf配置文件,其中domain为二级域名,account为dnspod的登陆邮箱,password为登陆密码。整个调用过程使用https加密post传输,不需要担心密码泄露。(我觉得dnspod直接使用密码做api调用没有namesilo的api key做的好)
2.本地运行
在命令行运行如下命令即可

./dnspod.sh dnspod.conf

由于使用了nslookup验证动态ip是否已经更新,所以可能需要30秒左右时间,稍等片刻。命令正常退出后可以登陆dnspod查看是不是已经成功更新了。
3.添加cron任务
在ddwrt web管理面板里 Cron 附加任务 添加如下内容即可

*/3 * * * * root /jffs/ddns/dnspod.sh /jffs/ddns/dnspod.conf

即每隔3分钟检验一次,如果ip有变动,脚本会运行更新。

附脚本内容如下:
dnspod.sh文件

#!/bin/sh
# usage: ./dnspod.sh ddns.conf

ACCOUNT=""
PASSWORD=""
DOMAIN=""
SUBDOMAIN=""
RECORD_LINE=""

DOMAIN_ID=""
RECORD_LIST=""

i=0;

dnspod_load_config(){
  cfg=$1;
 content=`cat ${cfg}`;
 ACCOUNT=`echo "${content}" |grep 'ACCOUNT'| sed 's/^ACCOUNT=["]\(.*\)["]/\1/'`;
  PASSWORD=`echo "${content}" |grep 'PASSWORD'| sed 's/^PASSWORD=["]\(.*\)["]/\1/'`;
 DOMAIN=`echo "${content}" |grep 'DOMAIN='| sed 's/^DOMAIN=["]\(.*\)["]/\1/'`;
  RECORD_LINE=`echo "${content}" |grep 'RECORD_LINE'| sed 's/^RECORD_LINE=["]\(.*\)["]/\1/'`;
    SUBDOMAIN=${DOMAIN%%.*}
    DOMAIN=${DOMAIN#*.}
}

dnspod_is_record_updated(){
    #resolve_ip=$(nslookup $SUBDOMAIN.$DOMAIN | tail -2 |grep Add | awk '{print $NF}')
    resolve_ip=$(curl -s -k https://www.xdty.org/resolve.php -X POST -d "domain=$SUBDOMAIN.$DOMAIN")
    current_ip=$(curl -s icanhazip.com)
    echo $resolve_ip $current_ip
    if [ "$resolve_ip" = "$current_ip" ]; then
        echo "Record updated."
        exit 0;
    fi
}

dnspod_domain_get_id(){
  options="login_email=${ACCOUNT}&login_password=${PASSWORD}";
  out=$(curl -s -k https://dnsapi.cn/Domain.List -d ${options});
    for line in $out;do
        if [ $(echo $line|grep '<id>' |wc -l) != 0 ];then
            DOMAIN_ID=${line%<*};
            DOMAIN_ID=${DOMAIN_ID#*>};
            #echo "domain id: $DOMAIN_ID";
        fi
        if [ $(echo $line|grep '<name>' |wc -l) != 0 ];then
            DOMAIN_NAME=${line%<*};
            DOMAIN_NAME=${DOMAIN_NAME#*>};
            #echo "domain name: $DOMAIN_NAME";
            if [ "$DOMAIN_NAME" = "$DOMAIN" ];then
               break;
            fi
        fi
    done
  out=$(curl -s -k https://dnsapi.cn/Record.List -d "${options}&domain_id=${DOMAIN_ID}")
    for line in $out;do
        if [ $(echo $line|grep '<id>' |wc -l) != 0 ];then
            RECORD_ID=${line%<*};
            RECORD_ID=${RECORD_ID#*>};
            #echo "record id: $RECORD_ID";
        fi
        if [ $(echo $line|grep '<name>' |wc -l) != 0 ];then
            RECORD_NAME=${line%<*};
            RECORD_NAME=${RECORD_NAME#*>};
            #echo "record name: $RECORD_NAME";
            if [ "$RECORD_NAME" = "$SUBDOMAIN" ];then
               break;
            fi
        fi
    done
    echo "$RECORD_NAME:$RECORD_ID"
}

dnspod_update_record_ip(){
  curl -k https://dnsapi.cn/Record.Ddns -d "login_email=${ACCOUNT}&login_password=${PASSWORD}&domain_id=${DOMAIN_ID}&record_id=${RECORD_ID}&sub_domain=${RECORD_NAME}&record_line=${RECORD_LINE}"
}

main(){

 dnspod_load_config $1
    dnspod_is_record_updated
 dnspod_domain_get_id
  dnspod_update_record_ip
}

main $1

dnspod.conf文件

ACCOUNT="xxxxxx@gmail.com"
PASSWORD="xxxxxxxxxx"
DOMAIN="xxxx.xxx.org"
RECORD_LINE="默认"

Tags: bash busybox ddns ddwrt dnspod dns解析 linux sh ubuntu

评论:19

  1. weking 回复
    2014 年 12 月 17 日 于 下午 12:38

    你好,我设置好之后运行,出现以下错误,但我登录信息没有错误,是什么原因呢?

    -1

    2014-12-17 12:34:23

    • tianyu 回复
      2014 年 12 月 17 日 于 下午 1:01

      有没有更详细点的错误信息?

  2. weking 回复
    2014 年 12 月 17 日 于 下午 12:39

    你好,我设置好之后运行,出现以下错误,但我登录信息没有错误,是什么原因呢?
    [CDATA[Login fail, please check login info]]

    • tianyu 回复
      2014 年 12 月 17 日 于 下午 1:04

      检查下DNSPOD的用户名密码是否正确吧,或者参数是不是在哪里传错了

    • tianyu 回复
      2014 年 12 月 17 日 于 下午 1:08

      在dnspod_update_record_ip里增加

      echo "login_email=${ACCOUNT}&login_password=${PASSWORD}&domain_id=${DOMAIN_ID}&record_id=${RECORD_ID}&sub_domain=${RECORD_NAME}&record_line=${RECORD_LINE}"

      看看和conf里的输出是不是一致的

      • weking 回复
        2014 年 12 月 17 日 于 下午 11:39

        添加之后检查输出信息,和conf是一样的。帐密绝对没有输错~

        • caca 回复
          2018 年 12 月 15 日 于 下午 5:24

          我也碰到这样的问题,用户名密码正确,但就是登陆不了

  3. abc 回复
    2015 年 1 月 8 日 于 下午 9:33

    我运行 ./dnspod.sh dnspod.conf 出现 /bin/sh: eval: line 1: ./dnspod.sh: not found 是什么问题

    • tianyu 回复
      2015 年 1 月 9 日 于 下午 1:19

      看看当前目录有没有这个文件,查下为什么没有

  4. hj 回复
    2015 年 1 月 11 日 于 下午 9:33

    root@R7000:/jffs# sh

    BusyBox v1.22.1 (2014-10-08 23:11:55 CEST) built-in shell (ash)
    Enter ‘help’ for a list of built-in commands.

    怎么我的 DD WRT 不能执行 SHELL Script 啊?

    • tianyu 回复
      2015 年 1 月 11 日 于 下午 9:38

      你是怎么执行的脚本?用的什么固件?我ac68u也是busybox的ash,可以执行sh脚本的
      root@route:~# sh

      BusyBox v1.22.1 (2014-06-13 22:06:50 CEST) built-in shell (ash)
      Enter ‘help’ for a list of built-in commands.

      • hj 回复
        2015 年 1 月 11 日 于 下午 9:49

        使用你的 sh 没问题,可能我刚另外找的 sh 有语法错误。
        多谢你!打扰你了。

  5. Peter 回复
    2015 年 7 月 5 日 于 上午 10:25

    ./dnspod.sh dnspod.conf 这个之后我得到
    -sh: ./dnspod.sh: Permission denied

    • tianyu 回复
      2015 年 7 月 5 日 于 上午 10:32

      “chmod +x dnspod.sh” 运行了没有?

    • Peter 回复
      2015 年 7 月 5 日 于 上午 11:03

      好了。 现在的问题是 我这还没有curl。我怎么安装?

  6. T先生 回复
    2018 年 3 月 30 日 于 下午 11:36

    您好,一直使用您的脚本,非常好用,但是最近无法收到谷歌邮件了,请问是您取消了吗?能否把「https://www.xdty.org/mail.php」开源呢?谢谢!

  7. CKS 回复
    2018 年 4 月 8 日 于 下午 4:59

    dnspod_is_record_updated(){
    resolve_ip=$(nslookup XXX.XXX.XX | awk ‘END {print}’ | awk ‘{print $NF}’)
    current_ip=$(curl -s ip.xdty.org)
    echo $resolve_ip
    echo $current_ip
    if [ “$resolve_ip” = “$current_ip” ]; then
    echo “Record updated.”
    exit 0;
    fi
    }
    XXX换成自己的域名
    我把楼主的shell 中dnspod_is_record_updated 修改了下 不知道是我的问题还是楼主的问题 原来的dnspod_is_record_updated2 中的 resolve_ip 老是取不到正确的IP 导致频繁更新IP 被封,而且用dnspod 频繁获取(3分钟)域名IP作比较也容易被封,我就用了nslookup。感谢楼主的脚本。

发表评论

邮箱地址不会被公开。 必填项已用*标注