====== Backup ====== The idea behind this script came when I needed to secure my configuration in Cloudflare. Data you don't control you don't own, so if my configuration only existed in Cloudflare was is to prevent it from being deleted or corrupted. Digging into it I found that it wasn't all that difficult to extract the important parts and have a local copy. The tricky part was to save it in a format that could easily be restored. So, with that in mind I created a series of scripts which could help me take back control, and if needed, move to a new provider. ===== The Script ===== The script makes use of a file called "zones.txt" which is populated in the first statement in the script. With an API token it extracts all the zones and pipe them to the "zones.txt" file which then is used as input for the actual backup of the records. It doesn't take into account all types of records but the ones that are important to me. It though export a raw dump of all records in a "full-backup" file, so it is possible to form it to your needs. At the end of the day all data is being backed up. #!/bin/bash # Set your Cloudflare API credentials CF_API_TOKEN="xxx" # Get all zones page=0 output_count=1 while [ $output_count -gt 0 ] do ((page=page+1)) x=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?page=$page" -H "Authorization: Bearer $CF_API_TOKEN" |jq -r '.result[] | .name') output_count=$(echo $x|wc -w) zone_list="$zone_list $x" done echo $zone_list | tr ' ' '\n' > zones.txt # Read the input file and create backups of DNS records for each zone while read -r name; do echo "Creating backup for zone: $name" # Lookup the zone ID for the domain name ZONE_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$name" \ -H "Authorization: Bearer $CF_API_TOKEN" \ -H "Content-Type: application/json" | jq -r '.result[0].id') # Make sure the zone ID is valid if [[ "$ZONE_ID" == "null" ]]; then echo "Invalid zone ID for domain name: $name" continue fi # Get a list of all DNS records for the specified zone RECORDS=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \ -H "Authorization: Bearer $CF_API_TOKEN" \ -H "Content-Type: application/json") # Extract the record attributes from the JSON response and save them to a file echo "$RECORDS" | jq -r '.result[]' > "$name-full-backup.csv" echo "$RECORDS" | jq -r '.result[] | select(.type == "A" or .type == "CNAME" or .type == "AAAA") | [.type, .name, .content, .ttl, .proxied, .comment] | @csv' | sed 's/"//g' >> "$name-backup.csv" echo "$RECORDS" | jq -r '.result[] | select(.type == "SRV") | [.type, .data.service, .data.proto, .data.name, .data.priority, .data.weight, .data.port, .data.target, .ttl, .proxied, .comment] | @csv' | sed 's/"//g' >> "$name-backup.csv" echo "$RECORDS" | jq -r '.result[] | select(.type == "TXT") | [.type, .name, .content, .ttl, .proxied, .comment] | @csv' | sed 's/"//g' >> "$name-backup.csv" echo "$RECORDS" | jq -r '.result[] | select(.type == "CAA") | [.type, .name, .data.flags, .data.tag, .data.value, .ttl, .proxied, .comment] | @csv' | sed 's/"//g' >> "$name-backup.csv" echo "Backup created for zone: $name" done < zones.txt