Loading... !> 我知道代码很乱,先将就用把:joy: #!/bin/bash # # Author: Beijixs # Version: 1.0 # Date: 2019-11-3 # Rely: python(json.tool) sort curl nslookup PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin # Shell Vars _DEBUG=false _INFO=false _ERR=true Print=false Update=false conf="/opt/usr/local/aliyun/dns.conf" # 配置文件路径 age_sum=0 declare -a g_pkey declare -a g_pval declare -a g_pkey_val declare -a parameter=($*) # Get the parameters given by the user. pack_url= RR= DomainName= Type= Value= MyIPv4= MyIPv6= Dev= IP_Status= _count=0 par_one=0 for m in ${parameter[*]};do case $m in -p|-P) [ -z "${U_ACK}" ]&&Print=true&&P_ACK=1&&par_one=$((++par_one)) ;; -u|-U) [ -z "${P_ACK}" ]&&Update=true&&U_ACK=1&&par_one=$((++par_one)) ;; -v|-V) if [ ! -z "${U_ACK}" -o ! -z "${P_ACK}" ]&&[ -z "${D_ACK}" ];then _INFO=true I_ACK=1 fi ;; -d|-D) if [ ! -z "${U_ACK}" -o ! -z "${P_ACK}" ]&&[ -z "${I_ACK}" ];then _DEBUG=true D_ACK=1 fi ;; -h|-H) ;; *) echo -e "Unknown Option: \033[31m${m}\033[0m" ;; esac done if [ ${par_one} -eq 0 ];then cat <<-EOF UsAge: aliyun.sh item -p|-P Print record details. -u|-U Update record value. -d|-D DEBUG mode, the order of use of parameters can not be messed up. -v|-V INFO mode, the order of use of parameters can not be messed up. -h|-H Display help information. EOF exit 12 fi _debug(){ ${_DEBUG} && echo -e "\033[32m[DEBUG]\033[0m: $*" } _info(){ ${_INFO} && echo -e "\033[34m[INFO]\033[0m: $*" } _error(){ ${_ERR} && echo -e "\033[31m[ERROR]\033[0m: $*" } ## ===== GET IPAddress ===== ## fun_get_ip(){ if ${Net_IP};then MyIPv4=$(curl -4 -s --connect-timeout 10 -m 5 "${GET_URL}") ${IPv6}&&MyIPv6=$(curl -6 -s --connect-timeout 10 -m 5 "${GET_URL}") else MyIPv4=$(ip a s ${Dev}|grep "\<inet\>"|awk '{print $2}') ${IPv6}&&MyIPv6=$(ip a s ${Dev}|grep -E "\<inet6.*global"|awk '{print $2}'|awk -F/ '{print $1}') fi _info "Local MyIPv4:" "$MyIPv4" _info "Local MyIPv6:" "$MyIPv6" _debug "Local MyIPv4:" "$MyIPv4" _debug "Local MyIPv6:" "$MyIPv6" } reset_func_ret(){ # Initialize variables。 _func_ret="" } reset_func_vars(){ g_pkey=() g_pval=() g_pkey_val=() rand_num=$(openssl rand -hex 16) _status="" _debug "Rand Number:" "${rand_num}" } put_param(){ g_pkey=(${g_pkey[*]} "$1") g_pval=(${g_pval[*]} "$2") #age_sum=$((++age_sum)) age_sum=${#g_pkey[@]} # 将值保存在数组中 } # Initialize public parameters. put_params_public(){ put_param "Format" "JSON" put_param "AccessKeyId" "${AccessKeyId}" put_param "Version" "2015-01-09" put_param "SignatureMethod" "HMAC-SHA1" put_param "SignatureVersion" "1.0" # time stamp local time_utc=$(date -u +"%Y-%m-%dT%H:%M:%SZ") put_param "Timestamp" "${time_utc}" _debug "Time Stamp:" "$time_utc" # SigatureNonce put_param "SignatureNonce" "${rand_num}" } put_params_DescribeDomainRecords(){ put_param "Action" "DescribeSubDomainRecords" put_param "DomainName" "${DomainName}" put_param "SubDomain" "${SubDomain}" put_param "RRKeyWord" "${RR}" put_param "Type" "${Type}" } put_params_UpdateDomainRecord(){ put_param "Action" "UpdateDomainRecord" put_param "RecordId" "${RecordId}" put_param "RR" "${RR}" put_param "Type" "${Type}" put_param "Value" "${Value}" } put_params_AddDomainRecord(){ put_param "Action" "AddDomainRecord" put_param "DomainName" "${DomainName}" put_param "RR" "${RR}" put_param "Type" "${Type}" put_param "Value" "${Value}" } fun_comb(){ reset_func_ret local url local key val key_code val_code # Encode "key" and "value" respectively. # Sort Key local I=0 while [ $I -lt ${age_sum} ];do eval key="${g_pkey[$I]}" eval val="${g_pval[$I]}" fun_encode "$key" key_code="${_func_ret}" g_pkey[$I]=${key_code} fun_encode "$val" val_code="${_func_ret}" g_pval[$I]=${val_code} I=$((++I)) done # 对key和value分别进行编码,并替换数组中原有的值 for i in `seq 0 $((${age_sum}-1))`;do declare -a g_pkey_val[$i]="${g_pkey[$i]}=${g_pval[$i]}" done # 将两个数组中的值结合,key=value,并保存在新的数组中 # key=value g_pkey_val=($( for m in $(seq 0 $((${#g_pkey_val[*]}-1)));do echo ${g_pkey_val[$m]} done| LC_COLLATE=C sort )) # 对数组进行排序 _debug "Sort:" "${g_pkey_val[*]}" # Sort key local I=0 while [ $I -lt ${#g_pkey_val[*]} ];do url="$url${g_pkey_val[$I]}&" let I++ done # 结合url _debug "Pack Url:" "$url" # Delete last "&" url=$(echo $url|grep -o ".*[^&]") # _func_ret=$url pack_url=$url _debug "Initial URL:" "$pack_url" } fun_encode(){ reset_func_ret local string="${1}" local strlen="${#string}" local encoded="" local count s d count=0 while [ $count -lt $strlen ];do s=${string:$count:1} case "$s" in [-_.~a-zA-Z0-9]) d=${s} ;; *) d=$(printf "%%%02X" "'$s") esac encoded="${encoded}${d}" count=$((++count)) done _func_ret=$encoded # 编码算法 } string_to_sign(){ local string=${pack_url} fun_encode "$string" string="GET&%2F&${_func_ret}" _debug "String to be signed:" "$string" local key_sign="${AccessKeySec}&" str_sign=$(echo -n "$string"|openssl dgst -binary -sha1 -hmac ${key_sign} | openssl enc -base64) _debug "Signature result:" "${str_sign}" fun_encode "$str_sign" _debug "Coding result:" "${_func_ret}" req_addr="https://alidns.aliyuncs.com/?${pack_url}&Signature=${_func_ret}" _debug "Real request URL:" "$req_addr" } fun_update(){ reset_func_vars # Initialize variables and arrays. put_params_public # Defining public parameters. put_params_UpdateDomainRecord fun_comb # Sort parameters and combine urls. string_to_sign # signature _info "Result" _debug "Result" #curl -s ${req_addr} |python -m json.tool local INFO=$(curl -s ${req_addr} --silent --connect-timeout 10 -w "Status:%{http_code}\n") _status=$(echo ${INFO}|grep -o "Status.*"|awk -F: '{print $2}' ) _debug "${INFO}" _info "${INFO}" if [ ${_status} = 200 ];then return 0 fi return 1 } fun_add_record(){ _info "Adding record..." _debug "Adding record..." reset_func_vars # Initialize variables and arrays. put_params_public # Defining public parameters. put_params_AddDomainRecord fun_comb string_to_sign # signature _info "Result" _debug "Result" local INFO=$(curl -s ${req_addr} --silent --connect-timeout 10 -w "Status:%{http_code}\n") _status=$(echo ${INFO}|grep -o "Status.*"|awk -F: '{print $2}' ) _debug "${INFO}" _info "${INFO}" if [ ${_status} = 200 ];then _info "Add record successfully." _debug "Add record successfully." return 0 fi _info "Add record failed.Do you own the domain name?(${DomainName})" _debug "Add record failed.Do you own the domain name?(${DomainName})" return 100 } fun_check(){ local SubDomain=${SubDomain} if [ ${SubDomain:0:1} == "@" ];then SubDomain=${DomainName} fi #local IP=$(dig @${DNS_Server} ${SubDomain} +short) local IP="$(nslookup -query=${Type} ${SubDomain} ${DNS_Server}|grep "Name" -A 1|tail -1|awk '{print $2}')" _debug "Last IP:" ${IP} _info "Last IP:" ${IP} if [ "$IP" == "${Value}" ];then _info "SubDomain: ${SubDomain}" _debug "SubDomain: ${SubDomain}" _info "The IP address is the same as the local IP address. No need to modify it." _debug "The IP address is the same as the local IP address. No need to modify it." return 0 else return 1 fi } fun_print(){ [ "${IPv6}" = "false" -a ${Type} = "AAAA" ]&&return 133 reset_func_vars # Initialize variables and arrays. put_params_public # Defining public parameters. put_params_DescribeDomainRecords # Defining unique parameters. fun_comb # Sort parameters and combine urls. string_to_sign # signature _info "Request completed:" #curl -s $req_addr|python -m json.tool curl -s $req_addr|python -m json.tool|grep -E "DomainName|RR|Type|Value|RecordId|Message"|sed "s#\"##g;s#,##;s#^[[:space:]]*##g"| \ awk -v b=${SubDomain} 'BEGIN{print "\n------------------------------------\n"," SubDomain : ",b,"\n------------------------------------"} \ BEGIN{printf "\tKey\t\tValue\n------------------------------------\n"} \ {printf " %-16s%-10s\n",$1,$2} \ END{printf "------------------------------------\n\n"}' } fun_check_id(){ local check=${1} local tmp="" if [ -z "${1}" ];then _debug "RecordId does not exist." _debug "Find recordId." tmp=$(fun_print|grep "RecordId"|awk '{print $2}') if [ -z ${tmp} ];then _debug "No such record." return 20 else _debug "RecordId" "${tmp}" RecordId=${tmp} sed -i "s#^Domain \"${Type}\" \"${DomainName}\" \"${RR}\".*#Domain \"${Type}\" \"${DomainName}\" \"${RR}\" \"$RecordId\"#" ${conf} return 0 fi fi return 0 } fun_to_update(){ if [ ${IP_Status} -eq 1 -a ${Type} = "AAAA" ];then _info "Skip:" "Ipv6 failed to get rid of ipv6 record updates." _debug "Skip:" "Ipv6 failed to get rid of ipv6 record updates." return 3 elif [ ${IP_Status} -eq 2 -a ${Type} = "A" ];then _info "Skip:" "Ipv4 failed to get rid of ipv6 record updates." _debug "Skip:" "Ipv4 failed to get rid of ipv6 record updates." return 4 fi if fun_check;then return 0 fi if fun_check_id ${RecordId};then if fun_update;then _debug "Update completed." _info "Update completed." return 0 else _error "Update failed." "Try updating \"RecordId\"." RecordId="" if fun_check_id ${RecordId};then if fun_update;then _debug "Update completed." _info "Update completed." return 0 fi _error "Update failed.(Unknown reason)" else _error "No such record." "Will automatically add records." fun_add_record # ADD Record fi fi else _error "No such record." "Will automatically add records." # ADD Record fun_add_record fi } fun_check_conf(){ local index=0 local Key=() local Value=() Key=("AccessKeyId" "AccessKeySec" "Dev" "Net_IP" "GET_URL" "DNS_Server" "IPv6") Value=("${AccessKeyId}" "${AccessKeySec}" "${Dev}" "${Net_IP}" "$GET_URL" "${DNS_Server}" "${IPv6}") for I in ${Key[*]};do if [ -z "${Value[$index]}" ];then case $I in Net_IP|AccessKeyId|AccessKeySec) _error "$I" "This value cannot be empty" exit 15 ;; GET_URL) GET_URL="ip.sb" _info "Default GET_URL:" "${GET_URL}" _debug "Default GET_URL:" "${GET_URL}" ;; DNS_Server) DNS_Server="dns23.hichina.com" _info "Default DNS_Server:" "${DNS_Server}" _debug "Default DNS_Server:" "${DNS_Server}" ;; IPv6) IPv6=false _info "Default IPv6:" "${IPv6}" _debug "Default IPv6:" "${IPv6}" ;; esac fi index=$((++index)) done [ ${IPv6} != "true" -a ${IPv6} != "false" ]&&_error "IPv6:" "Unknown value.(Value: true|false)"&&exit 12 [ ${Net_IP} != "true" -a ${Net_IP} != "false" ]&&_error "Net_IP:" "Unknown value.(Value: true|false)"&&exit 12 [ ${Net_IP} == "false" -a -z "${Dev}" ]&&_error "\"Net_IP\" is false, \"Dev\" cannot be empty"&&exit 12 } fun_check_ip(){ case ${IPv6} in true) if [ ! -z "${MyIPv4}" -a ! -z "${MyIPv6}" ];then IP_Status=0 elif [ ! -z "${MyIPv4}" -a -z "${MyIPv6}" ];then IP_Status=1 _error "Skip:" "Ipv6 address acquisition failed, will not update the A record" elif [ -z "${MyIPv4}" -a ! -z "${MyIPv6}" ];then IP_Status=2 _error "Skip:" "Ipv4 address acquisition failed, will not update A record." else _error "Can't get ipv4 and ipv6 address." exit 52 fi ;; false) IP_Status=1 _info "Skip:" "Ipv6 record update has been closed and AAAA record will not be updated." if [ -z "${MyIPv4}" ];then _error "Failed to get Ipv4 address." exit 51 fi ;; esac } fun_check_domain(){ local D_Key=("Type" "DomainName" "RR" "RecordId") local D_Val=("${Type}" "${DomainName}" "${RR}" "${RecordId}") for i in {0..2};do if [ -z "${D_Val[$i]}" ];then _error "${D_Key[$i]}" "None" return 25 fi done if [ ${Type} = "A" ];then Value=${MyIPv4} elif [ ${Type} = "AAAA" ];then Value=${MyIPv6} else _error "Unknow Type:" "${Type}" return 12 fi [ -z "${D_Val[3]}" ]&&_info "RecordId:" "None" _debug "SubDomain:" "${RR}.${DomainName}" _info "SubDomain:" "${RR}.${DomainName}" return 0 } # 引入配置文件 Domain(){ # Main function _debug "--------------------------------------------------------------------------------------------------------" _info "--------------------------------------------------------------------------------------------------------" DomainName="${2}" Type="${1}" RR="${3}" SubDomain="${RR}.${DomainName}" RecordId=${4} if [ ${_count} = 0 ];then # check_conf fun_check_conf # get_ip fun_get_ip # check_ip fun_check_ip _count=1 fi if fun_check_domain;then ${Print}&&fun_print ${Update}&&fun_to_update fi } . ${conf} !> 配置文件需要严格遵守格式 # AccessKeyId="" # AccessKeySec="" # AccessKeyId="" AccessKeySec="" # Set the network interface to obtain the ip address. This value is invalid when "Net_IP" is "true". Dev="ppp0" # "Net_IP" is not available, boolean value # Net_IP=false Net_IP=false # This value is not available when "Net_IP" is "true". GET_URL="ip.sb" # On IPv6,Defalut flase IPv6=true # Aliyun "DNS" server address, if not clear, please do not modify. # DNS_Server="dns23.hichina.com" # Domian "Type" "DomainName" "RRKeyWord" "RecordId" # Do not know "RecordId", please leave it blank. as follows. # Domain "A" "beijixs.cn" "www" # # The "RecordId" will be automatically added to the configuration file in the second parsing, please do not manually define. Domain "A" "beijixs.cn" "blog" ------------ <center>END</center> 最后修改:2019 年 11 月 15 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 0 如果觉得我的文章对你有用,请随意赞赏