查询本机是否支持 ipv6

查询网址:https://www.test-ipv6.com/

设置 API(密钥)

进入腾讯云 DNSPod:密钥管理

创建密钥

记录 IDToken

利用脚本更新 DNS

创建 DNSPod.sh

在代码的倒数第 7 行,分别替换 ID 和 Token

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
#!/bin/sh
#

#############################################################
# AnripDdns v6.1.1
#
# Dynamic DNS using DNSPod API
#
# Author: Rehiy, https://github.com/rehiy
# https://www.anrip.com/?s=dnspod
# Collaborators: ProfFan, https://github.com/ProfFan
#
# Usage: please refer to `ddnspod.sh`
#
#############################################################

# TokenID,Token

export arToken=""

# Get WAN IPv4

arWanIp4() {

local hostIp

local lanIps="^$"

lanIps="$lanIps|(^10\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$)"
lanIps="$lanIps|(^127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$)"
lanIps="$lanIps|(^169\.254\.[0-9]{1,3}\.[0-9]{1,3}$)"
lanIps="$lanIps|(^172\.(1[6-9]|2[0-9]|3[0-1])\.[0-9]{1,3}\.[0-9]{1,3}$)"
lanIps="$lanIps|(^192\.168\.[0-9]{1,3}\.[0-9]{1,3}$)"

case $(uname) in
'Linux')
hostIp=$(ip -o -4 addr list | grep -Ev '\s(docker|lo)' | awk '{print $4}' | cut -d/ -f1 | grep -Ev "$lanIps")
;;
Darwin|FreeBSD)
hostIp=$(ifconfig | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | grep -Ev "$lanIps")
;;
esac

if [ -z "$hostIp" ]; then
if type wget >/dev/null 2>&1; then
hostIp=$(wget -q -O- https://v4.myip.la)
else
hostIp=$(curl -s https://v4.myip.la)
fi
fi

if [ -z "$hostIp" ]; then
echo "arWanIp4 - Can't get ip address"
return 1
fi

if [ -z "$(echo $hostIp | grep -E '^[0-9\.]+$')" ]; then
echo "arWanIp4 - Invalid ip address $hostIp"
return 1
fi

echo $hostIp

}

# Get WAN IPv6

arWanIp6() {

local hostIp

local lanIps="(^$)|(^::1$)|(^[fF][eE][8-9a-fA-F])"

case $(uname) in
'Linux')
hostIp=$(ip -o -6 addr list | grep -Ev '\s(docker|lo)' | awk '{print $4,substr($NF,0,length($NF)-3)}' | sed 's/fore/2592000/g' | sort -k 2 -n | cut -d/ -f1 | grep -Ev "$lanIps" | head -n 1)
;;
Darwin|FreeBSD)
hostIp=$(ifconfig | grep "inet6 " | awk '{print $2}' | grep -Ev "$lanIps" | head -n 1)
;;
esac

if [ -z "$hostIp" ]; then
if type wget >/dev/null 2>&1; then
hostIp=$(wget -q -O- https://v6.myip.la)
else
hostIp=$(curl -s https://v6.myip.la)
fi
fi

if [ -z "$hostIp" ]; then
echo "arWanIp6 - Can't get ip address"
return 1
fi

if [ -z "$(echo $hostIp | grep -E '^[0-9a-fA-F:]+$')" ]; then
echo "arWanIp6 - Invalid ip address"
return 1
fi

echo $hostIp

}

# Dnspod Bridge
# Args: type data

arDdnsApi() {

local agent="AnripDdns/6.1.0(wang@rehiy.com)"

local apiurl="https://dnsapi.cn/${1:?'Info.Version'}"
local params="login_token=$arToken&format=json&$2"

if type wget >/dev/null 2>&1; then
wget -q -O- --no-check-certificate -U $agent --post-data $params $apiurl
else
curl -s -A $agent -d $params $apiurl
fi

}

# Fetch Ids of Domain and Record
# Args: recordType domain subdomain

arDdnsIds() {

local errMsg

local domainId
local recordId

# Get Domain Id
domainId=$(arDdnsApi "Domain.Info" "domain=$2")
domainId=$(echo $domainId | sed 's/.*"id":"\([0-9]*\)".*/\1/')

if ! [ "$domainId" -gt 0 ] 2>/dev/null ;then
errMsg=$(echo $domainId | sed 's/.*"message":"\([^\"]*\)".*/\1/')
echo "arDdnsIds - $errMsg"
return 1
fi

# Get Record Id
recordId=$(arDdnsApi "Record.List" "domain_id=$domainId&sub_domain=$3&record_type=$1")
recordId=$(echo $recordId | sed 's/.*"id":"\([0-9]*\)".*/\1/')

if ! [ "$recordId" -gt 0 ] 2>/dev/null ;then
errMsg=$(echo $recordId | sed 's/.*"message":"\([^\"]*\)".*/\1/')
echo "arDdnsIds - $errMsg"
return 1
fi

echo $domainId $recordId
}

# Fetch Record Ip
# Args: domainId recordId

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
[0-9a-fA-F]*)
echo $recordIp
return 0
;;
*)
errMsg=$(echo $recordIp | sed 's/.*"message":"\([^\"]*\)".*/\1/')
echo "arDdnsRecordIp - $errMsg"
return 1
;;
esac

}

