开发背景:

公司有台嵌入式拨号上网设备,内置busybox和完整wget命令(支持https协议),但没有curl、python、ruby、php等扩展工具可用。网上现有基于DNSPod实现的Linux脚本无法在该设备上运行,于是写了个Shell版动态域名客户端(ddnspod),现在发布出来希望能给需要的朋友带来一些方便。

项目源码:

https://github.com/anrip/ArDNSPod

DnsPod官方文档

https://support.dnspod.cn/Support/api

功能介绍:

  • 优雅的函数封装,灵活的更新策略
  • 基于DNSPod最新用户API实现动态域名客户端
  • 支持基于系统计划任务实现更新,防止脚本意外终止
  • 可运行于多数类unix系统中,包括部分嵌入式小型系统
  • 依赖sed/wget/nslookup命令,wget也可使用curl替代

更新说明:

2015年7月7日

  • 使用D+服务获取域名解析

2013年8月9日

  • 修正一处笔误

2013年8月8日

  • 默认DNS查询服务器更换为114.114.114.114

2013年5月23日

  • [[]]替换为[],防止一些嵌入设备无此命令

2013年4月1日

  • 完善说明文档
  • 优化全局变量定义
  • 刚发现DnsPod官方API示例已收录本文

2013年3月29日

  • 从dns服务器获取子域名IP
  • 实现仅IP变更后才提交更新

2013年3月28日

  • 现在是13年3月,故而第一个版本就定为v3.3吧
  • 使用APIv4.6实现简单的动态更新功能

常见问题:

record line invailid 将脚本保存为utf-8格式即可
Record id invalid 检查账号权限、是否冲突等

标签: shell, linux, dns, 域名

