文章目录
前言
由于服务器的外网是动态拨号,每次获取的外网IP都不同。手头上刚好有阿里云的域名。为此,想通过编写一个Shell脚本,定期通过互联网服务获取当前机器所在网络的外部IP地址,并将新的IP地址通过阿里云提供的API,更新到对应的域名解析记录。
申请AccessKey
登陆阿里云官网,在控制台的右上角,将鼠标移动到头像上,会出现如下列表:

选择AccessKey管理,会弹出如下提示:

选择开始使用子用户AccessKey
,这里不选择继续使用AccessKey
,原因是当前进入的页面是主账号,拥有所有的权限,建议通过使用子账户来配置,控制权限。
创建用户

填写要创建的登陆名称和显示名称,这里可以按照需要进行填写,然后点击确定
完成创建用户。如果弹出要验证短信,则按提示完成即可。

创建完成后,默认账户没有AccessKey ID
和AccessKey Secret
。
选择左侧用户列表,点击新创建的用户名,出现如下设置:

选择创建AccessKey

保存创建好的AccessKey ID
和AccessKey Secret
,注意AccessKey Secret
只会在这一次显示,后续无法在此查看。如果忘记了,只能删除掉重新添加新的。
创建用户组
点击用户组,选择创建用户组
,并填写用户组的相关信息。

点击确定
,创建用户组。
用户组添加成员

在用户组后面选择添加组成员

选择要添加的用户进行添加,然后点击确定
。
用户组添加权限

在用户组后面选择添加权限

点击确定
,添加权限。

