Managing a BIND DNS server with multiple zone files often requires extracting complete DNS record information for auditing, migration, or troubleshooting purposes. Here are efficient methods to gather all A and CNAME records without manual inspection.
The most reliable approach uses BIND's built-in named-checkzone
utility with output formatting:
for zone in $(ls /var/named/*.zone); do
named-checkzone -k fail -o - $(basename $zone .zone) $zone | \
awk '/IN A|IN CNAME/ {print $1,$4,$5}'
done
This command:
- Iterates through all zone files in /var/named
- Validates each zone's syntax while outputting records
- Filters for only A and CNAME records
- Prints hostname, record type, and value
For a faster but less validated approach:
grep -hE 'IN[[:space:]]+(A|CNAME)' /var/named/*.zone | \
awk '{print $1,$4,$5}' | \
sort | uniq
To generate CSV output suitable for spreadsheets:
echo "Host,Type,Value,ZoneFile" > dns_records.csv
for zone in /var/named/*.zone; do
zone_name=$(basename $zone .zone)
named-checkzone -k fail -o - $zone_name $zone | \
awk -v zn="$zone_name" '/IN A|IN CNAME/ {print $1","$4","$5","zn}'
done >> dns_records.csv
For servers with hundreds of zone files, consider parallel processing:
find /var/named -name "*.zone" -print0 | \
xargs -0 -P 8 -I {} sh -c '\
named-checkzone -k fail -o - $(basename {} .zone) {} | \
awk '\''/IN A|IN CNAME/ {print $1,$4,$5}'\'' \
' > all_dns_records.txt
When managing a BIND DNS server with numerous zone files, manually parsing each file for A and CNAME records becomes impractical. Here's how to automate this process using standard DNS tools and scripting.
If AXFR transfers are enabled, you can retrieve all records for a zone with:
dig @your_dns_server example.com AXFR
However, this requires proper permissions and may not be available in all configurations.
For direct zone file processing, this Bash script recursively searches for zone files and extracts records:
#!/bin/bash ZONE_PATH="/var/named/zones/" RECORD_TYPES=("A" "CNAME") for zone_file in $(find $ZONE_PATH -type f -name "*.db"); do echo "Processing $zone_file" for record_type in "${RECORD_TYPES[@]}"; do grep -E "^[^;].*IN[[:space:]]+$record_type" $zone_file | while read -r line; do echo "$zone_file: $line" done done done
Combine your extraction with BIND's built-in validation tool:
for zone in $(ls /etc/named/*.zone); do zone_name=$(basename $zone .zone) named-checkzone $zone_name $zone grep -E 'IN[[:space:]]+(A|CNAME)' $zone done
For more advanced processing, this Python script handles zone files more robustly:
import os import re def parse_zone_files(root_path): record_pattern = re.compile(r'^([^\s;]+)\s+.*?\s+IN\s+(A|CNAME)\s+(.*)$', re.M) for root, _, files in os.walk(root_path): for file in files: if file.endswith('.db'): with open(os.path.join(root, file)) as f: content = f.read() for match in record_pattern.finditer(content): print(f"File: {file} | Record: {match.group(0)}") parse_zone_files('/var/named/zones')
For servers hosting hundreds of zones, consider:
- Processing files in parallel with GNU parallel
- Implementing output filtering to focus on specific record patterns
- Caching results for subsequent queries