IPV6越来越流行了,有了IPV6后,再搞个动态的DDNS解析服务,就圆满了。
与现成的能用DDNS相比,支持IPV6,而且灵活,简单。
云服务商,我们还是用的最中意的华为云。
找到云解析服务的查询API
https://console.huaweicloud.com/apiexplorer/#/openapi/DNS/debug?api=ListRecordSets
先查询一下,自己当前的记录集
我这边的结果如下:
{
"id": "ff8080828e61eabc018ea161e5d910f0",
"name": "nav.xudongvp.com.",
"description": null,
"type": "AAAA",
"ttl": 30,
"records": [
"240e:3333:3333:3333:3333:3333:3333:3333"
],
"status": "ACTIVE",
"zone_id": "8aace3ba78033e080178e2b501f00821",
"zone_name": "xudongvp.com.",
"create_at": "2024-04-03T00:35:31.405",
"update_at": "2024-04-03T00:35:31.448",
"default": false,
"project_id": "08e5652c18000f3e2ffec01afc3fe9a4",
"links": {
"self": "https://dns.myhuaweicloud.com/v2/zones/8aace3ba78033e080178e2b501f00821/recordsets/ff8080828e61eabc018ea161e5d910f0"
},
"tags": []
}
下面我们用更新记录集的API,进行DNS信息更新。
更新的代码,我们就不自己重新全部写了。借用一个现成的,修改一下,原文参考:https://www.bilibili.com/read/cv20113893/
#!/usr/bin/sh
#. /etc/profile
# Copyright 2021 LVCS
# https://github.com/lllvcs/huaweicloud_ddns
# https://gitee.com/lvcs/huaweicloud_ddns
# 在运行此脚本之前,请先在华为云DNS管理控制台内添加对应域名的A记录
# 并获取对应的 ZONE_ID 和 RECORDSET_ID
DOMAIN_NAME="XXXXXXX"
RECORDSET_ID="XXXXXXX"
# 一般来说用户名和账户名相同
USERNAME="XXXXXXX"
ACCOUNTNAME="XXXXXXX"
PASSWORD="XXXXXXX"
# 对应解析记录的 ZONE_ID、RECORDSET_ID和PROJECT_ID,其中PROJECT_ID可以在华为云APIexplorer中的云解析服务>recordset管理>showRecordSet中填写id后的调试结果中的请求头X-Project-Id看到
ZONE_ID="XXXXXXX"
PROJECT_ID="XXXXXXX"
# 从外网API获取ip地址(默认开启1)
REMOTE_RESOLVE=1
# 从网卡获取ip地址(填写网卡名)
# 并请根据实际情况填写sed行数
INTERFACE="eth0"
# 更新IP
TARGET_IP=""
# 获取ip地址网址
GETIPURL="https://6.ipw.cn"
# End Point 终端地址 请根据地域选择,默认为北京1
IAM="iam.af-south-1.myhuaweicloud.com"
DNS="dns.cn-east-3.myhuaweicloud.com"
#认证token获取:
TOKEN_X="$(
curl -L -k -s -D - -X POST \
"https://$IAM/v3/auth/tokens" \
-H 'content-type: application/json' \
-d '{
"auth": {
"identity": {
"methods": ["password"],
"password": {
"user": {
"name": "'$USERNAME'",
"password": "'$PASSWORD'",
"domain": {
"name": "'$ACCOUNTNAME'"
}
}
}
},
"scope": {
"domain": {
"name": "'$ACCOUNTNAME'"
}
}
}
}' | grep X-Subject-Token
)"
TOKEN="$(echo $TOKEN_X | awk -F ' ' '{print $2}')"
#获取本机IP:
if [ -z $TARGET_IP ]; then
if [ $REMOTE_RESOLVE -eq 1 ]; then
if [ $INTERFACE ]; then
TARGET_IP=$(curl -s -6 --interface $INTERFACE $GETIPURL)
else
TARGET_IP=$(curl -s -6 $GETIPURL)
fi
else
if [ $INTERFACE ]; then
TARGET_IP=$(ifconfig $INTERFACE | grep 'inet6' | grep Global | grep -oE '(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))' | sed -n 1p)
else
TARGET_IP=$(ifconfig | grep 'inet6' | grep Global | grep -oE '(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))' | sed -n 1p)
fi
fi
fi
#获取云解析IP:
HWcloud_IP=$(echo $(curl -X GET -L -k "https://$DNS/v2/zones/$ZONE_ID/recordsets/$RECORDSET_ID" \
-H "X-Auth-Token: $TOKEN" \
-H "Content-Type: application/json" \
-H "X-Project-Id: $PROJECT_ID")| sed 's/,/\n/g'|grep 'records'| grep -oE '(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))')
#判断IP是否一致、是否需要调用API修改:
if [ "$TARGET_IP" == "$HWcloud_IP" ]; then
echo $(echo "[";date "+%Y-%m-%d %H:%M:%S";echo "] ";echo "云解析IP"[$HWcloud_IP]"与本机IP"[$TARGET_IP]"相同,无需修改";)
else
echo $(echo "[";date "+%Y-%m-%d %H:%M:%S";echo "] ";echo "云解析IP"[$HWcloud_IP]"与本机IP"[$TARGET_IP]"不同,正在修改,API响应内容如下:";
curl -X PUT -L -k -s \
"https://$DNS/v2/zones/$ZONE_ID/recordsets/$RECORDSET_ID" \
-H "Content-Type: application/json" \
-H "X-Auth-Token: $TOKEN" \
-d "{\"name\": \"$DOMAIN_NAME\",\"type\": \"AAAA\",\"records\": [\"$TARGET_IP\"],\"ttl\": 30}";)
fi
脚本中,相比与原脚本,主要更新了外部IP获取方式,本地IPV6的过滤筛选方式等,然后调试通过。
至于为什么我们只更新了IPV6的解析,没有更新IPV4的解析,原因就不展开了,懂得自然懂。