#!/bin/bash ### Functions check() { # Verify that required parameters are set IFS=$'\n' for var in ${check_vars[@]}; do var_name=$(echo $var | awk -F, '{ print $1 }') err_msg=$( echo $var | awk -F, '{ print $2 }') [ -z "${!var_name}" ] && error_exit "variable '${var_name}' empty. Error:$err_msg" done } add() { # Add challenge domain to DNS debug "create domain '$acme_domain'" response=`curl --silent \ -X POST https://api360.yandex.net/directory/v1/org/${orgId}/domains/${domain}/dns \ -H "Authorization: OAuth ${OAuth}" \ -H "Content-Type: application/json" \ -d '{"name":"'"$acme_domain"'","type":"TXT","ttl":"3600","text":"'"$token"'"}'` debug "Asked record: {\"name\":\"$acme_domain\",\"type\":\"TXT\",\"ttl\":\"3600\",\"text\":\"$token\"}" debug "Recieved response: \"$response\"" recordId=$(echo $response | jq .recordId) if [ "$recordId" != "null" ]; then # Save recordId for cleanup later mkdir -p -m 0700 $(dirname $recordIdFile) echo $response >> $recordIdFile debug "File '$recordIdFile' created/updated:\n$(sed -E '/^#/d;/^\s*$/d' $recordIdFile)" else err_code=$(echo $response | jq .code) err_message=$(echo $response | jq .message) error_exit "error code: $err_code -- $err_message" fi } del() { # Delete all or specific challenge domains from DNS if [[ "$1" == "cleanup" ]]; then # Cleanup records for specific domain if [ -z "$subdomain" ]; then # Delete all records for domain if 'domain.tld' specimied # Get ALL recordIDs from file debug "all '$domain' domain records will be removed" recordIds=`sed -E '/^#/d;/^\s*$/d' $recordIdFile | jq .recordId` else # Delete all records for specific subdomain only if 'subdomain.domain.tld' specified # Get ALL recordIDs from file for specific domain debug "all '$acme_domain' domain records will be removed" recordIds=`sed -E '/^#/d;/^\s*$/d' $recordIdFile | jq "select(.name == \"$acme_domain\") | .recordId"` fi else # Delete specific records for specific domain or subdomain specified challenge token # Get specific combinations of domain and token debug "'$acme_domain' domain records with token '$token' will be removed" recordIds=`sed -E '/^#/d;/^\s*$/d' $recordIdFile | jq "select(.name == \"$acme_domain\" and .text == \"$token\") | .recordId"` fi # Check selected exist records [ -z "$recordIds" ] && error_exit "can't parse '$recordIdFile' file or matched recordIds not found" # Delete selected records if exist unset not_removed for recordId in $recordIds; do debug "removeing record '$recordId'" del_result=`curl -H "Authorization: OAuth ${OAuth}" --silent \ -X DELETE https://api360.yandex.net/directory/v1/org/${orgId}/domains/${domain}/dns/${recordId}` if [ "$del_result" == "{}" ]; then sed -i "/$recordId/d" $recordIdFile # Remove record from file if it was removed from DNS unset del_msg else not_removed=${not_removed:+$not_removed, }$recordId del_msg=' NOT' fi debug "'$recordId' was$rm_msg removed from DNS and file '$recordIdFile'" done [ -n "$not_removed" ] && error_exit "Something went wrong. Server says: '$del_result' This records was NOT removed: '$not_removed'" } ### Requires requires jq ### Presets # Yandex Authentication credintals orgId=${YANDEX_ORGID:-''} OAuth=${YANDEX_OAUTH:-''} # Let's Encrypt DNS validtaion token token=$3 # Split FQDN to domain and subdomain. Specific for Yandex API fqdn=`echo $2 | grep -Po '^(?:(?!-)[a-z0-9-]{0,62}[a-z0-9]\.)+[a-z]{2,}$'` domain=`echo $fqdn | grep -Po '(?!-)[a-z0-9-]{0,62}[a-z0-9]\.[a-z]{2,}$'` subdomain=`echo $fqdn | sed -E 's/(\.?[^.]+){2}$//'` acme_domain="_acme-challenge${subdomain:+.$subdomain}" recordIdFile=${WORKING_DIR:-/tmp}/getssl_yandex_dns_records debug "FQDN: '$fqdn' Validation token: '$token' Asked domain: '$domain' Asked subdomain: '$subdomain' Record ID file: '$recordIdFile'" # Yandex API returns JSON with recordId as successful result # It's required for remove this record later. Yandex API cant't remove records by names, by recordId only [ -f "$recordIdFile" ] || echo -n " # DON'T EDIT! DON'T DELETE! # This is active Yandex DNS challenge records # Don't remove manually # Just run \`$(cd "$(dirname "$0")" || exit; pwd -P;) cleanup [subdomain.]domain.tld\` " > "$recordIdFile" ### Main process case "$1" in "add" ) check_vars=( "fqdn, No or invalid FQDN" "domain, No or invalid DOMAIN" "token, No challenge token" "orgId, No Yandex OrgID" "OAuth, No Yandex OAuth" ) check add ;; "del" ) check_vars=( "domain, No or invalid DOMAIN" "token, No challenge token" "orgId, No Yandex OrgID" "OAuth, No Yandex OAuth" ) check del ;; "cleanup" ) check_vars=( "domain, No or invalid DOMAIN" "orgId, No Yandex OrgID" "OAuth, No Yandex OAuth" ) check del cleanup ;; * ) echo "Unknown command '$1'. Valid commands: (add|del|cleanup)" ;; esac