Skip to content

❄️ Proxmox Backup Server - Cold backup

Abstract

A secondary Proxmox Backup Server operating as a pull-based, time-air-gapped replica of the primary PBS, powered on only during scheduled synchronization windows.


Prerequisites


Explanation

My goal is to have secondary local backup of my data that time-air-gapped. This offers: - an additional copy of my data (always useful) - an additional layer of security - some power saving as the server mostly powered off - longer retention on backups as this server has a bunch of spinning disks

I have PBS installed on a dedicated server, that will only power on at a specified time and after completing the sync of my backup, powers down automatically.

The cold storage PBS with only sync in a PULL motion. Meaning that it will pull the backups from the primary PBS. If the primary is compromised (malware, ransomware, credential theft), it cannot reach or overwrite the secondary backups.

1. Dedicated backup user

Create a dedicated backup user on your primary PBS PBS-cold-storage

Give that user the necessary permissions: - Path: The path to the datastore that wish to sync - User: Your created backup user - Role: DatastoreReader (our user only need read permissions)

PBS-cold-storage


2. Namespaces (optional)

On the secondary PBS (cold PBS), I have created the same namespaces as on my primary PBS but with "cold" added in the name.

PBS-cold-storage


3. Add the primary PBS

On your secondary PBS, add the primary PBS. For this I refer to my guide: Proxmox Backup Server

and setup a sync job. Be sure to disable the option 'Remove Vanished'!! Otherwise, when a snapshot is deleted from the primary PBS, it will also be deleted on your secondary PBS.

PBS-cold-storage

I will run mine daily at 2pm.


4. Automatically start PBS

The next step is to determine on how to start your PBS. There are a couple of different ways depending on your BIOS options and preferences: - Some BIOS options allow you to start the system at a predefined time. - Wake on LAN (a separate server wakes up the PBS server) - Turn on after power loss (using a smart plug to turn on at a predefined time)

I will be choosing the last option using a Zigbee plug in Home Assistant. Using this method I will be turning on my PBS server daily. When PBS has completed all its tasks, it will shut down (more on this in the next part). Afterwards, when Home Assistant measures that the wattage on the smart plug is below than 10W, it will cut the power until the next backup period.


5. Stop PBS after all jobs are finished

With the help of a bash script, we can check if PBS has any active tasks running. If there are no tasks running, we will assume that the sync/backup is complete and the server can shut down.

Credit for the script goes to Apalrd https://www.apalrd.net/posts/2024/pbs_hibernate/

Strategy: - 12h55 - Start PBS - 13h00 - Prune job - 13h10 - Garbage collection job - 13h30 - Sync job - 14h00 - Start bash script to check if there are any jobs running. If not, shutdown. - (I will run verify jobs once a week at separate time)

To create the bash script to check if there are any jobs running:

nano /usr/local/sbin/autoshutdown.sh

#!/bin/bash

#Count of times we have queried and there are tasks running
count=0
#Number of no-task intervals before we shutdown
max=10
#Interval in seconds
interval=5


#Continue until we shutdown
while true; do
    #Check if we should shutdown until we see not 
    if [[ $(proxmox-backup-manager task list) ]]; then
        #Continue to wait
        count=0
    else
        #There are no tasks running, so increment counter
        count=$((count + 1))
        echo "No tasks running, time until shutdown is $(((max - count) * interval)) seconds"
        #If we reached the max count, then shutdown
        if  ((count >= max)); then
            echo "Time to shutdown!"
            shutdown now
        fi
    fi
    #Delay by interval to next check
    sleep "$interval"
done
echo "Exiting"

Make it executable:

chmod +x /usr/local/sbin/autoshutdown.sh

nano /etc/systemd/system/autoshutdown.service
[Unit]
Description=Shutdown when there are no tasks left

[Service]
ExecStart=/usr/local/sbin/autoshutdown.sh

[Install]
WantedBy=default.target

Create a timer to start the bash script at 14h00

nano /etc/systemd/system/autoshutdown.timer

[Unit]
Description=Shutdown
RefuseManualStart=no
RefuseManualStop=no

[Timer]
#Run at 14:00 local time
OnCalendar=*-*-* 14:00:00
Unit=autoshutdown.service

[Install]
WantedBy=timers.target
systemctl daemon-reload
systemctl enable --now autoshutdown.timer

6. PBS verify job

I will run a verify job once a week. For this I will create: - a separate timer - the smart plug will start the PBS a litte before that time

Create a timer to start the bash script at 14h00

nano /etc/systemd/system/autoshutdown-after-verify.timer

[Unit]
Description=Shutdown
RefuseManualStart=no
RefuseManualStop=no

[Timer]
#Run at 14:00 local time
OnCalendar=*-*-* 01:00:00
Unit=autoshutdown.service

[Install]
WantedBy=timers.target
systemctl daemon-reload
systemctl enable --now autoshutdown-after-verify.timer