-
-
Save bigeagle/1892634 to your computer and use it in GitHub Desktop.
在bash中使用DNSPod的API接口实现DDNS客户端
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
############################## | |
# dnspodsh | |
# 基于dnspod api构架的bash ddns客户端 | |
# 作者:zrong(zengrong.net) | |
# 日期:2012-02-13 | |
############################## | |
login_email=${1:?'必须提供登录名'} | |
login_password=${2:?'必须提供密码'} | |
format="json" | |
lang="en" | |
userAgent="dnspodsh/0.1([email protected])" | |
commonPost="login_email=$login_email&login_password=$login_password&format=$format&lang=$lang" | |
apiUrl='https://dnsapi.cn/' | |
ipUrl='http://members.3322.org/dyndns/getip' | |
# 要处理的域名 | |
domainName='yourname.net' | |
# 要处理的子域名 | |
recordName='www' | |
# 搜索到的子域名的信息 | |
record='初始值' | |
# 多长时间比较一次ip地址 | |
delay=300 | |
# logfile | |
logFile=/var/log/dnspodsh.log | |
getUrl() | |
{ | |
curl -s -A $userAgent -d $commonPost$2 --trace trace.txt $apiUrl$1 | |
} | |
getVersion() | |
{ | |
getUrl "Info.Version" | |
} | |
getUserDetail() | |
{ | |
getUrl "User.Detail" | |
} | |
writeLog() | |
{ | |
local pre=`date` | |
for arg in $@;do | |
pre=$pre'\t'$arg | |
done | |
echo -e $pre>>$logFile | |
} | |
getDomainList() | |
{ | |
getUrl "Domain.List" "&type=all&offset=0&length=10" | |
} | |
# 根据域名id获取记录列表 | |
# $1 域名id | |
getRecordList() | |
{ | |
getUrl "Record.List" "&domain_id=$1&offset=0&length=20" | |
} | |
# 设置记录 | |
setRecord() | |
{ | |
writeLog '设置新记录' | |
getUrl 'Record.Modify' "&domain_id=$domainid&record_id=$recordid&sub_domain=$recordName&record_type=$recordtype&record_line=$recordline&ttl=$recordttl&value=$newip" | |
sleep 10 | |
# 再次通过dnspod的api获取最新的数据 | |
getInitValue | |
} | |
# 通过key得到找到一个JSON对象字符串中的值 | |
getDataByKey() | |
{ | |
local s='s/{[^}]*"'$2'":["]*\('$(getRegexp $2)'\)["]*[^}]*}/\1/' | |
#echo '拼合成的regexp:'$s | |
echo $1|sed $s | |
} | |
# 根据key返回要获取的正则表达式 | |
getRegexp() | |
{ | |
case $1 in | |
'value') echo '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}';; | |
'type') echo '[A-Z]\+';; | |
'name') echo '[-_.A-Za-z]\+';; | |
'ttl'|'id') echo '[0-9]\+';; | |
'line') echo '[^"]\+';; | |
esac | |
} | |
# 通过一个JSON key名称,获取一个{}包围的JSON对象字符串 | |
# $1 要搜索的key名称 | |
# $2 要搜索的对应值 | |
getJSONObjByKey() | |
{ | |
grep -o '{[^}{]*"'$1'":"'$2'"[^}]*}' | |
} | |
# 获取返回代码是否正确,任何情况下,如果碰到这个代码错误,就停止程序。因为dnspod在代码错误过多的情况下会封禁账号 | |
checkStatusCode() | |
{ | |
if [ "echo $1|grep '{"status":{[^}{]*"code":"1"[^}]*}'" ];then | |
return 0 | |
fi | |
writeLog 'DNSPOD返回错误:'$1 | |
exit 1 | |
} | |
getInitValue() | |
{ | |
domainList=$(getDomainList) | |
checkStatusCode "$domainList" | |
# 从dnspod获取要设置的域名的信息 | |
domainInfo=$(echo $domainList|getJSONObjByKey 'name' $domainName) | |
# 获取域名的id | |
domainid=$(getDataByKey "$domainInfo" 'id') | |
recordList=$(getRecordList $domainid) | |
checkStatusCode "$recordList" | |
# 从dnspod获取要设置的子域名记录的信息 | |
recordInfo=$(echo $recordList|getJSONObjByKey 'name' $recordName) | |
recordid=$(getDataByKey "$recordInfo" 'id') | |
recordttl=$(getDataByKey "$recordInfo" 'ttl') | |
recordtype=$(getDataByKey "$recordInfo" 'type') | |
#recordline=$(getDataByKey "$recordInfo" 'line') | |
# 由于从服务器获取的线路是utf编码,目前无法知道如何转换成中文,因此在这里写死。dnspod中免费用户的默认线路的名称就是“默认” | |
recordline='默认' | |
# 从dnspod获取要设置的子域名的ip | |
oldip=$(getDataByKey "$recordInfo" 'value') | |
writeLog '初始化数据' | |
} | |
getInitValue | |
if [ -z $oldip ];then | |
writeLog '无法取得旧ip,退出程序' | |
exit 1 | |
fi | |
while [ 1 ];do | |
# 由于获取到的数据多了一些多余的字符,所以提取ip地址的部分 | |
# 从api中获取当前的外网ip | |
newip=$(curl -s $ipUrl|grep -o $(getRegexp 'value')) | |
# 如果取值错误,就继续等待下一次取值 | |
if [ -z $newip ];then | |
writeLog '取值错误:'$newip | |
sleep $delay | |
continue | |
fi | |
writeLog 'newip:'$newip 'oldip:'$oldip | |
if [ "$newip" != "$oldip" ];then | |
setRecord | |
fi | |
sleep $delay | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment