| @ -1,43 +1,44 @@ | |||
| #!/usr/bin/env bash | |||
| email="" | |||
| key="" | |||
| # need to add your email address and key to cloudflare below | |||
| email='' | |||
| key='' | |||
| fulldomain="$1" | |||
| token="$2" | |||
| API='https://api.cloudflare.com/client/v4/zones' | |||
| AUTH=( -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" | |||
| resp=$(curl --silent "${AUTH[@]}" -X GET "$API?match=all&status=active") | |||
| # treat all names with dot as domain names | |||
| while read -d ' ' i; do | |||
| [[ $i =~ \"name\":\"([^\"]+\.[^\"]+)\" ]] && all_domains="${all_domains:+$all_domains }${BASH_REMATCH[1]}" | |||
| done <<<${resp//[ ,\[\{\}\]]/ } | |||
| [ -z "$all_domains" ] && { echo 'no active domains found on your cloudflare account'; exit 1; } | |||
| # select right CF domain (longest one) | |||
| domain=$fulldomain. | |||
| while [[ "$domain" && ! "$all_domains" =~ "${domain%?}" ]]; do domain=${domain#*.}; done | |||
| domain=${domain%?} | |||
| [ -z "$domain" ] && { echo 'domain name not found on your cloudflare account'; exit 1; } | |||
| resp=$(curl --silent "${AUTH[@]}" -X GET "$API?name=$domain&match=any&status=active") | |||
| # select result section | |||
| [[ "$resp" =~ \"result\"[^\{]*\{([^\{\}]*\{[^\{\}]*\}[^\{\}]*)+\} ]] | |||
| resp="${BASH_REMATCH[0]%\}*}"; resp="${resp#*\{}" | |||
| # remove subsections - leave only domain level | |||
| while [[ "$resp" =~ (.*)[\[\{][^]\{\}[]*[\]\}](.*) ]]; do resp="${BASH_REMATCH[1]}${BASH_REMATCH[2]}"; done | |||
| # must match - we ask for already verified domain | |||
| [[ "${resp// }" =~ \"id\":\"([^\"]+)\" ]] | |||
| domain_id=${BASH_REMATCH[1]} | |||
| # get a list of all domain names from cloudflare. If you have a lot, you may need | |||
| # "status=active&page=1&per_page=1000&match=all" instead of just "match=all" | |||
| all_domains=$(curl --silent -X GET "https://api.cloudflare.com/client/v4/zones?match=all" \ | |||
| -H "X-Auth-Email: ${email}" -H "X-Auth-Key: ${key}" -H "Content-Type: application/json" \ | |||
| | grep -o "\"name\":\"[^\"]*\"" | awk -F'"' '{print $4}') | |||
| NumParts=$(echo "$fulldomain" | awk -F"." '{print NF}') | |||
| i=1 | |||
| while [ $i -lt "$NumParts" ]; do | |||
| let parts=NumParts-i | |||
| testpart=$(echo "$fulldomain" |awk -v n=$parts -F\. '{for (i=n; i<NF; i++) printf $i "."; printf $NF}') | |||
| res=$(echo "$all_domains" | grep -c "$testpart") | |||
| if [[ "$res" == "1" ]]; then | |||
| domain=$(echo "$all_domains" | grep "$testpart") | |||
| let i=NumParts | |||
| fi | |||
| let i=i+1 | |||
| done | |||
| if [ -z "$domain" ]; then | |||
| echo "domain name can't be found on your cloudflare account" | |||
| exit 1 | |||
| fi | |||
| txtname=$( echo "_acme-challenge.${fulldomain}" | sed "s/.${domain}//") | |||
| response=$(curl --silent -X GET "https://api.cloudflare.com/client/v4/zones?name=${domain}&match=all" \ | |||
| -H "X-Auth-Email: ${email}" -H "X-Auth-Key: ${key}" -H "Content-Type: application/json") | |||
| domain_section=$(echo "$response" | awk -F"[}]" '{for(i=1;i<=NF;i++){if($i~/\"'"${domain}"'\"/){print $i}}}') | |||
| domain_id=$(echo "$domain_section" | awk -F"[,:}]" '{for(i=1;i<=NF;i++){if($i~/\"'"id"'\"/){print $(i+1)}}}'| awk -F'"' '{print $2}') | |||
| response=$(curl --silent -X POST "https://api.cloudflare.com/client/v4/zones/${domain_id}/dns_records" \ | |||
| -H "X-Auth-Email: ${email}" -H "X-Auth-Key: ${key}" -H "Content-Type: application/json" \ | |||
| --data "{\"type\":\"TXT\",\"name\":\"${txtname}\",\"content\":\"$token\",\"ttl\":300}") | |||
| curl --silent "${AUTH[@]}" -X POST "$API/$domain_id/dns_records" \ | |||
| --data "{\"type\":\"TXT\",\"name\":\"_acme-challenge.${fulldomain%.$domain}\",\"content\":\"$token\",\"ttl\":300}" | |||