118 lines
3.3 KiB
Bash
Executable file
118 lines
3.3 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# ==============================================================================
|
|
# Set up Proxmox Backup Client on a Debian trixie host.
|
|
#
|
|
# Installs the client and creates the client-side encryption key. Everything
|
|
# lives in /opt/backup (see backup.env for the connection/auth config).
|
|
#
|
|
# Run as root. Safe to re-run: it will not overwrite an existing key.
|
|
# ==============================================================================
|
|
|
|
KEYRING="/usr/share/keyrings/proxmox-archive-keyring.gpg"
|
|
KEYRING_URL="https://enterprise.proxmox.com/debian/proxmox-archive-keyring-trixie.gpg"
|
|
SOURCES_FILE="/etc/apt/sources.list.d/pbs-client.sources"
|
|
BACKUP_DIR="/opt/backup"
|
|
KEY_FILE="${BACKUP_DIR}/encryption-key.pem"
|
|
EXCLUDE_FILE="${BACKUP_DIR}/exclude"
|
|
ENV_FILE="${BACKUP_DIR}/backup.env"
|
|
ENV_SAMPLE="${BACKUP_DIR}/backup.env.sample"
|
|
SERVICE_UNIT="/etc/systemd/system/pbs-backup.service"
|
|
TIMER_UNIT="/etc/systemd/system/pbs-backup.timer"
|
|
BACKUP_TIME="02:00"
|
|
RANDOMIZE_DELAY="4h"
|
|
|
|
# 1. Proxmox archive signing key
|
|
wget "$KEYRING_URL" -O "$KEYRING"
|
|
|
|
# 2. APT source for the client-only repository
|
|
cat > "$SOURCES_FILE" <<'EOF'
|
|
Types: deb
|
|
URIs: http://download.proxmox.com/debian/pbs-client
|
|
Suites: trixie
|
|
Components: main
|
|
Signed-By: /usr/share/keyrings/proxmox-archive-keyring.gpg
|
|
EOF
|
|
|
|
# 3. Install the client
|
|
apt-get update
|
|
apt-get install -y proxmox-backup-client
|
|
|
|
# 4. Client-side encryption key (no password). Never overwrite an existing key.
|
|
mkdir -p "$BACKUP_DIR"
|
|
if [ -e "$KEY_FILE" ]; then
|
|
echo "Encryption key already exists at $KEY_FILE — leaving it untouched." >&2
|
|
else
|
|
proxmox-backup-client key create "$KEY_FILE" --kdf none
|
|
chmod 600 "$KEY_FILE"
|
|
echo "Created encryption key: $KEY_FILE"
|
|
fi
|
|
|
|
# 5. Exclude list (created only if it doesn't exist yet)
|
|
if [ ! -f "$EXCLUDE_FILE" ]; then
|
|
cat > "$EXCLUDE_FILE" <<'EOF'
|
|
/proc/*
|
|
/sys/*
|
|
/dev/*
|
|
/run/*
|
|
/tmp/*
|
|
/mnt/*
|
|
/media/*
|
|
/lost+found
|
|
/var/tmp/*
|
|
/var/cache/*
|
|
EOF
|
|
echo "Created exclude list: $EXCLUDE_FILE"
|
|
fi
|
|
|
|
# 6. Config template -> backup.env (unless backup.env already exists)
|
|
if [ -f "$ENV_FILE" ]; then
|
|
echo "backup.env already exists — leaving it untouched." >&2
|
|
elif [ -f "$ENV_SAMPLE" ]; then
|
|
cp "$ENV_SAMPLE" "$ENV_FILE"
|
|
chmod 600 "$ENV_FILE"
|
|
echo "Created $ENV_FILE from $ENV_SAMPLE"
|
|
else
|
|
echo "warning: $ENV_SAMPLE not found — create $ENV_FILE manually" >&2
|
|
fi
|
|
|
|
# 7. systemd timer — run the backup daily at night
|
|
cat > "$SERVICE_UNIT" <<EOF
|
|
[Unit]
|
|
Description=Proxmox Backup Client host backup
|
|
Wants=network-online.target
|
|
After=network-online.target
|
|
|
|
[Service]
|
|
Type=oneshot
|
|
ExecStart=${BACKUP_DIR}/backup.sh
|
|
Nice=19
|
|
IOSchedulingClass=idle
|
|
EOF
|
|
|
|
cat > "$TIMER_UNIT" <<EOF
|
|
[Unit]
|
|
Description=Daily Proxmox Backup
|
|
|
|
[Timer]
|
|
OnCalendar=*-*-* ${BACKUP_TIME}
|
|
RandomizeDelaySec=${RANDOMIZE_DELAY}
|
|
Persistent=true
|
|
|
|
[Install]
|
|
WantedBy=timers.target
|
|
EOF
|
|
|
|
systemctl daemon-reload
|
|
systemctl enable --now pbs-backup.timer
|
|
|
|
# 8. Hardening: deny read/write/execute to "others" for everything in /opt/backup
|
|
# (including the directory itself), so config and backups are not world-readable.
|
|
chmod -R o-rwx "$BACKUP_DIR"
|
|
|
|
echo
|
|
echo "Done. Fill in the credentials, then run ${BACKUP_DIR}/backup.sh (or wait for the timer):"
|
|
echo " ${EDITOR:-vi} ${ENV_FILE} # server/datastore/namespace/token"
|
|
echo " systemctl list-timers pbs-backup.timer"
|
|
echo " journalctl -u pbs-backup"
|