Updated the script so you no longer need to specify zones. The zones will be looked up against the account and it will pull down and zones into seperate config files. This means that the config file now only needs one API key from the account that has Zone:Read and DNS:Read permissions.

This commit is contained in:
Phil 2025-08-25 21:17:15 +01:00
parent 782afb0658
commit 44c7ea4b64
3 changed files with 132 additions and 54 deletions

View File

@ -1,24 +1,115 @@
# Export_DNS # Cloudflare DNS Export Script
## Cloudflare
### Config File This script automates exporting DNS records for all zones in a Cloudflare account.
Add your Cloudflare API key here. The key need to be able to read any DNS zones that you list below It uses the Cloudflare **API Token** authentication method (recommended for security).
```
API_KEY=your_single_api_key Each run saves the DNS export of every zone into an `export/` folder, with filenames containing the zone name and a timestamp.
---
## 📦 Requirements
- **bash** (any modern Linux/macOS environment will work)
- **curl**
- **jq** (for parsing JSON)
Install `jq` if you dont already have it:
```bash
# Ubuntu/Debian
sudo apt install jq -y
# macOS (Homebrew)
brew install jq
``` ```
Add the Zone ID to the zone_id_value section and set the site_name_value to the name of the domain. This will be the name of the file that is created with the DNS infomation. ---
```
ZONE_ID_1=zone_id_value_1
SITE_NAME_1=site_name_value_1
ZONE_ID_2=zone_id_value_2 ## ⚙️ Setup
SITE_NAME_2=site_name_value_2
1. Clone or copy these files:
- `import_dns_records.sh`
- `config.conf`
2. Edit the `config.conf` file and add your **Cloudflare API Token**:
```bash
# config.conf
CLOUDFLARE_API_TOKEN=your_api_token_here
``` ```
### The Script > 🔑 When creating your API Token in Cloudflare Dashboard, give it at least:
Inside the script is the following below (Line 7) > - **Zone: Read**
> - **DNS: Read**
---
## ▶️ Usage
Make the script executable:
```bash
chmod +x import_dns_records.sh
``` ```
EXPORT_FOLDER="export"
Run the script:
```bash
./import_dns_records.sh
``` ```
Change the value from export, to the location that the script should export the files to (E.g. /folder1/folder2/)
---
## 📂 Output
- All exports are saved into the `export/` folder.
- Each export is a plain text file containing the zones DNS records in BIND format.
- Filenames follow the format:
```
export/<zone_name>_<YYYYMMDD>_<HHMMSS>.txt
```
Example:
```
export/example.com_20250825_153012.txt
export/testdomain.net_20250825_153015.txt
```
---
## 🔒 Security Notes
- Never commit `config.conf` (it contains your API token).
- Limit API token permissions to the minimum required (Zone:Read, DNS:Read).
- Rotate API tokens periodically for best security practices.
---
## ✅ Example Workflow
```bash
# 1. Configure your token
echo 'CLOUDFLARE_API_TOKEN=abc123xyz...' > config.conf
# 2. Run the export
./import_dns_records.sh
# 3. Check the export folder
ls export/
```
---
## 🛠 Troubleshooting
- **Empty export files?**
Ensure your API Token has the correct permissions (Zone:Read, DNS:Read).
- **Script fails with `jq: command not found`?**
Install `jq` as shown above.
- **Only some zones exported?**
Check the API Tokens scope. If it was created for a specific zone, it wont return all zones.
Create a token scoped for “All zones - Read” to export everything.

View File

@ -1,9 +1,2 @@
API_KEY=your_single_api_key # Cloudflare API Token (must have Zone:Read + DNS:Read permissions)
CLOUDFLARE_API_TOKEN=your_api_token_here
ZONE_ID_1=zone_id_value_1
SITE_NAME_1=site_name_value_1
ZONE_ID_2=zone_id_value_2
SITE_NAME_2=site_name_value_2
# Add more entries as needed

52
Cloudflare/export_dns_cloudflare.sh Normal file → Executable file
View File

@ -1,44 +1,38 @@
#!/bin/bash #!/bin/bash
set -euo pipefail
# Source the configuration file # Load config
source config.conf source config.conf
# Create the export folder if it doesn't exist
EXPORT_FOLDER="export" EXPORT_FOLDER="export"
mkdir -p "$EXPORT_FOLDER" mkdir -p "$EXPORT_FOLDER"
# Function to export DNS records # Step 1: Fetch all zones from Cloudflare
export_dns_records() { echo "Fetching zone list from Cloudflare..."
local ZONE_ID=$1 zones_json=$(curl -s https://api.cloudflare.com/client/v4/zones \
local SITE_NAME=$2 -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json")
# Get current date and time # Step 2: Parse zones (needs jq)
TIMESTAMP=$(date +"%Y%m%d_%H%M%S") zone_count=$(echo "$zones_json" | jq '.result | length')
echo "Found $zone_count zones."
# Define the output filename with timestamp # Step 3: Loop through zones
OUTPUT_FILE="$EXPORT_FOLDER/${SITE_NAME}_$TIMESTAMP" for ((i=0; i<zone_count; i++)); do
ZONE_ID=$(echo "$zones_json" | jq -r ".result[$i].id")
SITE_NAME=$(echo "$zones_json" | jq -r ".result[$i].name")
# Perform the curl request and save the output TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
curl -X GET --url https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/export \ OUTPUT_FILE="$EXPORT_FOLDER/${SITE_NAME}_$TIMESTAMP.txt"
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" | tee "$OUTPUT_FILE"
}
# Loop through the configuration entries echo "Exporting DNS records for $SITE_NAME..."
i=1
while true; do
eval "ZONE_ID=\${ZONE_ID_$i}"
eval "SITE_NAME=\${SITE_NAME_$i}"
# Break the loop if no more entries curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/export" \
if [ -z "$ZONE_ID" ] || [ -z "$SITE_NAME" ]; then -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
break -H "Content-Type: application/json" | tee "$OUTPUT_FILE"
fi
# Export DNS records for the current entry echo " -> Saved to $OUTPUT_FILE"
export_dns_records "$ZONE_ID" "$SITE_NAME"
# Increment the counter
((i++))
done done
echo "✅ All exports complete. Files are in the '$EXPORT_FOLDER' folder."