rehiy / dnspod-shell Goto Github PK
View Code? Open in Web Editor NEW基于DNSPod用户API实现的纯Shell动态域名客户端
Home Page: https://www.rehiy.com/post/62/
基于DNSPod用户API实现的纯Shell动态域名客户端
Home Page: https://www.rehiy.com/post/62/
root@cubieboard4:/home/linaro/progranm/ArDNSPod# ./ddnspod.sh
Linux
./ddnspod.sh: 160: local: 192.168.10.116: bad variable name
大哥 最新版 本变量名有问题
我的发型版 如下
root@cubieboard4:/home/linaro/progranm/ArDNSPod# cat /etc/issue
Linaro 14.04 \n \l
root@cubieboard4:/home/linaro/progranm/ArDNSPod# uname -a
Linux cubieboard4 3.4.39 #65 SMP PREEMPT Thu Apr 30 17:25:26 CST 2015 armv7l armv7l armv7l GNU/Linux
测试sh脚本已经没有问题了,然后加入到crontab中,无法更新。在sh脚本中加入测试代码,发现脚本也运行了,就是无法更新地址。
【DNSPod动态域名】: 目前 IP: 222...*
【DNSPod动态域名】: 上次 IP: ...
【DNSPod动态域名】: Record line invalid
【DNSPod动态域名】: 更新动态DNS记录失败!请检查您的网络。提交的IP: 更新记录信息 recordID:
可采用在线获取IP的模式:
V4 URL: http://v4.ip.zxinc.org/getip
V6 URL: http://v6.ip.zxinc.org/getip
2019-11-26
废弃修改资料、修改密码、修改邮箱、获取手机验证码四个用户相关接口
废弃D令牌验证相关参数
Domain.List、Record.List、Domain.Info、Record.Info四个接口新增返回字段
优化 API 调用频次限制,并增加频次说明。
调整了有问题的错误码
停留在这里
估摸着可能是是判断返回的是ip还是错误信息的地方有点问题
arDdnsRecordIp() {
local errMsg
local recordIp
# Get Record Ip
recordIp=$(arDdnsApi "Record.Info" "domain_id=$1&record_id=$2")
recordIp=$(echo $recordIp | sed 's/.*,"value":"\([0-9a-fA-F\.\:]*\)".*/\1/')
# Output Record Ip
case "$recordIp" in
[1-9]*)
echo $recordIp
return 0
;;
*)
errMsg=$(echo $recordIp | sed 's/.*"message":"\([^\"]*\)".*/\1/')
echo "arDdnsRecordIp - $errMsg"
return 1
;;
esac
}
看到很多人依旧在使用这个脚本,但是这个脚本已经历时3年未更新。其中更是使用了 wget 的ssl模块,不知道大家认为是否有必要更改为 curl ?
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
我出现这写问题,我的路由器的上级路由器链接外网
使用云脚本,不用将脚本下载到本地,通过定时wget或者curl一键运行,参数可以在带到命令中而不用修改文件,我今天openwrt更新系统结果下载的脚本没了,然后就连接不上机器了
这个脚本我放在一台NAS设备上来用的,这台设备上面没有nvram这个命令,所以ipv6的地址获取不到,能不能换一个类似获取v4那种方式来获取v6地址呢?我找到一个接口http://v6.ipv6-test.com/api/myip.php,但是我不懂编程,能麻烦你帮忙改一下吗,感谢。另外想知道下这个脚本支不支持同时更新v4和v6的地址?
最近发现脚本刷的ip非常奇怪, ssh上去看了下ip -o -4 addr list
发现有多了一条
9: vethhole inet 253.253.253.253/24 brd 253.253.253.255 scope global vethhole\ valid_lft forever preferred_lft forever
我暂时修改了 grep -Ev '\s(docker|lo|vethhole)'
绕开了,不知有没有遇到过类似情况
Fetching Host Ip
Host Ip: 119.129.XX.XX
Record Type: A
Fetching Ids of XXXXXX.tk
Domain Ids: 86670461 798518213
Checking Record for XXXXXX.tk
Last Ip: arDdnsRecordIp - {"status":{"code":"8","message":"\u8bb0\u5f55\u7f16\u53f7\u9519\u8bef","created_at":"2021-04-24 22:04:23"}}
Fetching Host Ip
Host Ip: 240e:3b4:ce:8360:3408:XXXX:XXXX:d4XX
Record Type: AAAA
Fetching Ids of XXXXXX.tk
Domain Ids: 86670461 798518282
Checking Record for XXXXXXXXd.tk
Last Ip: arDdnsRecordIp - {"status":{"code":"8","message":"\u8bb0\u5f55\u7f16\u53f7\u9519\u8bef","created_at":"2021-04-24 22:04:24"}}
请问是什么问题导致的,应该如何解决?
3Q
ip route命令获取路由器的公网IP:
ip route get 8.8.8.8 | awk '{ print $NF; exit }'
基本上所有路由器都有ip这个命令,这样就可以不用访问第三方的网址获取公网IP。
第三方网址的问题:
#!/bin/sh
#################################################
#################################################
#################################################
#https://www.cnblogs.com/jackadam/p/8192843.html
#https://github.com/anrip/ArDNSPod
#1:必须安装CURL
#opkg --force-depends --force-overwrite install /tmp/libmbedtls_2.14.1-1_arm_cortex-a9.ipk
#opkg --force-depends --force-overwrite install /tmp/ca-bundle_20180409_all.ipk
#opkg --force-depends --force-overwrite install /tmp/libcurl_7.60.0-3_arm_cortex-a9.ipk
#opkg --force-depends --force-overwrite install /tmp/curl_7.60.0-3_arm_cortex-a9.ipk
#或者安装支持HTTPS的完整WGET
#2:拷贝ddnspod.sh和ddnspod.conf到相应的目录,并设置权限为777
#3:在/etc/ppp/ip-up.d目录新建一个文件autoddns.sh,权限0755,内容如下:
#只要wan口发生变化,就会执行脚本去DNSpod更新A记录的IP。
#简单测试一下:/etc/init.d/network restart
#################################################
case $(uname) in
'Linux')
echo "Linux"
A() {
local extip
extip=$(ip -o -4 addr list | grep -Ev '\s(docker|lo)' | awk '{print
if [ "x${extip}" = "x" ]; then
extip=$(ip -o -4 addr list | grep -Ev '\s(docker|lo)' | awk '{print $4}' | cut -d/ -f1 )
fi
echo $extip
}
getIPv6() {
local extip
extip=ip addr show ${ipv6ethName} | grep inet6 | awk '{print $2}' |grep ^${ipv6prefix} | grep '/64$' | sed 's/\/.*//g'
echo $extip
#ip addr show dev ${ipv6ethName} | sed -e's/^.inet6 ([^ ])/.*$/\1/;t;d'
#如果没有nvram,使用这条,注意将eth0改为本机上的网口设备(通过 ifconfig 查看网络接口)
}
# 获得外网ipv6地址
AAAA() {
local hostIP_v6=$(getIPv6)
while [[ -z $hostIP_v6 ]]
do
sleep 60
hostIP_v6=$(getIPv6)
done
echo $hostIP_v6
}
;;
*) ;;
esac
rreadlink() ( # Execute the function in a subshell to localize variables and the effect of cd
.
target=$1 fname= targetDir= CDPATH=
command
, so we must make sure that command
command
is a builtin in bash, dash, ksh, zsh, and some platforms do not even havecommand
bypasses aliases and shell functions and also finds builtins{ \unalias command; \unset -f command; } >/dev/null 2>&1
[ -n "$ZSH_VERSION" ] && options[POSIX_BUILTINS]=on # make zsh find builtins with command
too.
while :; do # Resolve potential symlinks until the ultimate target is found.
[ -L "$target" ] || [ -e "$target" ] || { command printf '%s\n' "ERROR: '$target' does not exist." >&2; return 1; }
command cd "$(command dirname -- "$target")" # Change to target dir; necessary for correct resolution of target path.
fname=$(command basename -- "$target") # Extract filename.
[ "$fname" = '/' ] && fname='' # !! curiously, basename /
returns '/'
if [ -L "$fname" ]; then
# Extract [next] target path, which may be defined
# relative to the symlink's own directory.
# Note: We parse ls -l
output to find the symlink target
# which is the only POSIX-compliant, albeit somewhat fragile, way.
target=$(command ls -l "$fname")
target=${target#* -> }
continue # Resolve [next] symlink target.
fi
break # Ultimate target reached.
done
targetDir=$(command pwd -P) # Get canonical dir. path
if [ "$fname" = '.' ]; then
command printf '%s\n' "${targetDir%/}"
elif [ "$fname" = '..' ]; then
# Caveat: something like /var/.. will resolve to /private (assuming /var@ -> /private/var), i.e. the '..' is applied
# AFTER canonicalization.
command printf '%s\n' "$(command dirname -- "${targetDir}")"
else
command printf '%s\n' "${targetDir%/}/$fname"
fi
)
DIR=$(dirname -- "$(rreadlink "$0")")
arToken=""
arMail=""
arPass=""
ipv6ethName=""
ipv6prefix=""
#. $DIR/ddnspod.conf
arDdnsInfo() {
recordType=$3
# Get domain ID
domainID=$(arApiPost "Domain.Info" "domain=${1}")
domainID=$(echo $domainID | sed 's/.{"id":"([0-9])".*/\1/')
# Get Record ID
recordID=$(arApiPost "Record.List" "domain_id=${domainID}&sub_domain=${2}&record_type=${recordType}")
recordID=$(echo $recordID | sed 's/.*\[{"id":"\([0-9]*\)".*/\1/')
# Last IP
recordIP=$(arApiPost "Record.Info" "domain_id=${domainID}&record_id=${recordID}&record_type=${recordType}")
recordIP=$(echo $recordIP | sed 's/.*,"value":"\([0-9a-z\.:]*\)".*/\1/')
# Output IP
case "$recordIP" in
[0-9a-z]*)
echo $recordIP
return 0
;;
*)
echo "Get Record Info Failed,Please Install wget/curl or check your network or check domain/sub domain."
return 1
;;
esac
}
arApiPost() {
local agent="AnripDdns/5.07([email protected])"
local inter="https://dnsapi.cn/${1:?'Info.Version'}"
if [ "x${arToken}" = "x" ]; then # undefine token
local param="login_email=${arMail}&login_password=${arPass}&format=json&${2}"
else
local param="login_token=${arToken}&format=json&${2}"
fi
if [ -n "`opkg list-installed | grep curl | sed 's/[[:space:]]//g'`" ];then #if install curl
curl -k -X POST $inter -d "$param"
elif [ -n "`opkg list-installed | grep wget | sed 's/[[:space:]]//g'`" ];then #if install wget
wget --quiet --no-check-certificate --output-document=- --user-agent=$agent --post-data $param $inter
else
echo "Please run 'opkg install wget' or 'opkg install curl'!"
fi
}
arDdnsUpdate() {
local domainID recordID recordRS recordCD recordIP myIP recordType
recordType=$4
# Get domain ID
domainID=$(arApiPost "Domain.Info" "domain=${1}")
domainID=$(echo $domainID | sed 's/.*{"id":"\([0-9]*\)".*/\1/')
# Get Record ID
recordID=$(arApiPost "Record.List" "domain_id=${domainID}&sub_domain=${2}&record_type=${recordType}")
recordID=$(echo $recordID | sed 's/.*\[{"id":"\([0-9]*\)".*/\1/')
# Update IP
myIP=$3
recordRS=$(arApiPost "Record.Modify" "domain_id=${domainID}&sub_domain=${2}&record_type=${recordType}&record_id=${recordID}&record_line=%e9%bb%98%e8%ae%a4&value=${myIP}")
recordCD=$(echo $recordRS | sed 's/.*{"code":"\([0-9]*\)".*/\1/')
recordIP=$(echo $recordRS | sed 's/.*,"value":"\([0-9a-z\.:]*\)".*/\1/')
# Output IP
if [ "$recordIP" = "$myIP" ]; then
if [ "$recordCD" = "1" ]; then
echo $recordIP
return 0
fi
# Echo error message
echo $recordRS | sed 's/.*,"message":"\([^"]*\)".*/\1/'
return 1
else
echo "Update Failed! Please check your network."
return 1
fi
}
arDdnsCheck() {
if [ "x${3}" = "x" ]; then
recordType='A'
else
recordType=$3
fi
hostIP=$(${recordType})
echo "----------------------------------------"
echo "$(date "+%Y-%m-%d %H:%M:%S") Updating Domain: ${2}.${1} to ${hostIP}(${recordType})"
lastIP=$(arDdnsInfo $1 $2 $recordType)
if [ $? -eq 0 ]; then
echo "$(date "+%Y-%m-%d %H:%M:%S") lastIP: ${lastIP}"
if [ "$lastIP" != "$hostIP" ]; then
postRS=$(arDdnsUpdate $1 $2 $hostIP $recordType)
if [ $? -eq 0 ]; then
echo "$(date "+%Y-%m-%d %H:%M:%S") postRS: ${postRS}"
return 0
else
echo ${postRS}
return 1
fi
fi
echo "Last IP is the same as current IP!"
return 1
fi
echo ${lastIP}
return 1
}
#echo ${#domains[@]}
#for index in ${!domains[@]}; do
#done
. $DIR/ddnspod.conf
-----------ddnspod.conf-------------------
arToken="XXXXX,XXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
ipv6ethName="pppoe-wan"
ipv6prefix="2409" #**移动IPV6前辍
arDdnsCheck "xxxxx.cn" "ipv4" #IPV4
arDdnsCheck "xxxxx.cn" "ipv6" "AAAA" #IPV6
dnspod已被腾讯云收购整合完全了,无法进入控制台了,请更新兼容腾讯云,谢谢
root@raspbian:/home/pi/ddns# ./ddnspod.sh
Type: A
OS: Linux
Address: 115.221.12.117
Updating Domain: .Timcc.xyz
hostIP: 115.221.12.117
Get Record Info Failed!
Linux
hostIP: 119.129.xxx.xxx
lastIP:
postRS: 119.129.xxx.xxx
像这样,相同的IP也推上去
I saw you use a script name "rreadlink" to get the current path of ddnspod.sh.
But why not use $PWD instead of this? $PWD is built in the bash so both Linux and Mac are supported it.
如题:
if [ "$recordIp" == "$4" ] && [ "$recordCd" == "1" ]; then
改成
if [ "$recordIp" = "$4" ] && [ "$recordCd" = "1" ]; then
if [ "$3" == "6" ]; then
修改
if [ "$3" = "6" ]; then
if [ "$lastIp" == "$hostIp" ]; then
改成
if [ "$lastIp" = "$hostIp" ]; then
Base on LEDE/OpenWrt (18.12, r4592, 2018-12-13-git-a1945fb)
Linux
Updating Domain: myDomain
hostIP: *.210.157.95 *.210.157.4 *.210.157.124
lastIP: *.210.157.124
Update Failed! Please check your network.
多拨用户,不知道有没有影响。
麻烦指导一下,谢谢!
如题,为何要通过第三方获取ip地址,如果members.3322.org这个网址挂了怎么办
x-wrt路由上提示 Error relocating /usr/bin/wget: ENGINE_load_builtin_engines: symbol not found
确认sh脚本及dns.conf文件 的编码为utf8
手动运行ddnspod.sh 提示
admin@R7000-56A2:/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: 169.254.53.112 123.117.202.xx
lastIP:
postRS: Record line invalid
目测是由于获取到两个hostIP,第一个好像是个私有ip。
不知道如何解决,等待您的回复,谢谢!
试一下,看到更新上去的是 ipv4 的址址,如果使用才能只把 ipv6 更新到 DDNS 中
域名 *.example.com 需要添加 多个 IP,要怎么设置?
如果要分线路的话又要怎么设置?
arDdnsCheck "test.org" "mail"
执行不成功呢 报错postRS: Record line invalid
2020年02月06日DNSPod API 升级 这次更新是否需要适配?
syntax error: unexpected word (expecting "in") ?
why this?
我用padavan配置,尝试用wget和直接复制的办法,都遇到这个问题
dnspod.cn如果要对同一个子域名解析多个A记录,或者AAAA记录,服务端就要将子域名配置多条解析记录,API更新参数中只有子域名subdomain的话,只能更新服务端该子域名的首条解析记录,无法对首条后的记录进行更新。
举个例子,在服务端配置两条主机记录test,第一条为A记录,第二条为AAAA记录,API提交记录更新只带上subdomain=test的话,只能更新服务器的A记录,无法更新第二条AAAA记录。如果API带上record_id参数,API提交record_id="第二条记录的ID”,就可以指定更新第二条AAAA记录。
这样运行两条脚本,就能实现IPV4/IPV6双栈动态解析,也可以一个域名记录指定多个IPV4地址,实现域名负载均衡(DNSPOD支持IPV4的负载均衡)
我的网卡有 10.16.0.0 IP,有公网IP,可是这个脚本居然只获得了 10.16 开头的IP。
https://github.com/anrip/ArDNSPod/blob/master/ddnspod.sh#L112
By this, seems you cannot check your last ip and caused the script update every time? do you plan to fix this?
在macOS下sed 还是有些问题 加以 brew install gnu-sed 然后把脚本里的所有sed改为gsed
macOS下ip指令需要brew install iproute2mac。才能使用
macos在更新Ipv6地址时 脚本第86行有问题,默认获取的是ipv4地址导致的错误如下:
echo "Mac" arIpAddress() { #ifconfig | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}'#默认获取了ipv4地址 ip addr show dev en0 | gsed '/fe80/d' | gsed -e's/^.*inet6 \([^ ]*\)\/.*$/\1/;t;d'| awk 'NR==1' }
arWanIp 获取到了两个ip,导致更新到api接口失败。
最好是在获取ip之后对ip做个判断。如果你的lanIp获取有问题时候,执行下边的3322接口取ip
root@SAF:/etc/apps/ddns/dnspod# ./dnspod.sh
Updating Domain: sz-hs8145v..tk
Host Ip: 11.42.63.150 113.116.182.118
lastIP: 183.15.178.204
Host Ip^C
root@SAF:/etc/apps/ddns/dnspod# ./dnspod.sh
Updating Domain: sz-hs8145v..tk
Host Ip: 113.116.182.118
lastIP: 183.15.178.204
postRs: 113.116.182.118
可以在入口加个传参,不检索网卡ip,或者可以自己指定网卡名称过滤ip。
像路由器或者光猫这类,带拨号的,肯定会有多个ip,不一定是内网ip。有些双wan拨号。
openwrt 拨号网卡 ppp259
您好,我在使用您的脚本时,发现无论如何都显示 Get Record Info Failed!
于是查看源码,注意到了在 127 行的判断
# Output IP
case "$recordIP" in
[1-9][0-9]*) #我的远端设置是 0.0.0.0 ,大概是这个原因所以没有进入这个逻辑,我修改为 [0-9]* 就好了
echo $recordIP
return 0
;;
*)
echo "Get Record Info Failed!"
return 1
;;
esac
我对 shell 不熟悉,希望您能改善一下这个判断。
求助crontab命令怎么写,我 */5 * * * * /root/ddnspod.sh 每5分钟执行行一此,无效
root@OpenWrt:~/ArDNSPod# ./ddnspod.sh
Updating Domain: x.yz.com
hostIP: 49.171.63.47
lastIP: 49.171.63.147
wget: bad address 'completed'
wget: bad address 'completed'
Update Failed! Please check your network.
on Netgear R7000 & Merlin 380.57_X6.5
error message are below:
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: xxx.xxx.xxx.xxx
lastIP:
postRS:xxx.xxx.xxx.xxx
dnspodapi接口有改变,导致提取Domain id 失败
修改这句话
domainID=$(echo $domainID | sed 's/.{"id":"([0-9])"./\1/')
为
domainID=$(echo $domainID | sed 's/.,"id":"([0-9])"./\1/')
就可完美解决。
解析 直接解析主域名 @ 的A记录 报错
更新时@和其他域名都可以更新,唯独*的通配符更新失败
能不能帮忙看一下是什么问题呢?
如果我要更新test.baidu.com,配置文件里是不是应该写
arDdnsCheck "baidu.com" "test"
这样?
I use this script on my NAS server. And I use a task scheduler to execute it every 10 min.
When the script return 1
as a "Error Return", the NAS server will send me an e-mail to tell me "Hey, your script failed".
BUT , "the current IP same as last IP" is quite a normal thing. So it's more reasonable to return 0
as a successful return.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.