51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

利用华为云 API 实现自动 DDNS 功能|支持IPv4|IPv6

DDNS 与常规 DNS 不同的地方就是,DDNS 是动态的,而 DNS 是静态的。所以所谓 DDNS 其实就是利用 DNS 服务商的 API 接口,近乎实时地去更新 DNS 解析而已。

网上其实也有很多现成的工具和服务商,比如 ddnsclient、no-ip、花生壳等等,那么为什么还要自己造一个呢?这是因为网上的其实或多或少有限制,比如 no-ip 每 30 天要点链接确认状态。

准备 {#article-header-0}

  • 华为云账号、密码,且域名已经托管在华为云上;
  • 执行环境已安装 jq 命令,如果要更新远程 IP,则还要安装 sshpass

功能 {#article-header-1}

  • 自动检测公网 IP;
  • 自动更新域名解析;
  • 解析不存在则自动创建;

脚本 {#article-header-2}

                        
                          #!/bin/bash

###############  授权信息(需修改成你自己的) ################


用户名
===



username="登陆的用户名"


密码
===



password="登陆密码"


做 DDNS 的根域名
===========



zone_name="根域名"


做 DDNS 的域名,创建成功后就是通过该域名访问内网资源
=============================



record_name="解析域名"
#参考 ACME,选用如下地址
iam="iam.myhuaweicloud.com"
dns="dns.ap-southeast-1.myhuaweicloud.com"


######################  修改配置信息 #######################


域名类型,IPv4 为 A,IPv6 则是 AAAA
==========================



record_type="A"


IPv6 检测服务,本站检测服务仅在大陆提供
======================



#ip=$(curl -s https://ipv6.vircloud.net)


IPv4 检测服务
=========



ip=$(curl -s ifconfig.me)
#如果是要检测远程 IP,可参考下条命令
#ip=$(sshpass -p '远程主机密码' ssh 远程主机账号@远程主机 IP 或域名 'curl -s ifconfig.me' 2\>/dev/null)


文件保存地址
======



#current_dir=$(cd `dirname $0`; pwd)
current_dir="/var/log/ddns-hw"


域名后不可带点
=======



record_name=${record_name%.}


变动前的公网 IP 保存位置
==============



ip_file="${current_dir}/ip.${record_name}.txt"


授权保存位置
======



auth_file="${current_dir}/huaweidns.${record_name}.auth"


域名识别信息保存位置
==========



id_file="${current_dir}/huaweidns.${record_name}.ids"


监测日志保存位置
========



log_file="${current_dir}/huaweidns.${record_name}.log"


################### 判断日志文件夹是否存在 ##################
if \[ ! -d "${current_dir}" \]; then
mkdir -p ${current_dir}
fi


######################  监测日志格式 ########################
log() {
if \[ "${1}" \]; then
echo -e "\[$(date)\] - ${1}" \>\> $log_file
echo -e "${1}"
fi
}
log "Initiated."
log "DDNS domain: ${record_name}"


######################  检查响应数据 ########################
check(){
if \[ "${1}" \]; then
log "${2}"
if \[\[ ${1} == ""code"" \]\]; then
result=`echo ${1} | grep -Po '(?<="message":")[^"]*'`
message="  ERROR ENCOUNTERED. RETURN MESSGAE: ${result}"
log "${message}"
if \[ ! -n "${3}" \]; then
exit 1
fi
elif \[\[ ${1} == ""error_msg"" \]\]; then
result=`echo ${1} | grep -Po '(?<="error_msg":")[^"]*'`
message="  ERROR ENCOUNTERED. RETURN MESSGAE: ${result}"
log "${message}"
if \[ ! -n "${3}" \]; then
exit 1
fi
elif \[\[ ${1} == ""total_count":0" \]\]; then
message="  ERROR ENCOUNTERED. RETURN MESSGAE: Doesn't exist."
log "${message}"
if \[ ! -n "${3}" \]; then
exit 1
fi
else
log "  OK."
fi
else
log "${2}"
message="  NO DATA RECEIVED. CHECK NETWORK CONNECTIVITY."
log "${message}"
if \[ ! -n "${3}" \]; then
exit 1
fi
fi
}


###################### 简单判断是否是 IP ####################
if \[ "${ip}" != "${1#\[0-9\].\[0-9\]}" \]; then
log "IPv4 detected: ${ip}"
elif \[ "${ip}" != "${1#:\[0-9a-fA-F\]}" \]; then
log "IPv6 detected: ${ip}"
else
log "No valid IP."
log "Check Done"
exit 0
fi


######################  判断 IP 是否变化 ####################
if \[ -f ${ip_file} \]; then
old_ip=$(cat ${ip_file})
else
dns_ip=$(curl -s -k -H "accept: application/dns-json" "https://doh.360.cn/resolve?name=${record_name}\&type=A")
if \[ -n "${dns_ip}" \]; then
dns_status=$(echo ${dns_ip} \| jq -r ".Status")
if \[ "${dns_status}" == "0" \]; then
dns_ip=$(echo ${dns_ip} \| jq -r ".Answer\[\] \| select(.type == 1) \| .data")
else
dns_ip=""
fi
if \[ "${dns_ip}" \]; then
old_ip=$(echo ${dns_ip} \| head -n 1)
else
ping_dns=$(ping ${record_name} -c 1 2\>/dev/null)
ping_ip=$(echo ${ping_dns} \| awk -F ' ' '{print $3}' \| head -n 1)
if \[ ! -n "${ping_ip}" \]; then
old_ip=""
else
old_ip=${ping_ip:1:${#ping_ip}-2}
fi
fi
fi
if \[ ! -n "${old_ip}" \]; then
log "No records detected."
else
echo "${old_ip}" \> ${ip_file}
log "Last recorded IP: ${old_ip}"
fi
fi
if \[ "${ip}" == "${old_ip}" \]; then
log "IP has not changed."
log "Done."
exit 0
else
log "IP changed, new IP: ${ip}, updating ..."
fi


######################  获取操作授权  ######################
get_token(){
auth_content=$(curl -L -k -s -D - -X POST "https://${iam}/v3/auth/tokens" -H "Content-Type: application/json;charset=utf8" --data-raw "{"auth": {"identity": {"methods": \["password"\],"password": {"user": {"name": "${username}","password": "${password}","domain": {"name": "${username}"}}}},"scope": {"project": {"name": "ap-southeast-1"}}}}")
check "${auth_content}" "Get token ..."
auth_identifier=$(echo "${auth_content}" \| grep X-Subject-Token \| awk -F ' ' '{print $2}')
auth_date=$(echo "${auth_content}" \| grep "Date: " \| awk -F ' ' '{print $2" "$4" "$3" "$5" "$6}')
auth_expire=$(date -d "${auth_date} +1day" +%s)
echo "${auth_expire} ${auth_identifier}" \> ${auth_file}
log "Token obtained successfully."
}
log "Check token ..."
if \[ -f ${auth_file} \] ; then
auth_identifier=$(head -1 ${auth_file} \| awk -F ' ' '{print $2}')
auth_expire=$(head -1 ${auth_file} \| awk -F ' ' '{print $1}')
if \[ ! -n "${auth_identifier}" \]; then
log "Token doesn't exist, getting ..."
get_token
else
current_date=$(date +%s)
if \[\[ "${current_date}" \> "${auth_expire}" \]\]; then
log "Token expires, refreshing ..."
get_token
fi
fi
log "Check token done."
else
log "Token doesn't exist, getting ..."
get_token
fi


######################  获取域名 ID 信息 ######################
get_zone(){
zone_identifier=$(curl -s -X GET "https://${dns}/v2/zones?name=${zone_name}" -H "X-Auth-Token: ${auth_identifier}" -H "Content-Type: application/json")
check "${zone_identifier}" "get zone_id ..."
zone_identifier=$(echo "${zone_identifier}" \| grep -Po '(?\<="id":")\[\^"\]' \| head -1)
}
get_record(){
record_identifier=$(curl -s -X GET "https://${dns}/v2/zones/${zone_identifier}/recordsets?name=${record_name}\&type=${record_type}" -H "X-Auth-Token: ${auth_identifier}" -H "Content-Type: application/json")
check "${record_identifier}" "get record_id ..." ${1}
record_identifier=$(echo "${record_identifier}" \| grep -Po '(?\<="id":")\[\^"\]')
}
create_record(){
description=$(echo "Created on: "$(date +"%Y/%m/%d %H:%M:%S"))
record_identifier=$(curl -s -X POST "https://${dns}/v2/zones/${zone_identifier}/recordsets" -H "X-Auth-Token: ${auth_identifier}" -H "Content-Type: application/json" --data-raw "{"name":"${record_name}.","description":"${description}","type":"${record_type}","ttl":120,"records":\["${ip}"\]}")
check "${record_identifier}" "create record ..."
record_identifier=$(echo "${record_identifier}" \| grep -Po '(?\<="id":")\[\^"\]\*')
}
log "Check ids ..."
if \[ -f ${id_file} \] ; then
zone_identifier=$(head -1 ${id_file})
if \[ ! -n "${zone_identifier}" \]; then
log "Zone_id doesn't exist, getting ..."
get_zone
sed -i '1d' ${id_file}
sed -i '1i ${zone_identifier}' ${id_file}
log "Zond_id obtained successfully."
fi
record_identifier=$(tail -1 ${id_file})
if \[ ! -n "${record_identifier}" \]; then
log "Record_id doesn't exist, getting ..."
get_record
sed -i '2d' ${id_file}
echo "${record_identifier}" \>\> ${id_file}
log "Record_id obtained successfully."
fi
log "Check ids done."
else
log "Ids doesn't exist, getting ..."
get_zone
get_record "create"
if \[ ! -n "${record_identifier}" \]; then
log "Record_id doesn't exist, creating ..."
create_record
log "Record_id created successfully."
fi
echo "${zone_identifier}" \> ${id_file}
echo "${record_identifier}" \>\> ${id_file}
fi


######################  更新 DNS 记录 ######################
description=$(echo "Last updated on: "$(date +"%Y/%m/%d %H:%M:%S"))
update=$(curl -s -X PUT "https://${dns}/v2/zones/${zone_identifier}/recordsets/${record_identifier}" -H "X-Auth-Token: ${auth_identifier}" -H "Content-Type: application/json" --data-raw "{"name":"${record_name}.","description" : "${description}","type":"${record_type}","ttl":120,"records":\["${ip}"\]}"")


check "${update}" "Updating record ..." "create"
record_identifier=$(echo "${update}" \| grep -Po '(?\<="id":")\[\^"\]\*')


if \[ ! -n "${record_identifier}" \]; then
log "Record_id doesn't exist, creating ..."
create_record
log "Record_id created successfully."
sed -i '2d' ${id_file}
echo "${record_identifier}" \>\> ${id_file}
log "Record_id updated successfully."
fi


message="IP has been updated to: ${ip}"
echo "${ip}" \> ${ip_file}
log "${message}"


log "Done."


                          <span aria-hidden="true" class="line-numbers-rows">
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                            <span>
                            </span>
                          </span>
                        </code>
                      </pre>



  
    

   
     
     Sh 
   
     

   
     

     Copy 
   
     
  
    
 

效果 {#article-header-3}

首次执行:

                        
                          Initiated.
DDNS domain: zd.vircloud.net
IPv4 detected: 1.2.3.4
No records detected.
IP changed, new IP: 1.2.3.4, updating ...
Check token ...
Token doesn't exist, getting ...
Get token ...
OK.
Token obtained successfully.
Check ids ...
Ids doesn't exist, getting ...
get zone_id ...
OK.
get record_id ...
ERROR ENCOUNTERED. RETURN MESSGAE: Doesn't exist.
Record_id doesn't exist, creating ...
create record ...
OK.
Record_id created successfully.
Updating record ...
OK.
IP has been updated to: 1.2.3.4
Done.
                          
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                          
                        
                      

Sh
Copy

后续更新:

                        
                          Initiated.
DDNS domain: zd.vircloud.net
IPv4 detected: 1.2.3.4
IP has not changed.
Done.
                          
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                          
                        
                      

Sh
Copy

                        
                          Initiated.
DDNS domain: zd.vircloud.net
IPv4 detected: 1.2.3.5
IP changed, new IP: 1.2.3.5, updating ...
Check token ...
Check token done.
Check ids ...
Check ids done.
Updating record ...
OK.
IP has been updated to: 1.2.3.5
Done.
                          
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                            
                          
                        
                      

Sh
Copy


相关文章:

1、《 利用 CloudFlare API 实现自动 DDNS 功能|支持IPv4|IPv6


赞(0)
未经允许不得转载:工具盒子 » 利用华为云 API 实现自动 DDNS 功能|支持IPv4|IPv6