#!/usr/bin/env bash # need to add your email address and API key to cloudflare below or set as env variables email=${CF_EMAIL:-''} key=${CF_KEY:-''} fulldomain="${1:?Need full domain name as first parameter}" token="$2" # If not set try to remove all tokens for fulldomain API='https://api.cloudflare.com/client/v4/zones' PARAMS=( -H "X-Auth-Email: $email" -H "X-Auth-Key: $key" -H 'Content-Type: application/json' ) # get a list of all domain names from cloudflare # If you have a lot, you may need add "&page=1&per_page=1000" and/or "&status=active" resp=$(curl --silent "${PARAMS[@]}" -X GET "$API") re='"result":\[(([^][]*\[[^][]*])*[^][]*)]' # find result section [[ "${resp// }" =~ $re ]] && resp="${BASH_REMATCH[1]}" while [[ "$resp" ]]; do # iterate through domains returned re='[^}{]*\{(([^}{]*\{[^}{]*})*[^}{]*)}(.*)' [[ "$resp" =~ $re ]]; first="${BASH_REMATCH[1]}"; resp="${BASH_REMATCH[3]}" # remove subsections - leave only domain level while [[ "$first" =~ (.*)[\[\{][^]\{\}[]*[\]\}](.*) ]]; do first="${BASH_REMATCH[1]}${BASH_REMATCH[2]}"; done re='"name":"([^"]*)"'; [[ "$first" =~ $re ]] && domains=( "${domains[@]}" "${BASH_REMATCH[1]}" ) re='"id":"([^"]*)"'; [[ "$first" =~ $re ]] && ids=( "${ids[@]}" "${BASH_REMATCH[1]}" ) done # select right cloudflare domain (longest one) domain=$fulldomain. # shellcheck disable=SC2076 while [[ "$domain" && ! "${domains[@]/#/@}" == *"@${domain%?}"* ]]; do domain=${domain#*.}; done domain=${domain%?} [ -z "$domain" ] && { echo 'domain name not found on your cloudflare account'; exit 1; } for i in "${!domains[@]}"; do [[ ${domains[i]} == "$domain" ]] && break; done domain_id=${ids[i]} resp=$(curl --silent "${PARAMS[@]}" -X GET "$API/$domain_id/dns_records?type=TXT&name=_acme-challenge.$fulldomain${token:+&content=$token}") re='"result":\[(([^][]*\[[^][]*])*[^][]*)]' # find result section [[ "${resp// }" =~ $re ]] && resp="${BASH_REMATCH[1]}" [ -z "$resp" ] && { echo 'challenge TXT record not found on your cloudflare account'; exit 2; } while [[ "$resp" ]]; do # iterate through records returned re='[^}{]*\{(([^}{]*\{[^}{]*})+[^}{]*)}(.*)' [[ "$resp" =~ $re ]]; first="${BASH_REMATCH[1]}"; resp="${BASH_REMATCH[3]}" re='"id":"([^"]*)"'; [[ "$first" =~ $re ]] && id="${BASH_REMATCH[1]}" respd=$(curl --silent "${PARAMS[@]}" -X DELETE "$API/$domain_id/dns_records/$id") if [[ "${respd// }" == *'"success":false'* ]]; then re='"message":"([^"]+)"'; [[ "$respd" =~ $re ]] echo "Error: DNS challenge not deleted: ${BASH_REMATCH[1]:-unknown error}"; exit 3 fi done