EdgeRouter 配置 dnspod 动态域名更新
作者:mostone测试路由器:UBNT EdgeRouter ER-X
路由器系统:EdgeRouter X v1.9.1.1
使用 Shell 脚本,配置为 pppoe 建立连接后被调用。
系统的 /etc/ppp/ip-up 脚本,会在 pppoe 连接建立后执行,并搜索 /config/scripts/ppp/ip-up.d/ 目录,执行目录下的所有脚本文件。
其中 /config/scripts 是路由器默认的配置目录,如果更新路由器固件,并不会删除其中的文件。
这款路由器支持 ssh 远程登录,可以使用 sftp 上传文件,放到 /config/scripts/ppp/ip-up.d/ 目录下即可,如果目录不存在,先建立目录层级。
脚本文件以下面方式运行(脚本文件名可以任意更改):
(注:在使用之前,需要修改文件,设置正确的 ACCESS_TOKEN。参考:https://support.dnspod.cn/Kb/showarticle/tsid/227/)
1.$> /config/scripts/ppp/ip-up.d/ddnspod.sh -q mydomain.com www
这用来查询 mydomain.com 在平台上的 domainId, www 的 recordId
2. $> /config/scripts/ppp/ip-up.d/ddnspod.sh --test 1111 2222 www 0 10.1.1.1
这用来提交测试的 IP 地址, 1111 为上面取得的 domainId,2222 为上面取得的 recordId,www 为子域名(可以用 @ 来更新主域名),0 为 record_line_id,最后是要提交的新 IP 地址。
record_line_id,如果是默认线路,值为 0,更多的可选值请参考:https://www.dnspod.cn/docs/domains.html#record-line
"line_ids": {
"默认": 0,
"国内": "7=0",
"国外": "3=0",
"电信": "10=0",
"联通": "10=1",
"教育网": "10=2",
"移动": "10=3",
"百度": "90=0",
"谷歌": "90=1",
"搜搜": "90=4",
"有道": "90=2",
"必应": "90=3",
"搜狗": "90=5",
"奇虎": "90=6",
"搜索引擎": "80=0"
} 提交的线路 id 值应该与你的设置保持一致。
如果 id 值中含有等号,请将 '=' 换成 '%3D',进行转义,如 "7%3D0"
3. 路由器重新建立 pppoe 连接时,自动被调用执行
这种方式使用,需要修改文件的最后一行,设置由上面第一种方式取得的 domainId 和 recordId,如果有多个域名要更新,复制为多行,并修改相应的 domainId, recordId 即可。
可以在 /var/log/ppp.log 中查看最后一次记录消息
ddnspod-ubnt.sh 代码:
#!/bin/sh
#################################################
# MosDdns for EdgeRouter X v1.0
# Dynamic DNS using DNSPod API
# Original by mostone<mostone@hotmail.com>, http://www.anrip.com/ddnspod
# Tested on EdgeRouter X v1.9.1.1
#################################################
# Usage:
#step 1. Set accessToken value at bellow.
#step 2. Input command in Shell: ddnspod-ubnt.sh -p domainName subdomainName
# this command will print domainId and recordId.
#step 3. Add updateDdns function call in the last of this file, replace your
# real domainId and recordId which get from step 1.
#step 4. copy this shell script file to ubnt router.
# path: /config/scripts/ppp/ip-up.d/
# this file will be call by /etc/ppp/ip-up.
#
#Done.
# Global Variables:
# Combine your token Id and token together as follows
ACCESS_TOKEN="11111,exxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx4"
IS_PPP_UP=1
if [ -z $PPP_LOCAL ]; then
IS_PPP_UP=0
fi
showMsg() {
echo $1
if [ $IS_PPP_UP -eq 1 ]; then
echo $1 >> /var/log/ppp.log
fi
}
# arguments: apiInterface postParameters
callApi() {
local agent="MosDdns/1.0(mostone@hotmail.com)"
local url="https://dnsapi.cn/${1:?'Info.Version'}"
local params="login_token=${ACCESS_TOKEN}&format=json&${2}"
curl --silent --request POST --user-agent $agent $url --data $params
}
# arguments: domainName subdomainName
printDomainAndRecordIds() {
local response domainId recordId lastIp
# Get domain Id
response=$(callApi "Domain.Info" "domain=${1}")
# echo "Domain.Info call respone: ${response}"
domainId=$(echo $response | sed 's/.*{"id":"\(*\)".*/\1/')
echo " Domain[${1}] Id is: ${domainId}"
# Get Record Id
response=$(callApi "Record.List" "domain_id=${domainId}&sub_domain=${2}")
# echo "Record.List call respone: ${response}"
recordId=$(echo $response | sed 's/.*\[{"id":"\(*\)".*/\1/')
echo " Record[${2}] Id is: ${recordId}"
# Print last Ip
lastIp=$(echo $response | sed 's/.*,"value":"\(*\)".*/\1/')
echo " Server side last Ip: ${lastIp}"
}
# arguments: domainId recordId
getLastIp() {
local response lastIp
# get last Ip
response=$(callApi "Record.Info" "domain_id=${1}&record_id=${2}")
lastIp=$(echo $response | sed 's/.*,"value":"\(*\)".*/\1/')
# validate Ip
case "$lastIp" in
*)
echo $lastIp
return 0
;;
*)
echo $response | sed 's/.*,"message":"\([^"]*\)".*/\1/'
return 1
;;
esac
}
# arguments: domainId recordId subdomainName lineId newIp
updateDdns() {
local response returnCode recordIp lastIp
# get last Ip
lastIp=$(getLastIp $1 $2)
if [ $? -eq 1 ]; then
showMsg $lastIp
return 1
fi
# same Ip check
if [ "$lastIp" = "$5" ]; then
showMsg "Server side last Ip is the same as current local Ip!"
return 1
fi
# update Ip
response=$(callApi "Record.Ddns" "domain_id=${1}&record_id=${2}&sub_domain=${3}&record_line_id=${4}&value=${5}&record_type=A")
returnCode=$(echo $response | sed 's/.*{"code":"\(*\)".*/\1/')
recordIp=$(echo $response | sed 's/.*,"value":"\(*\)".*/\1/')
showMsg "${response}"
# Output Ip
if [ "$recordIp" = "$5" ]; then
if [ "$returnCode" = "1" ]; then
showMsg "New Ip post success: ${recordIp}"
else
# Echo error message
showMsg $(echo $response | sed 's/.*,"message":"\([^"]*\)".*/\1/')
fi
else
showMsg "Update Failed! Please check your network."
fi
}
# use -q to print domain and record Ids
if [ "-q" = "$1" ]; then
printDomainAndRecordIds $2 $3
exit 0
fi
# use (--test domainId recordId subdomainName lineId newIp) to test update
if [ "--test" = "$1" ]; then
updateDdns $2 $3 $4 $5 $6
exit 0
fi
# to sure be call by /etc/ppp/ip-up
if [ $IS_PPP_UP -eq 0 ]; then
echo "Please copy script file to /config/scripts/ppp/ip-up.d/"
exit 0
else
date > /var/log/ppp.log
echo -e "PPP_LOCAL:${PPP_LOCAL} \nPPP_REMOTE:${PPP_REMOTE}" >> /var/log/ppp.log
fi
# Place each domain you want to update as follows
# you can have multiple domainList blocks
#
# updateDdns arguments: domainId recordId subdomainName lineId newIp
#
# lineId samples: "line_ids": {
# "默认": 0,
# "国内": "7=0", 请将 '=' 换成 '%3D', "7%3D0"
# "国外": "3=0",
# "电信": "10=0",
# "联通": "10=1", ......
# lineId list refrence: https://www.dnspod.cn/docs/domains.html#record-line
# (note: lineId if include '=', please replace with '%3D')
updateDdns "1111111" "222222" "@" "0" $PPP_LOCAL
补记:开了 VPN Server 之后,有客户端连接时,也会被执行,这时需要加一个 if 判断:
if [ "$PPP_IFACE" != "pppoe0" ]; then
#echo -e "PPP_IFACE:[${PPP_IFACE}]\nnot pppoe0" >> /var/log/ppp.log
exit 0
fi参考资料:https://github.com/anrip/ArDNSPod
页:
[1]