代码如下:

#!/bin/bash
#
PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin

AGE=$1
case "$AGE" in
    -p|-P)
    ;;
    -u|-U)
    ;;
    *)
cat <<-EOF
UsAge: aliyun.sh item

-p,-P           Print record details.
-u,-U           Update record value.
-p|-u -d|-D     DEBUG mode, the order of use of parameters can not be messed up.    
-p|-u -v|-V     INFO mode, the order of use of parameters can not be messed up.
EOF
    ;;
esac
conf="/opt/usr/local/aliyun/dns.conf"
TEST=$2
case "$TEST" in
    -d|-D)
        _DEBUG=true
        _INFO=false #  true|false
    ;;
    -v|-V)
        _INFO=true
        _DEBUG=false #  true|false
    ;;
    *)
        _DEBUG=false #  true|false
        _INFO=false #  true|false
    ;;  
esac

# vars 
age_sum=0
declare -a g_pkey
declare -a g_pval
declare -a g_pkey_val
pack_url=

RR=
DomainName=
# Age 
#_DEBUG=false #  true|false
#_DEBUG=true #  true|false
_ERR=true
#_INFO=false
_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 ===== ##
dev=ppp0
MyIPv4=$(ip a s ${dev}|grep "\<inet\>"|awk '{print $2}')
MyIPv6=$(ip a s ppp0|grep -E "\<inet6.*global"|awk '{print $2}'|awk -F/ '{print $1}')

reset_func_ret(){
# Initialize variables。
    _func_ret=""
}

reset_func_vars(){
    g_pkey=()
    g_pval=()
    g_pkey_val=()
    rand_num=$(openssl rand -hex 16)
    _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" "DescribeDomainRecords"
    put_param  "Action" "DescribeSubDomainRecords"
    put_param  "DomainName" "${DomainName}"
    put_param  "SubDomain" "${SubDomain}"
    put_param  "RRKeyWord" "${RR}"
}

put_params_UpdateDomainRecord(){
    put_param  "Action" "UpdateDomainRecord"
    #put_param  "DomainName" "beijixs.cn"
    put_param  "RecordId" "${RecordId}"
    put_param  "RR" "${RR}"
    put_param  "Type"  "A"
    put_param  "Value" "${MyIPv4}"
}

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"
    curl -s ${req_addr} |python -m json.tool

}
fun_check(){
    local SubDomain=${SubDomain}
    if [ ${SubDomain:0:1} == "@" ];then
        SubDomain=${DomainName}
    fi
    local IP=$(dig @${DNS_Server} ${SubDomain} +short)
    if [ "$IP" == "$MyIPv4" ];then
        _info "SubDomain: ${SubDomain}"
        _info  "The IP address is the same as the local IP address. No need to modify it."
        _info "---------------------------------------------------------------------------"
        return 0
    else
        return 1
    fi

}
# 引入配置文件
    _info "Local IPv4:" "${MyIPv4}"
    _info "Local IPv6:" "${MyIPv6}"
Domain(){
    DomainName="${1}" 
    _debug "DomainName:" "${DomainName}"
    _info "DomainName:" "${DomainName}"
    RR="${2}"
    _debug "RRKeyWord:" "${RR}"    
    _info "RRKeyWord:" "${RR}"    
    SubDomain="${RR}.${DomainName}"
    RecordId=${3}
    local reid=${3}

    case ${AGE} in
        -p|-P)
            fun_print
        ;;
        -u|-U)
            if fun_check;then
                return 0
            fi
            if [ -z ${RecordId} ];then
                    RecordId=$(fun_print|grep "RecordId"|awk '{print $2}')
                    _debug "RecordId:" $RecordId
                    [ -z $RecordId ]&& _error "RecordId:" "None" && return 9
                    fun_update
                        sed -i "s#\"${DomainName}\" \"${RR}\"#& \"$RecordId\"#" ${conf}
            else
                fun_update
                if fun_check &> /dev/null;then
                    return 0
                fi
                    _error "RecordId:" "Does not match, need to be updated."
                    RecordId=$(fun_print|grep "RecordId"|awk '{print $2}')
                    _debug "RecordId" $RecordId
                    [ -z $RecordId ]&& _ERR "RecordId:" "None" && return 9
                    fun_update
                    sed -i "s#${reid}#${RecordId}#" ${conf}
            fi

        ;;
    esac
}

fun_print(){
    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 -F: 'BEGIN{printf "\tKey\t\tValue\n------------------------------------\n"}{printf "    %-16s%-10s\n",$1,$2}END{printf "------------------------------------\n"}'
}

. ${conf}

配置文件

# AccessKeyId=""
# AccessKeySec=""
#

AccessKeyId="LTAI4FsCkhk1BGEVWeGsApjd"
AccessKeySec="cdsRObozc9VX2NkZdcdsddstLRwdX"
DNS_Server="dns23.hichina.com"

# Domian "DomainName" "RecordId"
# Do not know "RecordId", please leave it blank. as follows
# Domain "beijixs.cn" "www"
#
Domain "beijixs.cn" "blog" 

使用简单,修改配置文件即可(注意脚本中指定的配置文件路径)


查看解析情况

更新记录

IPv6暂时没有做
Last modification:November 2nd, 2019 at 07:02 pm
If you think my article is useful to you, please feel free to appreciate