该方法适用于任何可以执行 .sh 脚本的环境下
- 首先需要一个阿里的域名
- 需要有阿里的操作AccessKey,没有的可以在阿里云控制台申请
- 下载文件 aliyun.sh (点击访问)
或复制下面的代码保存为 aliyun.sh1
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!/bin/sh
set -e
if [ $1 ]; then
ApiId=$1
fi
if [ $2 ]; then
ApiKey=$2
fi
if [ $3 ]; then
Domain=$3
fi
if [ -z "$ApiId" -o -z "$ApiKey" -o -z "$Domain" ]; then
echo "参数缺失"
exit 1
fi
if [ $4 ]; then
SubDomain=$4
fi
if [ -z "$SubDomain" ]; then
SubDomain="@"
fi
Nonce=$(date -u "+%N") # 有bug?
Timestamp=$(date -u "+%Y-%m-%dT%H%%3A%M%%3A%SZ") # SB 阿里云, 什么鬼时间格式
Nonce=$Timestamp
urlencode() {
local raw="$1";
local len="${#raw}"
local encoded=""
for i in `seq 1 $len`; do
local j=$((i+1))
local c=$(echo $raw | cut -c$i-$i)
case $c in [a-zA-Z0-9.~_-]) ;;
*)
c=$(printf '%%%02X' "'$c") ;;
esac
encoded="$encoded$c"
done
echo $encoded
}
$1 = query string
getSignature() {
local encodedQuery=$(urlencode $1)
local message="GET&%2F&$encodedQuery"
local sig=$(echo -n "$message" | openssl dgst -sha1 -hmac "$ApiKey&" -binary | openssl base64)
echo $(urlencode $sig)
}
sendRequest() {
local sig=$(getSignature $1)
local result=$(wget -qO- --no-check-certificate --content-on-error "https://alidns.aliyuncs.com?$1&Signature=$sig")
echo $result
}
getRecordId() {
echo "获取 $SubDomain.$Domain 的 IP..." >&2
local queryString="AccessKeyId=$ApiId&Action=DescribeSubDomainRecords&Format=JSON&SignatureMethod=HMAC-SHA1&SignatureNonce=$Nonce&SignatureVersion=1.0&SubDomain=$SubDomain.$Domain&Timestamp=$Timestamp&Type=A&Version=2015-01-09"
local result=$(sendRequest "$queryString")
local code=$(echo $result | sed 's/.*,"Code":"\([A-z]*\)",.*/\1/')
local recordId=$(echo $result | sed 's/.*,"RecordId":"\([0-9]*\)",.*/\1/')
if [ "$code" = "$result" ] && [ ! "$recordId" = "$result" ]; then
local ip=$(echo $result | sed 's/.*,"Value":"\([0-9\.]*\)",.*/\1/')
if [ "$ip" == "$NewIP" ]; then
echo "IP 无变化, 退出脚本..." >&2
echo "quit"
else
echo $recordId
fi
else
echo "null"
fi
}
$1 = record ID, $2 = new IP
updateRecord() {
local queryString="AccessKeyId=$ApiId&Action=UpdateDomainRecord&DomainName=$Domain&Format=JSON&RR=$SubDomain&RecordId=$1&SignatureMethod=HMAC-SHA1&SignatureNonce=$Nonce&SignatureVersion=1.0&Timestamp=$Timestamp&Type=A&Value=$2&Version=2015-01-09"
local result=$(sendRequest $queryString)
local code=$(echo $result | sed 's/.*,"Code":"\([A-z]*\)",.*/\1/')
if [ "$code" = "$result" ]; then
echo "$SubDomain.$Domain 已指向 $NewIP." >&2
else
echo "更新失败." >&2
echo $result >&2
fi
}
$1 = new IP
addRecord() {
local queryString="AccessKeyId=$ApiId&Action=AddDomainRecord&DomainName=$Domain&Format=JSON&RR=$SubDomain&SignatureMethod=HMAC-SHA1&SignatureNonce=$Nonce&SignatureVersion=1.0&Timestamp=$Timestamp&Type=A&Value=$1&Version=2015-01-09"
local result=$(sendRequest $queryString)
local code=$(echo $result | sed 's/.*,"Code":"\([A-z]*\)",.*/\1/')
if [ "$code" = "$result" ]; then
echo "$SubDomain.$Domain 已指向 $NewIP." >&2
else
echo "添加失败." >&2
echo $result >&2
fi
}
Get new IP address
echo "获取当前 IP..."
NewIP=$(wget -qO- --no-check-certificate "http://members.3322.org/dyndns/getip")
echo "当前 IP 为 $NewIP."
Get record ID of sub domain
recordId=$(getRecordId)
if [ ! "$recordId" = "quit" ]; then
if [ "$recordId" = "null" ]; then
echo "域名记录不存在, 添加 $SubDomain.$Domain 至 $NewIP..."
addRecord $NewIP
else
echo "域名记录已存在, 更新 $SubDomain.$Domain 至 $NewIP..."
updateRecord $recordId $NewIP
fi
fi - 配置群晖内的计划任务
主要修改的是”用户定义脚本” 格式如下,多个域名每行一个
假设需要配置两个域名,一个是 www.domain.com,一个是cloud.domain.com
那么脚本内容就是
1 | sh {绝对地址}aliyun.sh {AccessKeyId} {AccessKeySecret} domain.com www |
配置群晖计划任务
控制面板 》任务计划 》新增任务
设定好执行时间