到这里,子账户的创建及权限配置就已经完成。
Shell脚本
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
| #!/bin/bash echo "[$(date "+%G/%m/%d %H:%M:%S")] AliDDNS.sh start..."
while true do
# 设置需要DDNS的地址,格式为 AliDDNS_SubDomainName.AliDDNS_DomainName , # 例如 AliDDNS_DomainName 为 example.com, AliDDNS_SubDomainName 为 ddns , # 连接起来就是 ddns.example.com #
AliDDNS_DomainName="" # 设置需要DDNS的子域名 <SubDomainName> AliDDNS_SubDomainName="" # 设置域名记录的TTL (生存周期) # 免费版产品最低为600(10分钟)~86400(1天), 付费版(企业版)包括以上范围, 还可以按照购买产品配置设置为: # 600(10分钟)、120(2分钟)、60(1分钟)、10(10秒)、5(5秒)、1(1秒), # 请按照自己的产品配置和DDNS解析速度需求妥善配置TTL值, 免费版设置低于600的TTL将会报错。 AliDDNS_TTL="600"
# 设置阿里云的AccessKeyId/AccessKeySecret, # 可在 https://ak-console.aliyun.com/ 处获取 , # 推荐使用 https://ram.console.aliyun.com/ #
AliDDNS_AK="" # 设置阿里云的Secret Key AliDDNS_SK=""
# 设置获取本机IP需要执行的命令 (用于nslookup命令获取DDNS域名的当前IP) AliDDNS_LocalIP="curl -s whatismyip.akamai.com" # 设置解析使用的DNS服务器 (推荐使用 223.5.5.5/223.6.6.6 , 毕竟都是阿里家的东西) AliDDNS_DomainServerIP="223.5.5.5"
# 防止用户忘记设置参数导致程序报错,部分参数如果检测到空值,自动使用默认值 [ "$AliDDNS_LocalIP" = "" ] && AliDDNS_LocalIP="curl -s whatismyip.akamai.com" [ "$AliDDNS_DomainServerIP" = "" ] && $AliDDNS_DomainServerIP="223.5.5.5" [ "$AliDDNS_TTL" = "" ] && AliDDNS_TTL="600" # 获取本机公网IP AliDDNS_LocalIP=`$AliDDNS_LocalIP 2>&1` || die "$AliDDNS_LocalIP" # 获取DDNS域名当前解析记录IP AliDDNS_DomainIP=`nslookup $AliDDNS_SubDomainName.$AliDDNS_DomainName $AliDDNS_DomainServerIP 2>&1` # 判断上一条命令的执行是否成功 if [ "$?" -eq "0" ] then # 如果执行成功,分离出结果中的IP地址 AliDDNS_DomainIP=`echo "$AliDDNS_DomainIP" | grep 'Address:' | tail -n1 | awk '{print $NF}'` # 进行判断,如果本次获取的新IP和旧IP相同,则进行休眠一分钟后再继续判断 if [ "$AliDDNS_LocalIP" = "$AliDDNS_DomainIP" ] then echo "[$(date "+%G/%m/%d %H:%M:%S")] Local IP ($AliDDNS_LocalIP) is the same with Domain IP ($AliDDNS_DomainIP)" echo "[$(date "+%G/%m/%d %H:%M:%S")] No change modified ..." sleep 60 continue fi fi # 如果IP发生变动,开始进行修改 # 生成时间戳 timestamp=`date -u "+%Y-%m-%dT%H%%3A%M%%3A%SZ"` # URL加密函数 urlencode() { # urlencode <string> out="" while read -n1 c do case $c in [a-zA-Z0-9._-]) out="$out$c" ;; *) out="$out`printf '%%%02X' "'$c"`" ;; esac done echo -n $out } # URL加密命令 enc() { echo -n "$1" | urlencode } # 发送请求函数 send_request() { local args="AccessKeyId=$AliDDNS_AK&Action=$1&Format=json&$2&Version=2015-01-09" local hash=$(echo -n "GET&%2F&$(enc "$args")" | openssl dgst -sha1 -hmac "$AliDDNS_SK&" -binary | openssl base64) curl -s "http://alidns.aliyuncs.com/?$args&Signature=$(enc "$hash")" } # 获取记录值 (RecordID) get_recordid() { grep -Eo '"RecordId":"[0-9]+"' | cut -d':' -f2 | tr -d '"' } # 请求记录值 (RecordID) query_recordid() { send_request "DescribeSubDomainRecords" "SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&SubDomain=$AliDDNS_SubDomainName.$AliDDNS_DomainName&Timestamp=$timestamp" } # 更新记录值 (RecordID) update_record() { send_request "UpdateDomainRecord" "RR=$AliDDNS_SubDomainName&RecordId=$1&SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&TTL=$AliDDNS_TTL&Timestamp=$timestamp&Type=A&Value=$AliDDNS_LocalIP" } # 添加记录值 (RecordID) add_record() { send_request "AddDomainRecord&DomainName=$AliDDNS_DomainName" "RR=$AliDDNS_SubDomainName&SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&TTL=$AliDDNS_TTL&Timestamp=$timestamp&Type=A&Value=$AliDDNS_LocalIP" }
# 判断RecordIP是否为空 if [ "$AliDDNS_RecordID" = "" ] then AliDDNS_RecordID=`query_recordid | get_recordid` fi if [ "$AliDDNS_RecordID" = "" ] then AliDDNS_RecordID=`add_record | get_recordid` echo "[$(date "+%G/%m/%d %H:%M:%S")] Added RecordID : $AliDDNS_RecordID" else update_record $AliDDNS_RecordID echo "[$(date "+%G/%m/%d %H:%M:%S")] Updated RecordID : $AliDDNS_RecordID" fi
# 输出最终结果 if [ "$AliDDNS_RecordID" = "" ]; then # 输出失败结果 (因为没有获取到RecordID) echo "[$(date "+%G/%m/%d %H:%M:%S")] DDNS Update Failed !" else # 输出成功结果 echo "[$(date "+%G/%m/%d %H:%M:%S")] DDNS Update Success, New IP is : $AliDDNS_LocalIP" fi
sleep 30 done
|
填入要管理的域名和对应的子域名,并将上一步获得的AccessKey ID
和AccessKey Secret
填入。运行脚本即可定时检测当前外网IP,并更新到对应的子域名记录里面。