已有 53 条评论

  1. 若海 若海

    若提示 [: not found ,请使用管理员权限运行,或使用 test 语法替代。

    [ "$A" = "$B" ] 等价于 test "$A" = "$B"

  2. 写的不错!

  3. shenzhi shenzhi

    执行这一句wget --quiet --no-check-certificate --output-document=- $inter
    报错:
    Segmentation fault
    如果不加--no-check-certificate,则无错。

    1. 需要wget支持才能获取到远程的url信息,若系统不支持wget,也可以用curl替换。

  4. hostIP: 131.143.134.35 lastIP: 132.225.217.192#53***Can'tfindwww.songweiqi789.tk:Noanswer ./dns1.sh: 50: [: 26: unexpected operator postRS: Record line invalid

    是我的域名出问题了还是别的问题?请直接:qq179834480

    1. [:错误,是系统无命令造成的,尝试使用管理员账号执行或删除[和]命令。参考一楼回复的方法。

  5. hostIP: 116.227.134.146 lastIP: Server:114.114.114.114Address:114.114.114.114#53Non-authoritativeanswer:Name:y36.xchun.netAddress:113.121.42.19 postRS: Record id invalid

    请问为什么会postRS: Record id invalid
    我用的是raspberry pi

    1. 这个是从dns服务器返回当前解析记录出错,请告知你的版子使用的系统信息,我测试下。

  6. surpass_hww surpass_hww

    nslookup y36.xchun.net $dnsvr | tr -d '\n[:blank:]' | sed 's/.+1 ([0-9.]+)/\1/'
    这里的y36.xchun.net是什么意思?是指自己的域名吗?

    1. 是的,换成自己的域名即可

  7. gao_m1 gao_m1

    lastIP: Server:114.114.114.114Address:114.114.114.114#53Non-authoritativeanswer:***Can'tfindlab.xxx.xxxx.com:Noanswer
    后面提示不能找到我的那个域名是什么意思啊??

    1. 应该是无法解析域名造成的

  8. pan pan

    试了下和看了下脚本,好像只能更新子域名?

    另外我两个linux环境,一个成功,另一个始终不成功。。。好奇怪。

    不成功的现象就是无法解析DNS

  9. crazygit crazygit

    感谢楼主的分享,要是代码能放到github上,做成gist就好了,再代码里面加上自己更新代码的语句,那我们就可以及时获取更新了

    1. 可以的,我整理下

  10. neilzhang neilzhang

    非常感谢,在NAS上面部署了,运作很完美!

  11. 检查更新域名

    arDdnsCheck "anrip.com" "lab"
    arDdnsCheck "anrip.net" "lab"
    请问"lab"问题,如解析anrip.com和www.anrip.com, "lab"应该怎么添.
    "lab"替换成”www",www.anrip.com可以正常,但是anrip.com没有被设置到位.
    如添加一行arDdnsCheck "anrip.com" "@"出现lastIP: Server:114.114.114.114Address:114.114.114.114#53Non-authoritativeanswer:***Can'tfind@.anrip.com:Noanswer
    或添加一行arDdnsCheck "anrip.com" "",出现nslookup: '.anrip.com' is not a legal name (unexpected end of input)
    hostIP: xx.xx.xx.xx
    lastIP:

    额外问下,我如添加系统启动,如何做到循环检测,比方说几分钟自动运行循环一遍.
    谢谢大佬了

    1. 目前脚本不支持更新主域名,后续我可以更新下支持。不过,不建议你去更新主域名的IP地址,可以做一条url转向。

      想要循环执行,可以添加一条系统的计划任务,Ubuntu下可以用 crontab -e

  12. dhf dhf

    赞!何不将代码丢到github

  13. Jack Sun Jack Sun

    我的也出现"postRS: Record line invalid" 报错, 请问是怎么回事? 谢谢

    1. 经测试,record line invailid是脚本里中文字符导致的,将脚本保存为utf-8格式即可

  14. astankvai astankvai

    我的出现 line 68: syntax error: Unterminated quoted string.请问这个怎么解?确定代码没有写错。

    1. 修改下文件的编码,或者把中文去掉,或者就是把文件改成使用linux换行

  15. astankvai astankvai

    要么就出现wget: illegal option -- -
    BusyBox V1.12.1
    Usage: wget [-csq] [-O file] [-Y on/off] [-P DIR] [-U agent] url

    ...

    1. 这是 wget 不支持 https 协议造成的,换用 curl 或者编译独立的 wget 可以解决的

  16. 上面所示的项目源码没有执行循环、开机启动等行为吧?
    原谅我不想学shell

  17. 娃娃脾气 娃娃脾气

    如何设置顶级域名?使用“@”好像提示未找到。

  18. 要更新主域名,直接把lab换成空字符串就可以

    1. 雷迅 雷迅

      root@OpenWrt:~# dnspod
      nslookup: can't resolve '.leixunpc.com': Name or service not known
      hostIP: 113.225.147.137
      lastIP: 114.114.114.114 puic1.114ds.com
      postRS: 113.225.147.137
      hostIP: 113.225.147.137
      lastIP: 113.225.147.137

      主域名 换成@ 和空格都有这样的提示

      1. 去掉.试试,因为这个脚本使用的第三方解析服务造成的。

  19. jenkins jenkins

    出错信息Record id invalid 怎么回事呢?

    1. 可能会账号没有权限,冲突

  20. edward edward

    你好 我重新编写了一个适合自己小米路由的版本 但是不知道为什么传上去会显示record line invalid
    已经尝试过utf-8的问题了
    链接: http://pan.baidu.com/s/1sjDU1Wx 密码: m64a

  21. wztx wztx

    你好,请问DNSPOD一个域最多支持动态解析几个域名?

    1. 理论上没有限制

      1. wztx wztx

        好像是超过三个就不行了,我五台设备,最多成功三个

      2. wztx wztx

        不能正常更新的LOG
        Jan 18 03:30:25 admin: 开始更新dnspod 的域名IP指向
        Jan 18 03:30:26 admin: 目前的IP: 106.88.200.95
        Jan 18 03:30:26 admin: 原来的IP: 125.84.13.184
        Jan 18 03:30:27 admin: 提交的IP:

        能正常更新的LOG
        Jan 18 03:31:11 admin: 开始更新dnspod 的域名IP指向
        Jan 18 03:31:11 admin: 目前的IP: 125.84.15.126
        Jan 18 03:31:11 admin: 原来的IP: 14.105.89.225
        Jan 18 03:31:14 admin: 125.84.15.126
        Jan 18 03:31:14 admin: 提交的IP:

  22. shupan shupan

    没有使用说明呀。。我改了ddnspod.sh最后的设置用户参数ermail和erpass为dnspod的账户和密码,然后检查更新域名改成了自己的域名。运行起来有显示hostIP,lastIP不显示。postRS提示Record id invalid 失败了。CentOS 7

    1. 一般情况下,需要检查账号是否错误,域名是否有权限设置。网络是否可达。

  23. shupan shupan

    我想上面的原因可能是因为我在另外一台PC上也登陆了一个dnspodclient客户端导致的。将它停止后没有再报这个错误。

  24. silence silence

    咨询一下:

    复制dns.conf.example到同一目录下的dns.conf并根据你的配置修改即可。

    同一目录下的dns.conf  这句话没明白。(新手不好意思)

  25. dts dts

    感谢!在树莓派Raspbian 上完美工作。

    请教几个问题:1.我发现dnspod.com(国际版)的api和dnspod.cn是一样的,只是地址不同。所以我尝试使用dnspod.com的账户和api,并改动了ddnspod.sh第121行,结果(以账户、密码方式dns.conf):

    Linux hostIP: 116.12.x.x lastIP: postRS: Missing user token, login failed

    查源码,对比中英的api文档也找不到问题所在。我只是个初学者,请教有什么解决办法或者方向么?谢谢

  26. dts dts

    2.dnspod.com没有提供可视化的token生成界面,也得通过api的方式获取。

    https://www.dnspod.com/docs/info.html#get-the-user-token

    可是.sh代码应该怎么写呢……

    1. 请从github上获取更新,支持token

  27. copperfiled copperfiled

    如何把脚本改为直接读取wan口的ip,而不是在网站获取外网ip,因为路由有开ss,经常把ss的外网识别到域名上去,而不是真正的wan口自己拨号的外网ip。

    1. 可以使用 ifconfig 来读取wan口ip,然后使用grep取出来。

  28. shit shit

    admin@CntR6300V2:/jffs/scripts# ./ddnspod.sh
    Linux
    ./ddnspod.sh: line 96: command: not found
    ./ddnspod.sh: line 96: command: not found
    ./ddnspod.sh: line 96: command: not found
    ./ddnspod.sh: line 96: command: not found
    ./ddnspod.sh: line 96: command: not found
    hostIP: 192.168.1.6 192.168.6.1
    lastIP:
    postRS: Record line invalid

    我出现这写问题,我的路由器的上级路由器链接外网

    1. deangelx deangelx

      把 ddnspod.sh 的第96行的

      DIR=$(dirname -- "$(rreadlink "$0")")

      改为 DIR=$(dirname -- "$0") 就可以了

  29. shit shit

    admin@CntR6300V2:/jffs/scripts# ./ddnspod.sh
    Linux
    ddnspod.sh: line 96: command: not found
    ddnspod.sh: line 96: command: not found
    ddnspod.sh: line 96: command: not found
    ddnspod.sh: line 96: command: not found
    ddnspod.sh: line 96: command: not found
    hostIP: 192.168.1.6 192.168.6.1
    lastIP:
    postRS: Record line invalid

    我出现这写问题,我的路由器的上级路由器链接外网

  30. shit23 shit23

    admin@CntR6300V2:/jffs/scripts# ./ddnspod.sh
    Linux
    ddnspod.sh: line 96: command: not found
    ddnspod.sh: line 96: command: not found
    ddnspod.sh: line 96: command: not found
    ddnspod.sh: line 96: command: not found
    ddnspod.sh: line 96: command: not found
    hostIP: 192.168.1.6 192.168.6.1
    lastIP:
    postRS: Record line invalid

    我出现这写问题,我的路由器的上级路由器链接外网

  31. 长城 长城

    你好。我用的路由器启用 DNSPod 域名解析 然后也添加A套餐了。

     

    A套餐的地址是当前ip然后不能我把路由器解析了。A套餐还是显示我当前地址啊。。。

  32. 陈

    为什么我取得是本机IP,不是公网IP,请指教,谢谢

    1. Anakie Anakie

       

      arIpAddress() {

      }

      里面的内容全删掉  ,花括号里只留下面一句

       

      wget -qO - ifconfig.co

      1. ad ad

        获得外网IP了,但是Get Record Info Failed! 高手,还有办法吗

  33. 我用这个更新了ip,怎么设置ttl 目前ttl值是10  需要怎么修改

  34. jack jack

    root@OpenWrt:/usr/lib/ddns# ./ddnspod.sh
    Linux
    ./ddnspod.sh: /usr/lib/ddns/dns.conf: line 1: arToken=***: not found
    ./ddnspod.sh: /usr/lib/ddns/dns.conf: line 2: ip: not found
    ./ddnspod.sh: /usr/lib/ddns/dns.conf: line 2: ip: not found
    Updating Domain: .blocks
    hostIP:
    wget: can't execute 'openssl': No such file or directory
    wget: error getting response: Connection reset by peer
    wget: can't execute 'openssl': No such file or directory
    wget: error getting response: Connection reset by peer
    wget: can't execute 'openssl': No such file or directory
    wget: error getting response: Connection reset by peer
    Get Record Info Failed!
    ./ddnspod.sh: /usr/lib/ddns/dns.conf: line 3: ip: not found
    ./ddnspod.sh: /usr/lib/ddns/dns.conf: line 3: ip: not found
    Updating Domain: *
    hostIP:
    wget: can't execute 'openssl': No such file or directory
    wget: error getting response: Connection reset by peer
    wget: can't execute 'openssl': No such file or directory
    wget: error getting response: Connection reset by peer
    wget: can't execute 'openssl': No such file or directory
    wget: error getting response: Connection reset by peer
    Get Record Info Failed!
    root@OpenWrt:/usr/lib/ddns# wget: can't execute 'openssl': No such file or direc
    tory

    1. jack jack

      在openwrt中安装openssl-util就解决了openssl的问题。

      1. jack jack

        root@OpenWrt:/# /usr/lib/ddns/ddnspod.sh
        Linux
        /usr/lib/ddns/ddnspod.sh: /usr/lib/ddns/dns.conf: line 1: #: not found
        /usr/lib/ddns/ddnspod.sh: /usr/lib/ddns/dns.conf: line 8: ip: not found
        /usr/lib/ddns/ddnspod.sh: /usr/lib/ddns/dns.conf: line 8: ip: not found
        Updating Domain: **
        hostIP:
        Get Record Info Failed!
        新问题
        貌似没有获取IP地址。

      2. 因为dnspod现在是通过https协议请求数据,所以必须使用openssl

        1. ddht ddht

          大神,
          我的centos用openssl version -a,检查了是有openssl的,为什么还是不行。

          1. 主要看是否支持 curl 或者 wget with https

添加新评论