利用shell脚本,实现腾讯云DNSPod进行DDNS动态域名解析ipv6地址

开始

  • 本代码为shell脚本,且已在Linux环境测试,理论上可以在各种Linux设备进行DDNS动态域名服务,如群晖等NAS或Linux虚拟机。
  • 代码已在群晖Ubuntu测试过。
  • 在开始之前,首先你需要在腾讯云上购买域名域名解析服务在腾讯云上。

如何购买域名?

腾讯云域名注册网页上,可以购买域名。

在购买完成后,可以进入腾讯云的域名控制台,查看域名信息。

如何设置API(密钥)

DNSPod即可设置API(密钥)。

步骤

  • 首先进入DNSPod控制台
  • 然后点击头像,进入【我的账号】,或直接进入DNS账号中心
  • 接下来点击左边【账号中心】的【密钥管理】,或直接进入密钥管理
    在这里插入图片描述
  • 在密钥管理中,点击【创建密钥】即可创建密钥(API)
    在这里插入图片描述
  • 在输入名称之后(名称随意),便可以生成密钥(API)
    在这里插入图片描述

重点

在创建API时候,API的Token仅一次可见,如果忘记复制,需要重新申请。
在这里插入图片描述
在完成之后,你便获得了IDToken,这样你就可以将这两个信息填入代码当中,即可利用代码自动更新IP。

⚠ 重点⚠

  • ID——即脚本中dnspod_ddnsipv6_id,将"API_KEY_ID"替换为ID
  • Token——即脚本中的dnspod_ddnsipv6_token,将"API_KEY_TOKEN"替换为Token

如何使用DDNS动态域名服务

为什么使用DDNS

  • 家用宽带的IPV6地址动态分配,每次拨号设备重启或重新拨号,IP地址都会变换。
  • 绝大多数家庭的IPV4地址为内网地址,无法使用IPV4地址访问服务器。
  • 对于群晖,自带的DNSPod.cn的DDNS域名解析仅支持ipv4,实用性不大。

利用脚本更新DNS

更新情况

V1.02

  • 修改了ipv6的提取规则,现在可以判定fe80开头的地址;
  • 对于ipv6的提取错误,添加了中文的提示;

V1.01

  • 添加了对于syntax error的错误解决方法;

V1.00

  • 发布

这里使用的是shell脚本,在Linux(如NAS、Linux虚拟机),该命令都可以执行。

对于shell脚本,使用的命令包括curlip这些与网络相关的包,NAS与大部分虚拟机都自带,如没有自带,也可以自行安装。

代码复制到文件后,将文件名的后缀,如txt等,修改为sh,例如dnsUpdate.sh(当然,你也可以使用bash命令,而不修改后缀。)

在复制完成后,将脚本中需要替换的名称替换掉,你可以使用bash命令执行这个脚本,从而实现DNS的更新。

命令:bash 文件名称bash 文件绝对路径,例如bash dnsUpdate.shbash /volume1/.../dnsUpdate.sh

你也可以不重名(这样执行需要添加bash):
在这里插入图片描述

⚠ 重点⚠

  • 该代码在更新或添加DNS记录后,自动退出,如果需要实现DDNS,需要定时执行该代码。
  • 关于定时执行该代码的时间,与设置的ttl时间有关,一般与ttl时间一致。
  • 代码仅需将开头的7行(不包括第1行),替换为自己的需要的信息即可,后面可以保持不动。
# 填写示例
dnspod_ddnsipv6_id="123456"
dnspod_ddnsipv6_token="abcdefghijklmnopqrstuvwxyz123456"
dnspod_ddnsipv6_ttl="600"
dnspod_ddnsipv6_domain='test.com'
dnspod_ddnsipv6_subdomain='file'
local_net="eth0"
# 执行成功后,访问地址为http://file.test.com

下面放完整代码。

脚本代码

#!/usr/bin/bash    
dnspod_ddnsipv6_id="API_KEY_ID" #【API_id】将引号内容修改为获取的API的ID
dnspod_ddnsipv6_token="API_KEY_TOKEN" #【API_token】将引号内容修改为获取的API的token
dnspod_ddnsipv6_ttl="600" # 【ttl时间】解析记录在 DNS 服务器缓存的生存时间,默认600(s/秒)
dnspod_ddnsipv6_domain='替换自己所购买的域名' #【已注册域名】引号里改成自己注册的域名
dnspod_ddnsipv6_subdomain='替换为想要的名字' #【二级域名】将引号内容修改为自己想要的名字,需要符合域名规范,附常用的规范
local_net="eth0" # 【网络适配器】 默认为eth0,如果你的公网ipv6地址不在eth0上,需要修改为对应的网络适配器
# 常用的规范【二级域名】
# 【www】 常见主机记录,将域名解析为 www.test.com
# 【@】   直接解析主域名 test.com
# 【*】   泛解析,匹配其他所有域名 *.test.com

# 举例
# 在腾讯云注册域名,登陆DNSPOD,在【我的账号】的【账号中心】中,有【密钥管理】
# 点击创建密钥即可创建一个API
# 如果你在腾讯云注册域名叫【test.com】
# 那么【dnspod_ddnsipv6_domain】后面就填【test.com】
# 然后根据常用的规范/自己想要的名字在【dnspod_ddnsipv6_subdomain】填入自己需要的名字
# 现假设为【file】,那么你的访问地址为【file.test.com】
if [ "$dnspod_ddnsipv6_record" = "@" ]
then
  dnspod_ddnsipv6_name=$dnspod_ddnsipv6_domain
else
  dnspod_ddnsipv6_name=$dnspod_ddnsipv6_subdomain.$dnspod_ddnsipv6_domain
fi

