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

Leave a Reply

Your email address will not be published. Required fields are marked *