From 5616ba8c54f8a2cc8913c017d523f457d1d16b17 Mon Sep 17 00:00:00 2001 From: Phil Date: Mon, 23 Jun 2025 22:55:07 +0100 Subject: [PATCH] Added files --- AdGuardBackup.env | 21 +++++++ AdGuard_Backup.sh | 107 ++++++++++++++++++++++++++++++++++ README.md | 142 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 269 insertions(+), 1 deletion(-) create mode 100644 AdGuardBackup.env create mode 100644 AdGuard_Backup.sh diff --git a/AdGuardBackup.env b/AdGuardBackup.env new file mode 100644 index 0000000..7ddb138 --- /dev/null +++ b/AdGuardBackup.env @@ -0,0 +1,21 @@ +# SSH Settings +HA_SSH_KEY="$HOME/.ssh/id_rsa" +HA_SSH_USER="youruser" + +# Backup destination +BACKUP_DEST="/your/backup/directory" + +# Remote file path (can be overridden) +REMOTE_FILE="/opt/AdGuardHome/AdGuardHome.yaml" + +# Servers to backup (space-separated) +SERVER_LIST="server1.example.com server2.example.com 192.168.1.100" + +# Notifications (optional) +NTFY_ENABLED=false +NTFY_SERVER="https://ntfy.yourdomain.com" +NTFY_TOPIC="adguard-backups" + +DISCORD_ENABLED=false +DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/..." + diff --git a/AdGuard_Backup.sh b/AdGuard_Backup.sh new file mode 100644 index 0000000..6282264 --- /dev/null +++ b/AdGuard_Backup.sh @@ -0,0 +1,107 @@ +#!/bin/bash + +# === Load environment === +ENV_FILE="./AdGuardBackup.env" +if [ ! -f "$ENV_FILE" ]; then + echo "Environment file not found: $ENV_FILE" + exit 1 +fi +source "$ENV_FILE" + +# === Sanity Check === +sanity_check() { + if [ -z "$HA_SSH_KEY" ]; then + echo "Error: HA_SSH_KEY is not set."; exit 1 + fi + if [ -z "$HA_SSH_USER" ]; then + echo "Error: HA_SSH_USER is not set."; exit 1 + fi + if [ -z "$BACKUP_DEST" ]; then + echo "Error: BACKUP_DEST is not set."; exit 1 + fi + if [ -z "$SERVER_LIST" ]; then + echo "Error: SERVER_LIST is not set."; exit 1 + fi + if [ "$NTFY_ENABLED" == "true" ]; then + if [ -z "$NTFY_SERVER" ] || [ -z "$NTFY_TOPIC" ]; then + echo "Error: NTFY settings are incomplete."; exit 1 + fi + fi + if [ "$DISCORD_ENABLED" == "true" ]; then + if [ -z "$DISCORD_WEBHOOK_URL" ]; then + echo "Error: DISCORD_WEBHOOK_URL is not set."; exit 1 + fi + fi +} + +# === Notification Functions === +send_ntfy_notification() { + local message="$1" + if [ "$NTFY_ENABLED" = true ]; then + curl -s -X POST -d "$message" "$NTFY_SERVER/$NTFY_TOPIC" >/dev/null + fi +} + +send_discord_notification() { + local message="$1" + if [ "$DISCORD_ENABLED" = true ]; then + curl -s -X POST -H "Content-Type: application/json" \ + -d "{\"content\": \"$message\"}" "$DISCORD_WEBHOOK_URL" >/dev/null + fi +} + +# === Run Sanity Check === +sanity_check + +# === Setup Variables === +TIMESTAMP=$(date '+%Y-%m-%d_%H-%M-%S') +START_TIME=$(date +%s) +LOG_FILE="$BACKUP_DEST/backup-$TIMESTAMP.log" +REMOTE_FILE=${REMOTE_FILE:-"/opt/AdGuardHome/AdGuardHome.yaml"} + +mkdir -p "$BACKUP_DEST" +touch "$LOG_FILE" + +# Parse server list +IFS=' ' read -r -a SERVERS <<< "$SERVER_LIST" + +# === Start Logging and Notify === +echo "[$(date)] Starting AdGuardHome backup..." | tee -a "$LOG_FILE" +send_ntfy_notification "๐Ÿ›ก๏ธ AdGuardHome backup started at $TIMESTAMP" +send_discord_notification "๐Ÿ›ก๏ธ AdGuardHome backup started at $TIMESTAMP" + +# === Main Backup Loop === +for HOST in "${SERVERS[@]}"; do + SERVER="$HA_SSH_USER@$HOST" + echo "[$(date)] Connecting to $SERVER..." | tee -a "$LOG_FILE" + + REMOTE_HOSTNAME=$(ssh -i "$HA_SSH_KEY" -o StrictHostKeyChecking=no "$SERVER" 'hostname' 2>/dev/null) + if [[ -z "$REMOTE_HOSTNAME" ]]; then + echo "[$(date)] โŒ Failed to retrieve hostname from $HOST" | tee -a "$LOG_FILE" + send_ntfy_notification "โŒ Backup failed: could not retrieve hostname from $HOST" + send_discord_notification "โŒ Backup failed: could not retrieve hostname from $HOST" + continue + fi + + DEST_FILE="$BACKUP_DEST/AdGuardHome.yaml-$REMOTE_HOSTNAME-$TIMESTAMP" + + scp -i "$HA_SSH_KEY" -o StrictHostKeyChecking=no "$SERVER:$REMOTE_FILE" "$DEST_FILE" 2>>"$LOG_FILE" + if [[ $? -eq 0 ]]; then + echo "[$(date)] โœ… Backup successful: $DEST_FILE" | tee -a "$LOG_FILE" + send_ntfy_notification "โœ… Backup complete for $REMOTE_HOSTNAME" + send_discord_notification "โœ… Backup complete for $REMOTE_HOSTNAME" + else + echo "[$(date)] โŒ Failed to copy from $HOST" | tee -a "$LOG_FILE" + send_ntfy_notification "โŒ Backup failed for $REMOTE_HOSTNAME" + send_discord_notification "โŒ Backup failed for $REMOTE_HOSTNAME" + fi +done + +# === Finalize === +END_TIME=$(date +%s) +DURATION=$((END_TIME - START_TIME)) + +echo "[$(date)] Backup script completed in ${DURATION}s." | tee -a "$LOG_FILE" +send_ntfy_notification "๐Ÿ“ฆ Backup completed in ${DURATION}s" +send_discord_notification "๐Ÿ“ฆ Backup completed in ${DURATION}s" + diff --git a/README.md b/README.md index 2db4813..85b79c8 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,142 @@ -# AdGuard-lxc-Config-Backup +# AdGuardHome Config Backup Script + +This project provides a Bash script to back up the AdGuardHome configuration file (`AdGuardHome.yaml`) from multiple remote servers via SSH. + +The script supports: + +- Backup of multiple servers defined in a `.env` file +- Timestamped backup files named using the server's hostname +- Logging of each backup session +- Optional notifications via [ntfy.sh](https://ntfy.sh/) and Discord + +--- + +## ๐Ÿ“ฆ Features + +- SSH key authentication +- Environment-based configuration +- Per-host backup with hostname and timestamp +- Automatic log file generation +- Optional failure/success notifications + +--- + +## ๐Ÿ› ๏ธ Requirements + +- Bash +- `ssh` and `scp` installed +- A valid SSH private key +- Optional: `curl` (for notifications) + +--- + +## ๐Ÿงพ Setup + +### 1. Clone the repository + +```bash +git clone https://github.com/youruser/adguard-backup-script.git +cd adguard-backup-script +``` + +### 2. Configure the `.env` file + +Copy and edit the sample `.env` file: + +```env +# SSH Settings +HA_SSH_KEY="$HOME/.ssh/id_rsa" +HA_SSH_USER="youruser" + +# Backup destination (local path) +BACKUP_DEST="/your/backup/directory" + +# Remote config path (optional override) +REMOTE_FILE="/opt/AdGuardHome/AdGuardHome.yaml" + +# List of remote servers (space-separated) +SERVER_LIST="server1.example.com server2.example.com 192.168.1.100" + +# Notification options (optional) +NTFY_ENABLED=true +NTFY_SERVER="https://ntfy.yourdomain.com" +NTFY_TOPIC="adguard-backups" + +DISCORD_ENABLED=true +DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/..." +``` + +### 3. Make the script executable + +```bash +chmod +x backup_adguard.sh +``` + +### 4. Run the backup + +```bash +./backup_adguard.sh +``` + +--- + +## ๐Ÿ—‚๏ธ Backup Output + +- Files saved to: `$BACKUP_DEST` +- Naming convention: `AdGuardHome.yaml--` +- Example: `AdGuardHome.yaml-server1-2025-06-23_14-45-01` + +--- + +## ๐Ÿ”” Notifications (Optional) + +### ntfy +- Configure `NTFY_ENABLED=true`, `NTFY_SERVER`, and `NTFY_TOPIC` in your `.env`. + +### Discord +- Set `DISCORD_ENABLED=true` and supply your `DISCORD_WEBHOOK_URL`. + +--- + +## ๐Ÿงช Sanity Checks + +The script will validate: +- SSH key path +- SSH user +- Backup destination +- Server list +- Notification credentials (if enabled) + +--- + +## ๐Ÿ“œ Log Files + +Each run generates a log file: +- Location: `$BACKUP_DEST` +- Format: `backup-.log` + +Example: +``` +backup-2025-06-23_14-45-01.log +``` + +--- + +## ๐Ÿ’ก Tips + +- Use cron to automate the script (e.g., daily backups). +- Ensure your SSH key is authorized on all target servers. +- Monitor logs or enable notifications for unattended runs. + +--- + +## ๐Ÿ“„ License + +MIT License + +--- + +## ๐Ÿค Contributing + +Feel free to fork, submit PRs, or suggest improvements!