die () {
    echo "Error: unable to find [public IPv6 address], please use the 'ip addr' command or query the network panel of the system to check the network card, and fill in the name of the network card with the IPv6 address in the 'local_net' position in the command file." >&2
    echo "IP地址提取错误: 在指定的网络适配器上[$local_net]找不到<公网IPv6地址>(不是fe80开头),请使用'ip addr'命令或在系统的网络面板查询有公网IP的网络适配器,然后在脚本的[local_net]中用填写网络适配器的名称。" >&2
    exit
}

ipv6_list=`ip addr show $local_net | grep "inet6.*global" | awk '{print $2}' | awk -F"/" '{print $1}'` || die

for ipv6 in ${ipv6_list[@]}
do
    if [[ "$ipv6" =~ ^fe80.* ]]
    then
        continue
    else
        echo select IP: $ipv6 >&1
        break
    fi
done

if [ "$ipv6" == "" ] || [[ "$ipv6" =~ ^fe80.* ]]
then
    die
fi

dns_server_info=`nslookup -query=AAAA $dnspod_ddnsipv6_name 2>&1`

dns_server_ipv6=`echo "$dns_server_info" | grep 'address ' | awk '{print $NF}'`
if [ "$dns_server_ipv6" = "" ]
then
    dns_server_ipv6=`echo "$dns_server_info" | grep 'Address: ' | awk '{print $NF}'`
fi
    
if [ "$?" -eq "0" ]
then
    echo "DNS server IP: $dns_server_ipv6" >&1

    if [ "$ipv6" = "$dns_server_ipv6" ]
    then
        echo "The address is the same as the DNS server." >&1
    fi
    unset dnspod_ddnsipv6_record_id
else
    dnspod_ddnsipv6_record_id="1"   
fi

send_request() {
    local type="$1"
    local data="login_token=$dnspod_ddnsipv6_id,$dnspod_ddnsipv6_token&domain=$dnspod_ddnsipv6_domain&sub_domain=$dnspod_ddnsipv6_subdomain$2"
    return_info=`curl -X POST "https://dnsapi.cn/$type" -d "$data" 2> /dev/null`
}

query_recordid() {
    send_request "Record.List" ""
}

update_record() {
    send_request "Record.Modify" "&record_type=AAAA&record_line=默认&ttl=$dnspod_ddnsipv6_ttl&value=$ipv6&record_id=$dnspod_ddnsipv6_record_id"
}

add_record() {
    send_request "Record.Create" "&record_type=AAAA&record_line=默认&ttl=$dnspod_ddnsipv6_ttl&value=$ipv6"
}

if [ "$dnspod_ddnsipv6_record_id" = "" ]
then
    echo "seem exists, try update." >&1
    query_recordid
    code=`echo $return_info  | awk -F \"code\":\" '{print $2}' | awk -F \",\"message\" '{print $1}'`
    echo "return code $code" >&1
    if [ "$code" = "1" ]
    then
        dnspod_ddnsipv6_record_id=`echo $return_info | awk -F \"records\":.{\"id\":\" '{print $2}' | awk -F \",\"ttl\" '{print $1}'`
        update_record
        echo "update sucessful" >&1
    else
        echo "error code return, domain not exists, try add." >&1
        add_record
        echo "add sucessful." >&1
    fi
else
    echo "domain not exists, try add."
    add_record
    echo "add sucessful" >&1
fi

常见问题

我无法利用脚本获取到IPV6地址(IP地址提取错误)

  • 首先,需要确认你的机器拥有ipv6地址。
    • 在终端输入ip addr或者使用ifconfig命令查询是否存在ipv6地址,如果存在,可能脚本获取的网络适配器不对。
    • 例如使用ip addr
      在这里插入图片描述
    • 你可以观察到,在eth0这个网络适配器下,存在ipv6地址,并且为公网ipv6地址(如果以fe80开头,则为本地地址)
    • 用该网络适配器名称替换脚本中的local_net变量的值,即将原先的eth0替换为存在ipv6地址的适配器名称。

我无法执行这个脚本

  • 在Linux中,如果要使用脚本,需要使用bash命令,如果不带bash,想直接执行,需要给该脚本赋予执行权限。

  • 利用cd命令(在终端)可以进入脚本对应的文件夹。
    在这里插入图片描述

  • 使用ls -l命令可以查询当前目录(查询当前目录可用pwd命令)下的文件的详细信息。
    在这里插入图片描述

  • 如上图所示,在当前目录下,使用ls -l即可查询文件的详细信息,或者ls -l 绝对路径也可以直接查询该目录下的文件信息,其中有关于文件能否执行,在开头可以看到(只需要关注是否有x,在Linux中表示执行权限)。

    • 第一个rwx表示文件所有者的权限(如果中间有-表示缺少该权限),第二个为用户组权限,第三个为其他人权限。
  • 如果没有x,那么,你需要为这个文件赋予执行权限。

  • 使用:chmod ugo+rwx <filename>命令,即可修改这个文件的权限。

    注:如果提示权限不足,则使用sudo chmod ugo+rwx <filename>这个命令。
    (如果你没有管理员权限则无法修改文件属性)

在修改完文件的属性之后,便可以再次执行该文件。

执行报错syntax error near unexpected token `$’{\r’'如何解决

  • 原因: 因为文件在Windows上复制的,复制之后,文件的换行符为dos格式的\r\n而Linux则为unix格式的\n,所以提示unexpected token $’{\r’(即语法错误)。
  • 解决方法:首先在脚本执行之前,使用 sed -i 's/\r//g dnspod.sh'命令,然后再执行bash dnspod.sh
    sed -i 's/\r//g' dnspod.sh
    bash dnspod.sh
    
  • 其中sed命令为清除文本中的\r标识,注意,该标识在一般的文本编辑器自动省略。
    在这里插入图片描述
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值