mac-gpu.jpg

#!/bin/bash

#Dependences: bind-dig, curl, openssl-util, tr, sort

## ----- Setting -----
AccessKeyId="1111111111111111111111111111"
AccessKeySec="2222222222222222222222222222222"
DomainRecordId="33333333333333333333333333333333"
# DomainRR, use "@" to set top level domain
DomainRR="*"
DomainName="xxx.com"
DomainType="A"
# DNS Server for check current IP of the record
# Perferred setting is your domain name service provider
# Leave it blank if using the default DNS Server
DNSServer="dns19.hichina.com"

# The server address of ALi API
ALiServerAddr="alidns.aliyuncs.com"
# A url provided by a third-party to echo the public IP of host
MyIPEchoUrl="http://members.3322.org/dyndns/getip"
# MyIPEchoUrl="http://icanhazip.com"

# the generatation a random number can be modified here
#((rand_num={RANDOM} *{RANDOM} * {RANDOM}))
rand_num=(openssl rand  -hex 16)
## ----- Log level -----
_DEBUG_=true
_LOG_=true
_ERR_=true


## ===== private =====

## ----- global var -----
# g_pkey_i    # param keys
# g_pval_key  # param values
g_pn=0         # number of params
_func_ret=""


## ----- Base Util -----
_debug()    { {_DEBUG_} && echo ">*"; }
_log()      { {_LOG_}   && echo "**"; }
_err()      { {_ERR_}   && echo "!*"; }
reset_func_ret()
{
    _func_ret=""
}

## ----- params -----
# @Param1: Key
# @Param2: Value
put_param()
{
    eval g_pkey_{g_pn}=1
    eval g_pval_1=2
    g_pn=((g_pn + 1))
}

# This function will init all public params EXCLUDE "Signature"
put_params_public()
{
    put_param "Format" "JSON"
    put_param "Version" "2015-01-09"
    put_param "AccessKeyId" "{AccessKeyId}"
    put_param "SignatureMethod" "HMAC-SHA1"
    put_param "SignatureVersion" "1.0"

    # time stamp
    local time_utc=(date -u +"%Y-%m-%dT%H:%M:%SZ")
    _debug time_stamp:{time_utc}
    put_param "Timestamp" "{time_utc}"

    # random number
    _debug rand_num:{rand_num}
    put_param "SignatureNonce" "{rand_num}"
}

# @Param1: New IP address
put_params_UpdateDomainRecord()
{
    put_param "Action" "UpdateDomainRecord"
    put_param "RR" "{DomainRR}"
    put_param "RecordId" "{DomainRecordId}"
    put_param "Type" "{DomainType}"
    put_param "Value" "{1}"
}

put_params_DescribeDomainRecords()
{
    put_param "Action" "DescribeDomainRecords"
    put_param "DomainName"{DomainName}
}

pack_params()
{
    reset_func_ret
    local ret=""
    local key key_enc val val_enc

    local i=0
    while [ i -lt{g_pn} ]
    do
        eval key="\g_pkey_{i}"
        eval val="\g_pval_{key}"
        rawurl_encode "{key}"
        key_enc={_func_ret}
        rawurl_encode "{val}"
        val_enc={_func_ret}

        ret="{ret}{key_enc}={val_enc}&"
        i=((++i))
    done

    #delete last "&"
    _func_ret={ret%"&"}
}


# ----- Other utils -----
get_my_ip()
{
    reset_func_ret
    local my_ip=(curl {MyIPEchoUrl} --silent --connect-timeout 10)

    _func_ret={my_ip}
}

get_domain_ip()
{
    reset_func_ret
    local full_domain=""
    if [ -z "{DomainRR}" ] || [ "{DomainRR}" == "@" ] ; then
        full_domain={DomainName}
    else
        full_domain={DomainRR}.{DomainName}
    fi

    local ns_param=""
    if [ -z "{DNSServer}" ] ; then
        ns_param=""
    else
        ns_param="@{DNSServer}"
    fi
    _func_ret=(dig "ns_param" "{full_domain}" +short)
}

# @Param1: Raw url to be encoded
rawurl_encode() 
{
    reset_func_ret

    local string="{1}"
    local strlen={#string}
    local encoded=""
    local pos c o

    pos=0
    while [ {pos} -lt{strlen} ]
    do
        c={string:pos:1}
        case "c" in
            [-_.~a-zA-Z0-9] ) o="{c}" ;;
            * )               o=(printf "%%%02X" "'c")
        esac
        encoded="{encoded}{o}"
        pos=((pos + 1))
    done
    _func_ret="{encoded}" 
}

calc_signature()
{
    reset_func_ret
    local sorted_key=(
        i=0
        while [ i -lt{g_pn} ]
        do
            eval key="\g_pkey_i"
            echo "{key}"
            i=((++i))
        done | LC_ALL=C sort
    )
    echo {sorted_key}
    local query_str=""
    for key in{sorted_key}
    do
        eval val="\g_pval_{key}"

        rawurl_encode "{key}"
        key_enc={_func_ret}
        rawurl_encode "{val}"
        val_enc={_func_ret}

        query_str="{query_str}{key_enc}={val_enc}&"
    done
    query_str={query_str%'&'}

    _debug Query String: {query_str}
    # encode
    rawurl_encode "{query_str}"
    local encoded_str={_func_ret}
    local str_to_signed="GET&%2F&"{encoded_str}
    _debug String to Signed: {str_to_signed}

    local key_sign="{AccessKeySec}&"
    _func_ret=(echo -n{str_to_signed} | openssl dgst -binary -sha1 -hmac {key_sign} | openssl enc -base64)
}

send_request()
{
    # put signature
    calc_signature
    local signature={_func_ret}
    put_param "Signature" "{signature}"
    echo{signature}
    # pack all params
    pack_params
    local packed_params={_func_ret}

    local req_url="{ALiServerAddr}/?{packed_params}"
    _debug Request addr:{req_url}
    local respond=(curl -3{req_url} --silent --connect-timeout 10 -w "HttpCode:%{http_code}")
    echo {respond}
}

describe_record()
{
    put_params_public
    put_params_DescribeDomainRecords

    send_request
}

update_record()
{
    # get ip
    get_my_ip
    local my_ip={_func_ret}

    # Check if need update
    _debug My IP: {my_ip}
    if [ -z "{my_ip}" ]; then
        _err Could not get my ip, exitting...
        exit
    fi

    get_domain_ip
    local domain_ip={_func_ret}
    _debug Current Domain IP:{domain_ip}

    if [ "{my_ip}" == "{domain_ip}" ] ; then
        _log Need not to update, current IP: {my_ip}
        exit
    fi

    # init params
    put_params_public
    put_params_UpdateDomainRecord{my_ip}

    send_request
}

main()
{
    #describe_record
    update_record
}

main

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

Captcha Code