#!/bin/bash #========================================= # Author : Colben # Create : 2022-04-11 19:48 #========================================= set -euo pipefail export LANG=en_US.UTF-8 trap Quit EXIT ACCESS_KEY_ID='aliyun access key id' ACCESS_KEY_SECRET='aliyun access key secret' DOMAIN=$CERTBOT_DOMAIN SUB_DOMAIN=_acme-challenge RECORD_ID= RECORD_VA=$CERTBOT_VALIDATION PID_FILE=/tmp/$(basename ${0%.sh}).pid if [ -t 0 ]; then function Print { echo -e "\033[32;1m$(date +'[%F %T]') $*\033[0m"; } function Warn { echo -e "\033[33;1m$(date +'[%F %T]') $*\033[0m"; } function Error { echo -e "\033[31;1m$(date +'[%F %T]') $*\033[0m"; exit 1; } else #exec &> ${0%.sh}.out function Print { echo -e "$(date +'[%F %T] INFO') $*"; } function Warn { echo -e "$(date +'[%F %T] WARN') $*"; } function Error { echo -e "$(date +'[%F %T] ERROR') $*"; exit 1; } fi function Quit { local exitCode=$? [ 0 -ne $exitCode ] && Error Failed to request aliyun api! [ -z "${END:-}" ] && echo && Error Interrupted manually! Print Succeeded to request aliyun api and wait 30 seconds. sleep 30 } function GetSignature { local uriEncoded="GET&%2F&$(echo "$1" | sed -e 's/=/%3D/g' -e 's/:/%253A/g' -e 's/&/%26/g')" local sha1Str=$(echo -n "$uriEncoded" | openssl dgst -sha1 -hmac "$ACCESS_KEY_SECRET&" -binary) echo -n "$sha1Str" | base64 | sed -e 's/=/%3D/g' -e 's/+/%2B/g' -e 's,/,%2F,g' } function ListRecord { Warn Get request uri ... local sign= local resp= local uri="AccessKeyId=$ACCESS_KEY_ID" uri="${uri}&Action=DescribeDomainRecords" uri="${uri}&DomainName=$DOMAIN" uri="${uri}&Format=JSON" uri="${uri}&KeyWord=$SUB_DOMAIN" uri="${uri}&SearchMode=EXACT" uri="${uri}&SignatureMethod=HMAC-SHA1" uri="${uri}&SignatureNonce=$RANDOM" uri="${uri}&SignatureVersion=1.0" uri="${uri}&Timestamp=$(date +'%FT%TZ' -d'8 hours ago')" uri="${uri}&Type=TXT" uri="${uri}&Version=2015-01-09" sign=$(GetSignature "$uri") Warn List record ... resp=$(curl -sSL -XGET "http://alidns.aliyuncs.com/?$uri&Signature=$sign" | jq -eM .) RECORD_ID=$(echo $resp | jq -crM .DomainRecords.Record[].RecordId) [ 'null' == "$RECORD_ID" ] && echo "$resp" && exit 1 return 0 } function CreateRecord { Warn Get request uri ... local sign= local resp= local uri="AccessKeyId=$ACCESS_KEY_ID" uri="${uri}&Action=AddDomainRecord" uri="${uri}&DomainName=$DOMAIN" uri="${uri}&Format=JSON" uri="${uri}&RR=$SUB_DOMAIN" uri="${uri}&SignatureMethod=HMAC-SHA1" uri="${uri}&SignatureNonce=$RANDOM" uri="${uri}&SignatureVersion=1.0" uri="${uri}&Timestamp=$(date +'%FT%TZ' -d'8 hours ago')" uri="${uri}&Type=TXT" uri="${uri}&Value=$RECORD_VA" uri="${uri}&Version=2015-01-09" sign=$(GetSignature "$uri") Warn Create sub_domain: $SUB_DOMAIN with value: $RECORD_VA ... resp=$(curl -sSL -XGET "http://alidns.aliyuncs.com/?$uri&Signature=$sign" | jq -eM .) [ 'null' != "$(echo $resp | jq -crM .Message)" ] && echo "$resp" && exit 1 return 0 } function ModifyRecord { Warn Get request uri ... local sign= local resp= local uri="AccessKeyId=$ACCESS_KEY_ID" uri="${uri}&Action=UpdateDomainRecord" uri="${uri}&DomainName=$DOMAIN" uri="${uri}&Format=JSON" uri="${uri}&RR=$SUB_DOMAIN" uri="${uri}&RecordId=$RECORD_ID" uri="${uri}&SignatureMethod=HMAC-SHA1" uri="${uri}&SignatureNonce=$RANDOM" uri="${uri}&SignatureVersion=1.0" uri="${uri}&Timestamp=$(date +'%FT%TZ' -d'8 hours ago')" uri="${uri}&Type=TXT" uri="${uri}&Value=$RECORD_VA" uri="${uri}&Version=2015-01-09" sign=$(GetSignature "$uri") Warn Modify record: $RECORD_ID with value: $RECORD_VA ... resp=$(curl -sSL -XGET "http://alidns.aliyuncs.com/?$uri&Signature=$sign" | jq -eM .) [ 'null' != "$(echo $resp | jq -crM .Message)" ] && echo "$resp" && exit 1 return 0 } function DeleteRecord { Warn Get request uri ... local sign= local resp= local uri="AccessKeyId=$ACCESS_KEY_ID" uri="${uri}&Action=DeleteDomainRecord" uri="${uri}&DomainName=$DOMAIN" uri="${uri}&Format=JSON" uri="${uri}&RecordId=$RECORD_ID" uri="${uri}&SignatureMethod=HMAC-SHA1" uri="${uri}&SignatureNonce=$RANDOM" uri="${uri}&SignatureVersion=1.0" uri="${uri}&Timestamp=$(date +'%FT%TZ' -d'8 hours ago')" uri="${uri}&Version=2015-01-09" sign=$(GetSignature "$uri") Warn Delete record $RECORD_ID ... resp=$(curl -sSL -XGET "http://alidns.aliyuncs.com/?$uri&Signature=$sign" | jq -eM .) [ 'null' != "$(echo $resp | jq -crM .Message)" ] && echo "$resp" && exit 1 return 0 } function Main { [ -e "$PID_FILE" ] && Error Pid file $PID_FILE already exists, quit! echo $$ > $PID_FILE for _ in {1..5}; do ListRecord || continue if [ -z "$RECORD_ID" ]; then CreateRecord || continue else ModifyRecord || continue fi END=1 return 0 done return 1 } # Start here Main