Shell脚本调用阿里云API实现DDNS动态域名解析[通俗易懂]

Shell脚本调用阿里云API实现DDNS动态域名解析[通俗易懂]由于服务器的外网是动态拨号,每次获取的外网IP都不同。手头上刚好有阿里云的域名。为此,想通过编写一个Shell脚本,定期通过互联网服务获取当前机器所在网络的IP地址,并将新的IP地址通过阿里云提供的API,更新到对应的域名解析记录。申请AccessKey登陆阿里云官网,在控制台的右上角,将鼠标移动到头像上,会出现如下列表:选择AccessKey管理,会弹出如下提示:选择开始使用子用户Access

大家好,又见面了,我是你们的朋友全栈君。

前言

由于服务器的外网是动态拨号,每次获取的外网IP都不同。手头上刚好有阿里云的域名。为此,想通过编写一个Shell脚本,定期通过互联网服务获取当前机器所在网络的外部IP地址,并将新的IP地址通过阿里云提供的API,更新到对应的域名解析记录。

申请AccessKey

登陆阿里云官网,在控制台的右上角,将鼠标移动到头像上,会出现如下列表:
AccessKey管理入口
选择AccessKey管理,会弹出如下提示:
子用户AccessKey入口
选择开始使用子用户AccessKey,这里不选择继续使用AccessKey,原因是当前进入的页面是主账号,拥有所有的权限,建议通过使用子账户来配置,控制权限。

创建用户

创建用户信息页面
填写要创建的登陆名称和显示名称,这里可以按照需要进行填写,然后点击确定完成创建用户。如果弹出要验证短信,则按提示完成即可。
创建用户完成页面
创建完成后,默认账户没有AccessKey IDAccessKey Secret
选择左侧用户列表,点击新创建的用户名,出现如下设置:
创建用户AccessKey入口
选择创建AccessKey
AccessKey信息页面
保存创建好的AccessKey IDAccessKey Secret,注意AccessKey Secret只会在这一次显示,后续无法在此查看。如果忘记了,只能删除掉重新添加新的。

创建用户组

点击用户组,选择创建用户组,并填写用户组的相关信息。
创建用户组信息页面
点击确定,创建用户组。

用户组添加成员

添加组成员入口
在用户组后面选择添加组成员
添加组成员页面
选择要添加的用户进行添加,然后点击确定

用户组添加权限

添加权限入口
在用户组后面选择添加权限
添加权限页面
点击确定,添加权限。
添加权限结果页面
到这里,子账户的创建及权限配置就已经完成。

Shell脚本

#!/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
#
# 设置需要DDNS的域名 <DomainName>
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/#/user/list 生成的AK/SK, 更安全
#
# 设置阿里云的Access Key
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 IDAccessKey Secret填入。运行脚本即可定时检测当前外网IP,并更新到对应的子域名记录里面。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/143003.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Spring JpaTransactionManager事务管理

    Spring JpaTransactionManager事务管理    首先,在做关于JpaTransactionManager之前,先对Jpa做一个简单的了解,他毕竟不如hibernate那么热门,其实二者很相识,只不过后期hibernate和JDO版本都已经兼容了其Jpa,目前大家用的少了。   JPA全称JavaPersistenceAPI.JPA通过JDK5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化…

    2025年7月21日
    3
  • word文档页码不连续编号怎么办_怎样给论文加页码

    word文档页码不连续编号怎么办_怎样给论文加页码论文页码设置大家好!今天和大家分享两个和页码有关的技巧:大家好!今天和大家分享两个和页码有关的技巧:为分栏页面分别设置页码对纵向文档中的横向表格设置页码page域及域代码操作基础技巧01分栏页面像下面这个文档,对页面分成了两栏,如果现在想给每一栏都添加一个页码序号,也就是在第1页的左右两栏分别显示第1页和第2页,在第2页的左右两栏分别显示第3页和第4页,这样的效果该如何设置呢?我们先在页脚中设置好…

    2025年7月29日
    3
  • pytorch tensor转int_numpy和pytorch

    pytorch tensor转int_numpy和pytorchtensor转换为numpy采用.numpy()函数即可a=torch.tensor([1,2,3])print(a)print(type(a))print(a.dtype)b=a.numpy()print(b)print(type(b))print(b.dtype)输出:torch.tensor整数默认为int64即LongTensor小数默认为float32不过一般对tensor采用tensor.data()或者tensor.detach(

    2022年10月9日
    4
  • idea 2022.01 mac 激活(注册激活)2022.01.19

    (idea 2022.01 mac 激活)这是一篇idea技术相关文章,由全栈君为大家提供,主要知识点是关于2021JetBrains全家桶永久激活码的内容https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~0HKLM1UCCY-eyJsaWNlb…

    2022年3月31日
    545
  • windows 7 开机错误 未能连接到一个Windows服务

    windows 7 开机错误 未能连接到一个Windows服务Windows无法连接到systemeventnotificationservice服务。此问题阻止标准用户登录系统。作为管理员用户,您可以复查系统事件日志,以获得有关此服务未响应原因的详细信息。如下图:莫名其妙突然电脑死机了,重启后就出现了上述问题,并且电脑无法连网,开机速度慢到需要4分钟多,刚开机还黑屏。查看systemeventnotificationserv…

    2022年5月15日
    39
  • mysql的UUID获取上一篇下一篇(上一条 下一条)应用实例[通俗易懂]

    mysql的UUID获取上一篇下一篇(上一条 下一条)应用实例[通俗易懂]先讲原理:有上一篇下一篇(上一条下一条),肯定是在:搜索条件下,排序规则固定的场景下,得到的一个查询集合(列表)中的一个效果。1.我们在这两个条件(搜索条件where排序规则order),给查询结果集给利用rownum(一个顺序自增的标号)2.查询出目标uuid的rownum值x.3.查询上一条和下一条:rownum=x-1的uuid得到上一条rownum=x+1的uuid得到下一条实际应用:一个固定的检索条件固定排序的查询:SELECT bn.*FROM b

    2022年8月9日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号