# Update Record Ip
# Args: domainId recordId subdomain hostIp recordType

arDdnsUpdate() {

local errMsg

local recordRs
local recordIp
local recordCd

if [ -z "$5" ]; then
echo "arDdnsUpdate - Args number error"
return 1
fi

# Update Ip
recordRs=$(arDdnsApi "Record.Modify" "domain_id=$1&record_id=$2&sub_domain=$3&record_type=$5&value=$4&record_line=%e9%bb%98%e8%ae%a4")
recordIp=$(echo $recordRs | sed 's/.*,"value":"\([0-9a-fA-F\.\:]*\)".*/\1/')
recordCd=$(echo $recordRs | sed 's/.*{"code":"\([0-9]*\)".*/\1/')

# Output Result
if [ "$recordIp" = "$4" ] && [ "$recordCd" = "1" ]; then
echo "arDdnsUpdate - success"
return 0
else
errMsg=$(echo $recordRs | sed 's/.*,"message":"\([^"]*\)".*/\1/')
echo "arDdnsUpdate - $errMsg"
return 1
fi

}

# DDNS Check
# Args: Main Sub
arDdnsCheck() {

local errCode

local recordType
local hostIp

local ddnsIds
local lastIp
local postRs

echo "Fetching Host Ip"
if [ "$3" = "6" ]; then
recordType=AAAA
hostIp=$(arWanIp6)
else
recordType=A
hostIp=$(arWanIp4)
fi

errCode=$?
echo "> Host Ip: $hostIp"
echo "> Record Type: $recordType"
if [ $errCode -ne 0 ]; then
return 1
fi

echo "Fetching Ids of $2.$1"
ddnsIds=$(arDdnsIds "$recordType" "$1" "$2")

errCode=$?
echo "> Domain Ids: $ddnsIds"
if [ $errCode -ne 0 ]; then
return 1
fi

echo "Checking Record for $2.$1"
lastIp=$(arDdnsRecordIp $ddnsIds)

errCode=$?
echo "> Last Ip: $lastIp"
if [ $errCode -ne 0 ]; then
return 1
fi

if [ "$lastIp" = "$hostIp" ]; then
echo "> Last Ip is the same as host Ip"
return 0
fi

echo "Updating Record for $2.$1"
postRs=$(arDdnsUpdate $ddnsIds "$2" "$hostIp" "$recordType")

errCode=$?
echo "> $postRs"
if [ $errCode -ne 0 ]; then
return 1
fi

}

arToken="ID,Token"

# IPv4:
#arDdnsCheck "test.org" "subdomain"

# IPv6:
arDdnsCheck "365day.top" "pan" 6

给该脚本可执行权限

1
chmod 777 DNSPod.sh

当前目录下执行:./DNSPod.sh

设置定时任务

crontab 命令用于设置周期性被执行的指令。该命令从标准输入设备读取指令,并将其存放于“crontab”文件中,以供之后读取和执行。

检查是否安装了 crontab

1
rpm -qa | grep crontab

创建一个任务文件

命令行输入crontab -e会自动打开一个空文件

1
crontab -e

每 1 小时查询一次自己的 IP 地址,并修改解析记录

1
0 */1 * * *  /www/server/DNSPod.sh

后续

保存成功的文件在 /var/spool/cron 目录下

列出当前的所有调度任务

1
crontab -l

查看执行日志

1
cat /var/log/cron

参考