User Tools

Site Tools


howtos:backup_zones

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
howtos/backup_zones.txt · Last modified: 08/04/2023 18:39 by domingo