In a typical Virtualmin setup, BIND configuration files are stored under /etc/bind/ (or /var/named/ depending on the OS), while zone files are usually located in /var/lib/bind/ or a similar directory defined in the configuration. When DNSSEC is enabled via Virtualmin, the DNSSEC keys are stored separately, commonly within the same zone directory or in a dedicated path such as /var/lib/bind/keys/ or /etc/bind/keys/.
It is important to note that using the Webmin “Backup Configuration Files” feature alone is not sufficient to fully restore a BIND master server in Virtualmin. This backup typically includes configuration files but does not reliably cover DNSSEC key material. To ensure a complete and functional migration, DNSSEC keys must be manually archived and transferred to the new server. After copying, they must be placed in the correct directory with proper ownership and permissions so that BIND can load them correctly. Without these keys, DNSSEC-signed zones will fail to validate, leading to resolution issues.
Backup in local server, Debian 12.
#!/bin/bash
# ==========================================
# DNSSEC atslēgu dublēšanas skripts (Debian 12 + Virtualmin)
# Dublē tikai /var/lib/bind/ (K*.key, K*.private, *.signed)
# Izveido vienu arhīvu tar.gz – bez mapēm
# Saglabā tikai pēdējās 3 kopijas
# Faila nosaukumā iekļauts pilnais hostname
# ==========================================
BACKUP_DATE=$(date +%Y%m%d-%H%M%S)
HOSTNAME_FULL=$(hostname -f 2>/dev/null || hostname)
BACKUP_DIR="/root/dnssec-backups"
ARCHIVE_FILE="$BACKUP_DIR/${HOSTNAME_FULL}-dnssec-backup-$BACKUP_DATE.tar.gz"
LIST_FILE="/tmp/dnssec_filelist.txt"
SOURCE_DIR="/var/lib/bind"
mkdir -p "$BACKUP_DIR"
echo ""
echo "==== DNSSEC BACKUP STARTED: $(date) ===="
if [ ! -d "$SOURCE_DIR" ]; then
echo "Kļūda: Mape $SOURCE_DIR neeksistē!"
exit 1
fi
# Atrodam DNSSEC failus
find "$SOURCE_DIR" -type f \( -name "K*.key" -o -name "K*.private" -o -name "*.signed" \) > "$LIST_FILE"
if [ ! -s "$LIST_FILE" ]; then
echo "Brīdinājums: DNSSEC atslēgas netika atrastas mapē $SOURCE_DIR."
rm -f "$LIST_FILE"
exit 0
fi
# Izveido arhīvu ar failiem tikai nosaukuma līmenī (bez mapēm)
tar -czf "$ARCHIVE_FILE" -T "$LIST_FILE" --transform='s:.*/::' --warning=no-file-changed
# Iztīra pagaidu sarakstu
rm -f "$LIST_FILE"
echo "DNSSEC backup izveidots: $ARCHIVE_FILE"
# ==========================================
# Saglabā tikai pēdējās 3 kopijas
# ==========================================
cd "$BACKUP_DIR" || exit 1
COUNT=$(ls ${HOSTNAME_FULL}-dnssec-backup-*.tar.gz 2>/dev/null | wc -l)
if [ "$COUNT" -gt 3 ]; then
REMOVE_COUNT=$((COUNT - 3))
REMOVE_FILES=$(ls -1t ${HOSTNAME_FULL}-dnssec-backup-*.tar.gz | tail -n "$REMOVE_COUNT")
echo "Dzēšu vecāko/vecākos backup failus:"
echo "$REMOVE_FILES"
echo "$REMOVE_FILES" | xargs rm -f --
fi
echo "==== BACKUP COMPLETED: $(date) ===="
exit 0
Backup to remote server via ssh.
Change this with Your server info.
REMOTE_USER=”root”
REMOTE_HOST=”remoteserver.hostname or ip address”
REMOTE_PORT=”2322″
REMOTE_PATH=”/root/dnsbackup/”
#!/bin/bash
# ======================================================
# DNSSEC atslēgu dublēšanas skripts (Debian 12 + Virtualmin)
# Dublē /var/lib/bind (K*.key, K*.private, *.signed)
# Izveido tar.gz arhīvu bez mapēm
# Saglabā pēdējās 3 kopijas
# Nosūta arhīvu uz attālinātu serveri caur SCP (ar custom portu)
# ======================================================
BACKUP_DATE=$(date +%Y%m%d-%H%M%S)
HOSTNAME_FULL=$(hostname -f 2>/dev/null || hostname)
BACKUP_DIR="/root/dnssec-backups"
ARCHIVE_FILE="$BACKUP_DIR/${HOSTNAME_FULL}-dnssec-backup-$BACKUP_DATE.tar.gz"
LIST_FILE="/tmp/dnssec_filelist.txt"
SOURCE_DIR="/var/lib/bind"
# ====== attālinātā backup konfigurācija ======
REMOTE_USER="root"
REMOTE_HOST="remoteserver.hostname or ip address"
REMOTE_PORT="2322" # Maini uz savu SSH portu (noklus. 22)
REMOTE_PATH="/root/dnsbackup/"
# ==============================================
mkdir -p "$BACKUP_DIR"
echo ""
echo "==== DNSSEC BACKUP STARTED: $(date) ===="
# Pārbauda direktoriju
if [ ! -d "$SOURCE_DIR" ]; then
echo "Kļūda: mape $SOURCE_DIR neeksistē!"
exit 1
fi
# Atrod DNSSEC failus
find "$SOURCE_DIR" -type f \( -name "K*.key" -o -name "K*.private" -o -name "*.signed" \) > "$LIST_FILE"
if [ ! -s "$LIST_FILE" ]; then
echo "Brīdinājums: DNSSEC faili netika atrasti $SOURCE_DIR"
rm -f "$LIST_FILE"
exit 0
fi
# Izveido arhīvu (bez mapju struktūras)
tar -czf "$ARCHIVE_FILE" -T "$LIST_FILE" --transform='s:.*/::' --warning=no-file-changed
rm -f "$LIST_FILE"
echo "DNSSEC backup izveidots: $ARCHIVE_FILE"
# ====== dzēš vecākos failus (saglabā 3 pēdējos) ======
cd "$BACKUP_DIR" || exit 1
COUNT=$(ls ${HOSTNAME_FULL}-dnssec-backup-*.tar.gz 2>/dev/null | wc -l)
if [ "$COUNT" -gt 3 ]; then
REMOVE_COUNT=$((COUNT - 3))
REMOVE_FILES=$(ls -1t ${HOSTNAME_FULL}-dnssec-backup-*.tar.gz | tail -n "$REMOVE_COUNT")
echo "Dzēšu vecākos backup failus:"
echo "$REMOVE_FILES"
echo "$REMOVE_FILES" | xargs rm -f --
fi
# ====== nosūta arhīvu uz attālinātu serveri (ar custom portu) ======
if [ -n "$REMOTE_USER" ] && [ -n "$REMOTE_HOST" ]; then
echo "Nosūtu arhīvu uz $REMOTE_HOST porta $REMOTE_PORT..."
# Pievieno -P flag ja ports nav 22
if [ "$REMOTE_PORT" != "22" ]; then
SCP_CMD="scp -P $REMOTE_PORT -q \"$ARCHIVE_FILE\" \"${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_PATH}\""
else
SCP_CMD="scp -q \"$ARCHIVE_FILE\" \"${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_PATH}\""
fi
eval $SCP_CMD
if [ $? -eq 0 ]; then
echo "Arhīvs veiksmīgi nosūtīts uz ${REMOTE_HOST}:${REMOTE_PATH}"
else
echo "Kļūda: arhīva nosūtīšana uz ${REMOTE_HOST} neizdevās!"
fi
fi
echo "==== BACKUP COMPLETED: $(date) ===="
exit 0