Negli articoli dedicati a Promxmox Backup e al backup del proprio VPS tramite Proxmox backup Client, abbiamo solamente accennato al restore.

Di seguito uno script bash che automatizza il montaggio degli snapshot e permette di ripristinare file o cartelle in modo semplice e veloce, senza dover ricordare la sintassi dei comandi di proxmox backup client.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#!/bin/bash

# Exit immediately if a command exits with a non-zero status, or if an unset variable is referenced
set -Eeuo pipefail

########################################
# CONFIGURATION
########################################

# Encrypted configuration file
readonly ENCRYPTED_CONFIG="pve01-config.gpg"
# Temporary decrypted config path (RAM disk)
readonly DECRYPTED_CONFIG="/dev/shm/pve01-config-$(date +%s).tmp"

########################################
# FUNCTIONS
########################################

# Cleanup temporary decrypted config file
cleanup() {
    if [ -f "$DECRYPTED_CONFIG" ]; then
        # Overwrite file with zeros and delete file
        shred -uz "$DECRYPTED_CONFIG" 2> /dev/null
    fi
    
    # Kill gpg-agent to avoid caching issues
    gpgconf --kill gpg-agent 2> /dev/null
}

# Check for required dependencies

check_dependencies() {
    for cmd in gnupg proxmox-backup-client tree; do
        if ! command -v "$cmd" &> /dev/null; then

        CODENAME=$(. /etc/os-release && echo "$VERSION_CODENAME")
        REPO_FILE="/etc/apt/sources.list.d/pbs-client.list"
        KEY_FILE="/etc/apt/trusted.gpg.d/proxmox-release-${CODENAME}.gpg"

        if [ ! -f "$REPO_FILE" ]; then
            wget "https://enterprise.proxmox.com/debian/proxmox-release-trixie.gpg" -O "$KEY_FILE"
            echo "deb http://download.proxmox.com/debian/pbs-client trixie main" > "$REPO_FILE"
            apt update
        fi

        apt -y install gnupg proxmox-backup-client tree

        fi
    done
}

# Load configuration from decrypted file
load_config() {
    source "$DECRYPTED_CONFIG"
    export PBS_PASSWORD
}

# Unmount the current mount point if mounted
unmount_snapshot() {
    echo -e "\nUnmounting $PBS_MOUNT_POINT"
    find /mnt/pbs_restore -mindepth 1 -maxdepth 1 -type d -exec umount {} \; || true
}

# List available snapshots
list_snapshots() {
    echo -e "\nFetching snapshots..."
    proxmox-backup-client snapshot list --repository "$PBS_REPOSITORY" --ns "$PBS_NAMESPACE"

}

# Mount the selected snapshot
mount_snapshot() {
    local snapshot_name="$1"
    local pxar_list="etc.pxar pve-cluster.pxar pve-manager.pxar pve.pxar"
    export PBS_ENCRYPTION_PASSWORD

    echo -e "\nMounting snapshot...\n"

    for pxar_name in $pxar_list; do
            local target="$PBS_MOUNT_POINT/${pxar_name%.pxar}"
            mkdir -p "$target"
    
            echo "Mounting $pxar_name -> $target"
    
            proxmox-backup-client mount \
                "$snapshot_name" \
                "$pxar_name" \
                "$target" \
                --repository "$PBS_REPOSITORY" \
                --ns "$PBS_NAMESPACE" \
                --keyfile <(echo "$PBS_ENCRYPTION_KEY") 2> /dev/null
                # Pass the encryption key to the client.
                # <(...) creates a virtual temporary file
                # containing the value of the variable PBS_ENCRYPTION_KEY.
                # This way, there is no need to save the key to disk.
    done

    if [ $? -eq 0 ]; then
        echo -e "\nSnapshot mounted successfully at:\n\n$PBS_MOUNT_POINT"
    else
        echo -e "\nError: Failed to mount the snapshot."
        exit 1
    fi
}

# Show the entries of the mount point
show_mount_contents() {
    echo -e "\n---------------------------------------------"
    echo "Entries at $PBS_MOUNT_POINT:"
    echo "---------------------------------------------"
    sudo tree -L 2 $PBS_MOUNT_POINT | head -n 10
    echo "[...]"
}

########################################
# MAIN SCRIPT into a subshell
########################################

