Configure backup encryption with GPG and rsync for secure automated backups

Intermediate 45 min Apr 04, 2026 1,354 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Set up automated encrypted backups using GPG 2.4 and rsync with systemd timers. This tutorial covers GPG key management, encrypted backup scripts, and restoration procedures for production environments.

Prerequisites

  • Root or sudo access
  • At least 2GB free disk space for backups
  • Network access for remote backup sync
  • Basic understanding of Linux file permissions

What this solves

Automated backups are essential, but storing sensitive data in plaintext creates security risks. This tutorial shows you how to implement GPG encryption with rsync for secure automated backups that protect your data both in transit and at rest. You'll create production-ready backup scripts with systemd timers that encrypt files before transfer and include verification procedures.

Step-by-step configuration

Update system packages

Start by updating your package manager to ensure you get the latest versions of GPG and related tools.

sudo apt update && sudo apt upgrade -y
sudo apt install -y gnupg2 rsync coreutils
sudo dnf update -y
sudo dnf install -y gnupg2 rsync coreutils

Verify GPG 2.4 installation

Check that GPG 2.4 or later is installed and working correctly.

gpg --version | head -1
gpg --list-keys

Generate GPG key pair for backups

Create a dedicated GPG key pair specifically for backup encryption. Use a strong passphrase and store it securely.

gpg --full-generate-key

Select the following options when prompted:

  • Key type: (1) RSA and RSA (default)
  • Key size: 4096
  • Valid for: 2y (2 years)
  • Real name: Backup System
  • Email: backups@example.com
  • Comment: Automated backup encryption

Export and backup the GPG keys

Export both public and private keys to secure locations. Store the private key backup in a safe location separate from your backup server.

gpg --list-secret-keys --keyid-format=long
export KEYID="your_key_id_here"
gpg --armor --export $KEYID > /root/backup-public-key.asc
gpg --armor --export-secret-keys $KEYID > /root/backup-private-key.asc
chmod 600 /root/backup-private-key.asc
Warning: Store the private key backup in a secure location separate from your backup server. If you lose this key, encrypted backups cannot be restored.

Create backup directory structure

Set up the directory structure for backup scripts, logs, and temporary files with proper permissions.

sudo mkdir -p /opt/backup-system/{scripts,logs,temp}
sudo chmod 755 /opt/backup-system
sudo chmod 750 /opt/backup-system/{scripts,logs,temp}
sudo chown root:root /opt/backup-system -R

Create GPG encryption wrapper script

Create a wrapper script that handles GPG encryption with proper error handling and logging.

#!/bin/bash

# GPG Backup Encryption Wrapper
# Usage: gpg-backup-wrapper.sh 

set -euo pipefail

# Configuration
GPG_RECIPIENT="backups@example.com"
LOG_FILE="/opt/backup-system/logs/backup-$(date +%Y%m%d).log"
TEMP_DIR="/opt/backup-system/temp"
DATE=$(date +"%Y%m%d_%H%M%S")

# Logging function
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

# Check arguments
if [ $# -ne 3 ]; then
    log "ERROR: Usage: $0 

Make the wrapper script executable

Set proper permissions on the backup wrapper script.

sudo chmod 750 /opt/backup-system/scripts/gpg-backup-wrapper.sh
sudo chown root:root /opt/backup-system/scripts/gpg-backup-wrapper.sh

Create rsync encryption script

Create a script that combines encrypted local backups with secure rsync transfer to remote destinations.

#!/bin/bash

# Encrypted Rsync Backup Script
# Encrypts files locally, then syncs to remote destination

set -euo pipefail

# Configuration
SOURCE_DIRS=(
    "/etc"
    "/home"
    "/var/log"
    "/opt/important-data"
)

LOCAL_BACKUP_DIR="/backup/encrypted"
REMOTE_USER="backup"
REMOTE_HOST="backup.example.com"
REMOTE_DIR="/backups/$(hostname)"
SSH_KEY="/root/.ssh/backup_rsa"
LOG_FILE="/opt/backup-system/logs/rsync-backup-$(date +%Y%m%d).log"
RETENTION_DAYS=30

# Logging function
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

log "Starting encrypted rsync backup process"

# Create local backup directory
mkdir -p "$LOCAL_BACKUP_DIR"

# Encrypt each source directory
for SOURCE in "${SOURCE_DIRS[@]}"; do
    if [ -d "$SOURCE" ]; then
        BACKUP_NAME=$(echo "$SOURCE" | sed 's/\//_/g' | sed 's/^_//')
        log "Processing: $SOURCE -> $BACKUP_NAME"
        
        /opt/backup-system/scripts/gpg-backup-wrapper.sh \
            "$SOURCE" "$BACKUP_NAME" "$LOCAL_BACKUP_DIR"
        
        if [ $? -ne 0 ]; then
            log "ERROR: Failed to backup $SOURCE"
            continue
        fi
    else
        log "WARNING: Source directory does not exist: $SOURCE"
    fi
done

# Sync encrypted backups to remote server
log "Syncing encrypted backups to remote server..."
rsync -avz --delete-after --progress \
    -e "ssh -i $SSH_KEY -o StrictHostKeyChecking=no" \
    "$LOCAL_BACKUP_DIR/" \
    "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/" \
    2>> "$LOG_FILE"

if [ $? -eq 0 ]; then
    log "Remote sync completed successfully"
else
    log "ERROR: Remote sync failed"
    exit 1
fi

# Clean up old local backups
log "Cleaning up backups older than $RETENTION_DAYS days..."
find "$LOCAL_BACKUP_DIR" -name "*.gpg" -mtime +$RETENTION_DAYS -delete

log "Encrypted rsync backup process completed"

# Generate backup report
BACKUP_COUNT=$(find "$LOCAL_BACKUP_DIR" -name "*.gpg" -mtime -1 | wc -l)
TOTAL_SIZE=$(du -sh "$LOCAL_BACKUP_DIR" | cut -f1)

log "Backup summary: $BACKUP_COUNT files created, total size: $TOTAL_SIZE"

Make rsync script executable

Set proper permissions on the rsync backup script.

sudo chmod 750 /opt/backup-system/scripts/encrypted-rsync-backup.sh
sudo chown root:root /opt/backup-system/scripts/encrypted-rsync-backup.sh

Create SSH key for backup authentication

Generate an SSH key pair for secure authentication to the remote backup server.

sudo ssh-keygen -t rsa -b 4096 -f /root/.ssh/backup_rsa -N ""
sudo chmod 600 /root/.ssh/backup_rsa
sudo chmod 644 /root/.ssh/backup_rsa.pub
Note: Copy the public key to your remote backup server and add it to the backup user's authorized_keys file.

Create systemd service and timer

Set up systemd service and timer files for automated backup execution.

[Unit]
Description=Encrypted Backup Service
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
User=root
ExecStart=/opt/backup-system/scripts/encrypted-rsync-backup.sh
StandardOutput=journal
StandardError=journal

Create systemd timer

Configure the timer to run encrypted backups daily at 2 AM.

[Unit]
Description=Run encrypted backup daily
Requires=encrypted-backup.service

[Timer]
OnCalendar=daily
Persistent=true
AccuracySec=1min

[Install]
WantedBy=timers.target

Enable and start the backup timer

Enable the systemd timer to run automatically and start it immediately.

sudo systemctl daemon-reload
sudo systemctl enable encrypted-backup.timer
sudo systemctl start encrypted-backup.timer
sudo systemctl status encrypted-backup.timer

Create backup verification script

Create a script to verify that encrypted backups can be successfully decrypted and restored.

#!/bin/bash

# Backup Verification Script
# Tests decryption and extraction of encrypted backups

set -euo pipefail

# Configuration
BACKUP_DIR="/backup/encrypted"
TEST_DIR="/tmp/backup-verification"
LOG_FILE="/opt/backup-system/logs/verification-$(date +%Y%m%d).log"

# Logging function
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

log "Starting backup verification process"

# Create test directory
rm -rf "$TEST_DIR"
mkdir -p "$TEST_DIR"

# Find most recent backup files
BACKUP_FILES=$(find "$BACKUP_DIR" -name "*.gpg" -mtime -1 -type f)

if [ -z "$BACKUP_FILES" ]; then
    log "ERROR: No recent backup files found"
    exit 1
fi

VERIFIED=0
FAILED=0

for BACKUP_FILE in $BACKUP_FILES; do
    FILENAME=$(basename "$BACKUP_FILE")
    log "Verifying: $FILENAME"
    
    # Attempt decryption
    if gpg --quiet --decrypt "$BACKUP_FILE" > "$TEST_DIR/test.tar.gz" 2>/dev/null; then
        log "  Decryption: SUCCESS"
        
        # Attempt extraction test (first few files only)
        if tar -tzf "$TEST_DIR/test.tar.gz" | head -10 > /dev/null 2>&1; then
            log "  Archive integrity: SUCCESS"
            ((VERIFIED++))
        else
            log "  Archive integrity: FAILED"
            ((FAILED++))
        fi
        
        rm -f "$TEST_DIR/test.tar.gz"
    else
        log "  Decryption: FAILED"
        ((FAILED++))
    fi
done

# Cleanup
rm -rf "$TEST_DIR"

log "Verification completed: $VERIFIED successful, $FAILED failed"

if [ $FAILED -gt 0 ]; then
    exit 1
fi

exit 0

Make verification script executable

Set proper permissions on the verification script.

sudo chmod 750 /opt/backup-system/scripts/verify-backup.sh
sudo chown root:root /opt/backup-system/scripts/verify-backup.sh

Create backup restoration script

Create a script to simplify the process of restoring encrypted backups when needed.

#!/bin/bash

# Backup Restoration Script
# Usage: restore-backup.sh 

set -euo pipefail

# Check arguments
if [ $# -ne 2 ]; then
    echo "Usage: $0 

Make restoration script executable

Set proper permissions on the restoration script.

sudo chmod 750 /opt/backup-system/scripts/restore-backup.sh
sudo chown root:root /opt/backup-system/scripts/restore-backup.sh

Verify your setup

Test your encrypted backup system to ensure everything is working correctly.

# Check GPG key is available
gpg --list-keys "backups@example.com"

# Test manual backup creation
sudo /opt/backup-system/scripts/gpg-backup-wrapper.sh /etc test-backup /tmp

# Verify the encrypted file was created
ls -la /tmp/test-backup_*.tar.gz.gpg

# Test backup verification
sudo /opt/backup-system/scripts/verify-backup.sh

# Check systemd timer status
sudo systemctl list-timers encrypted-backup.timer

# Check recent backup logs
sudo tail -20 /opt/backup-system/logs/backup-$(date +%Y%m%d).log
Note: The backup automation integrates well with Linux system backup automation for comprehensive data protection strategies.

Common issues

Symptom Cause Fix
GPG encryption fails with "public key not found" Wrong recipient email or key not imported gpg --list-keys and verify recipient matches exactly
Permission denied on backup scripts Incorrect file permissions chmod 750 /opt/backup-system/scripts/*.sh
Rsync fails with SSH connection error SSH key not configured or wrong permissions Verify SSH key exists and has chmod 600 permissions
Systemd timer not running Timer not enabled or service file error systemctl enable encrypted-backup.timer && systemctl start encrypted-backup.timer
Backup verification fails Corrupted backup or wrong GPG key Check log files and verify GPG key matches encryption key
Insufficient disk space for backups Large files or inadequate retention policy Adjust retention days or implement compression levels
Never use chmod 777. It gives every user on the system full access to your backup files and keys. Instead, use proper ownership with chown and minimal permissions like 750 for scripts and 600 for private keys.

Next steps

Automated install script

Run this to automate the entire setup

इसे खुद मैनेज नहीं करना चाहते?

हम उन businesses के लिए infrastructure संभालते हैं जो uptime पर निर्भर हैं। Fully managed, एक fixed contact के साथ जो आपके setup को जानता है।

आपको एक निश्चित contact मिलता है जो आपके setup को जानता है

रॉटरडैम में उनकी डेस्क पर 12:17 · एक message में पहुंचें, कोई ticket form नहीं