(

    # Set trap for cleanup on exit or error
    trap cleanup EXIT ERR SIGINT SIGTERM

    clear

    # Elevate to root if not already
    if [[ $EUID -ne 0 ]]; then
        echo "Root privileges required. Re-running with sudo..."
        exec sudo --preserve-env=HOME "$0" "$@"
    fi

    # Check for required dependencies
    check_dependencies

    # Decrypt the config file temporarily
    echo "Decrypting configuration file (you will be prompted for the GPG password)..."
    gpg --decrypt --output "$DECRYPTED_CONFIG" "$ENCRYPTED_CONFIG" 2>/dev/null
    if [ $? -ne 0 ]; then
        echo "Error: Failed to decrypt the configuration file. Wrong password?"
        exit 1
    fi

    # Load configuration
    load_config

    # Unmount if already mounted
    unmount_snapshot

    # List available snapshots
    list_snapshots

    # Prompt user for snapshot name
    read -p "Enter the snapshot name to mount: " SNAPSHOT_NAME
    if [ -z "$SNAPSHOT_NAME" ]; then
        echo -e "Error: No snapshot name provided."
        exit 1
    fi

    # Check if mount point exists, if not create it
    if [ ! -d "$PBS_MOUNT_POINT" ]; then
        echo "Creating $PBS_MOUNT_POINT directory..."
        mkdir -p "$PBS_MOUNT_POINT"
    fi

    # Mount the selected snapshot
    mount_snapshot "$SNAPSHOT_NAME"

    show_mount_contents

)

Prerequisiti

Per eseguire questo script, è necessario avere installati i seguenti pacchetti:

  • gnupg
  • proxmox-backup-client
  • tree

Se questi pacchetti non sono già presenti, lo script provvederà ad installarli automaticamente tramite la funzione check_dependencies.

Il file di configurazione viene cifrato con il seguente comando:

1
gpg -c --cipher-algo AES256 /path/to/config

Un template del file di configurazione viene riportato di seguito:

1
2
3
4
5
6
7
8
PBS_REPOSITORY=''
PBS_PASSWORD=''
PBS_FINGERPRINT=''
PBS_ENCRYPTION_PASSWORD=''
PBS_ENCRYPTION_KEY=''
ID=''
PBS_NAMESPACE=''
PBS_MOUNT_POINT='/mnt/pbs_restore'

Se si aggiorna qualsiasi variabile nel file, è necessario cifrarlo nuovamente utilizzando il comando riportato sopra.

Esecuzione

Quando viene eseguito:

  1. Lo script verifica l’UID dell’utente che lo esegue. Se l’UID è diverso da 0, viene richiesta la password dell’utente per elevare i privilegi tramite sudo
  2. Ad ogni esecuzione, lo script richiede la password per decrittare il file di configurazione
  3. Una volta inserita la password, viene mostrata una lista degli snapshot disponibili
  4. È necessario inserire il nome dello snapshot da montare, ad esempio: host/pve01/2026-05-17T19:00:25Z
  5. La funzione mount_snapshot include la variabile locale pxar_list che contiene la lista dei pxar (Proxmox Backup Archive)
    • Nel caso di pxar differenti, la variabile locale della funzione, dovrá essere modificata. Verificare il campo ExecStart del servizio che si occupa del backup
  6. Questo snapshot verrà montato sulla macchina in cui lo script viene eseguito nella directory /mnt/pbs_restore
  7. La directory, se non presente, viene creata dallo
  8. L’intero script viene eseguito in una subshell per evitare che le variabili vengano ereditate dalla shell dell’utente
  9. Il file decriptato è collocato in /dev/shm, un filesystem temporaneo montato in RAM, e verrà eliminato alla fine dell’esecuzione grazie alla funzione trap cleanup, che gestisce gli eventi EXIT, ERR, SIGINT, e SIGTERM

Ripristino delle configurazioni di PVE

Le configurazioni delle VM, le definizioni degli storage e le impostazioni del cluster sono memorizzate in un database SQLite chiamato config.db. È fondamentale non sovrascrivere questo file mentre i servizi di Proxmox sono attivi.

  • Prima di procedere, arrestare i seguenti servizi di Proxmox:
1
2
3
4
systemctl stop pve-cluster
systemctl stop pvedaemon
systemctl stop pveproxy
systemctl stop pvestatd
  • Effettuare una copia di backup del database di configurazione:
1
cp /var/lib/pve-cluster/config.db /var/lib/pve-cluster/config.db.bak
  • Sostituire i seguenti file e directory:
Path Descrizione
/etc/pve/qemu-server/ Definizioni delle VM
/etc/pve/lxc/ Configurazioni dei container
/etc/pve/storage.cfg Pool di storage
/etc/pve/datacenter.cfg Impostazioni globali
/etc/pve/corosync.conf Informazioni sul cluster
/etc/network/interfaces
/etc/hosts
/etc/resolv.conf
/etc/fstab
/var/lib/pve/ Dati di Proxmox
/var/lib/pve-cluster/config.db Config. delle VM, storage e impostazioni del cluster
/var/lib/pve-manager/ Dati di gestione di Proxmox
  • Una volta completato il ripristino, riavviare il sistema: shutdown -r now

Riferimenti