Estrategias Avanzadas de BorgBackup

BorgBackup es una herramienta de backup con deduplicación, compresión y cifrado diseñada para entornos enterprise Linux, capaz de gestionar terabytes de datos de forma eficiente con repositorios locales o remotos vía SSH. Sus características avanzadas incluyen el modo append-only para protección contra ransomware, compresión adaptativa por tipo de archivo y verificación de integridad integrada. Esta guía cubre las estrategias más avanzadas para despliegues en producción.

Requisitos Previos

  • Linux (Ubuntu/Debian o CentOS/Rocky)
  • Python 3.6+ (Borg depende de Python)
  • OpenSSL
  • Acceso SSH al servidor de backup (para repositorios remotos)
  • Espacio de almacenamiento suficiente (al menos 1.5x los datos)

Instalación de BorgBackup

# Ubuntu/Debian
apt-get install -y borgbackup

# CentOS/Rocky Linux
dnf install -y borgbackup

# Instalar desde pip (siempre la versión más reciente)
pip3 install borgbackup

# O descargar el binario estático (sin dependencias)
curl -LO "https://github.com/borgbackup/borg/releases/latest/download/borg-linux64"
mv borg-linux64 /usr/local/bin/borg
chmod +x /usr/local/bin/borg

# Verificar la instalación
borg --version

Instalar Borgmatic (wrapper de alto nivel)

Borgmatic simplifica la configuración y automatización de Borg:

# Instalar borgmatic
pip3 install borgmatic

# O con apt en Ubuntu 22.04+
apt-get install -y borgmatic

# Verificar
borgmatic --version

Modo Append-Only para Protección contra Ransomware

El modo append-only es la característica de seguridad más importante de Borg para producción. En este modo, el servidor de backup acepta nuevos archivos pero no permite eliminar archivos existentes, protegiendo los backups incluso si el servidor de producción es comprometido.

Configurar acceso SSH restringido en el servidor de backup

# En el SERVIDOR DE BACKUP (no en el servidor de producción)

# Crear usuario dedicado para backups
useradd --system --create-home --shell /bin/bash borguser
mkdir -p /var/backups/borg

# Inicializar el repositorio en modo append-only
borg init \
    --encryption=repokey-blake2 \
    --append-only \
    /var/backups/borg/servidor-produccion

# Obtener la clave pública SSH del servidor de producción
# (se configurará en el siguiente paso)
# Configurar authorized_keys con restricciones en el servidor de backup
# /home/borguser/.ssh/authorized_keys
cat >> /home/borguser/.ssh/authorized_keys << 'EOF'
command="borg serve --append-only --restrict-to-path /var/backups/borg/servidor-produccion",restrict ssh-ed25519 AAAA... clave-del-servidor-produccion
EOF

Con esta configuración:

  • El servidor de producción puede crear archivos nuevos (backups)
  • No puede eliminar archivos existentes (protección contra ransomware)
  • Solo puede acceder al directorio específico del repositorio

Purga manual desde el servidor de backup

# La eliminación de archivos antiguos SOLO puede hacerla
# el administrador directamente en el servidor de backup

# En el servidor de backup, conectarse directamente (no via SSH remoto)
borg prune \
    --keep-daily 7 \
    --keep-weekly 4 \
    --keep-monthly 12 \
    /var/backups/borg/servidor-produccion

borg compact /var/backups/borg/servidor-produccion

Repositorios Remotos y SSH

# En el SERVIDOR DE PRODUCCIÓN, configurar la clave SSH
ssh-keygen -t ed25519 -f /root/.ssh/borg_backup -N "" -C "borg-backup-$(hostname)"

# Ver la clave pública para agregarla al servidor de backup
cat /root/.ssh/borg_backup.pub

# Probar la conexión SSH al servidor de backup
ssh -i /root/.ssh/borg_backup [email protected] "borg info"

Variables de entorno para repositorios remotos

# Crear archivo de configuración del entorno de Borg
cat > /etc/borg/backup.env << 'EOF'
# Repositorio principal (servidor de backup)
export BORG_REPO="ssh://[email protected]:22/var/backups/borg/servidor-produccion"

# Clave de cifrado del repositorio
export BORG_PASSPHRASE="frase-de-paso-muy-larga-y-segura-aqui"

# Clave SSH para la conexión
export BORG_RSH="ssh -i /root/.ssh/borg_backup"

# No preguntar confirmación en scripts
export BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK=yes

# Opciones de compresión por defecto
export BORG_COMPRESSION="zstd,5"
EOF
chmod 600 /etc/borg/backup.env

Compresión Adaptativa

Borg soporta múltiples algoritmos de compresión. La elección depende del tipo de datos:

# Niveles de compresión disponibles:
# - none: sin compresión (más rápido, más espacio)
# - lz4: muy rápida, compresión moderada (buena para datos ya comprimidos)
# - zstd,N: equilibrio velocidad/compresión (N de 1-22, recomendado 3-9)
# - zlib,N: compatible, buena compresión (N de 1-9)
# - lzma,N: máxima compresión, muy lento (N de 0-9)

# Para datos mixtos de producción: zstd nivel 5
borg create \
    --compression zstd,5 \
    $BORG_REPO::backup-{now} \
    /etc /home /var/www

# Para logs y datos texto: zstd nivel 9
borg create \
    --compression zstd,9 \
    $BORG_REPO::logs-{now} \
    /var/log

# Script con compresión adaptativa por tipo de directorio

Script completo de backup con compresión adaptativa

cat > /usr/local/bin/borg-backup.sh << 'EOF'
#!/bin/bash
# Backup avanzado con BorgBackup y compresión adaptativa

set -euo pipefail

# Cargar configuración
source /etc/borg/backup.env

FECHA=$(date +%Y-%m-%dT%H:%M:%S)
LOG_FILE="/var/log/borg/backup-$(date +%Y-%m-%d).log"

mkdir -p /var/log/borg

log() {
    echo "[$(date +%H:%M:%S)] $*" | tee -a "$LOG_FILE"
}

# Función de backup con compresión optimizada
backup_directorio() {
    local NOMBRE="$1"
    local COMPRESION="$2"
    shift 2
    local DIRS=("$@")
    
    log "Iniciando backup: $NOMBRE"
    
    borg create \
        --verbose \
        --stats \
        --progress \
        --compression "$COMPRESION" \
        --exclude-caches \
        --exclude-if-present .nobackup \
        "$BORG_REPO::${NOMBRE}-${FECHA}" \
        "${DIRS[@]}" 2>&1 | tee -a "$LOG_FILE"
    
    log "Backup completado: $NOMBRE"
}

# Backup de configuración del sistema (zstd alto para máxima compresión)
backup_directorio "sistema" "zstd,9" /etc /root

# Backup de aplicaciones web (zstd moderado - equilibrio)
backup_directorio "web" "zstd,5" \
    /var/www \
    --exclude "/var/www/*/node_modules" \
    --exclude "/var/www/*/.git" \
    --exclude "/var/www/*/.next"

# Backup de datos de usuario (zstd moderado)
backup_directorio "usuarios" "zstd,5" /home \
    --exclude "/home/*/.cache" \
    --exclude "/home/*/.local/share/Trash"

# Política de retención
log "Aplicando política de retención..."
borg prune \
    --keep-daily 7 \
    --keep-weekly 4 \
    --keep-monthly 6 \
    --keep-yearly 1 \
    --prefix "sistema-" \
    "$BORG_REPO" 2>&1 | tee -a "$LOG_FILE"

borg prune \
    --keep-daily 14 \
    --keep-weekly 8 \
    --keep-monthly 12 \
    --prefix "web-" \
    "$BORG_REPO" 2>&1 | tee -a "$LOG_FILE"

# Liberar espacio después del prune
borg compact "$BORG_REPO" 2>&1 | tee -a "$LOG_FILE"

log "=== Backup completado exitosamente ==="
EOF

chmod +x /usr/local/bin/borg-backup.sh

Monitorización y Verificación

# Ver estadísticas del repositorio
source /etc/borg/backup.env
borg info $BORG_REPO

# Listar todos los archivos con información detallada
borg list $BORG_REPO

# Ver el contenido de un archivo específico
borg list $BORG_REPO::nombre-del-archivo

# Verificar la integridad del repositorio
borg check $BORG_REPO

# Verificación completa (lee todos los datos - lento)
borg check --verify-data $BORG_REPO

Integración con Prometheus/Grafana

# Generar métricas en formato Prometheus
cat > /usr/local/bin/borg-metrics.sh << 'EOF'
#!/bin/bash
source /etc/borg/backup.env

# Obtener información del repositorio
INFO=$(borg info --json $BORG_REPO 2>/dev/null)

# Extraer métricas
ARCHIVOS=$(echo $INFO | jq -r '.cache.stats.total_chunks // 0')
ORIGINAL=$(echo $INFO | jq -r '.cache.stats.total_csize // 0')
COMPRIMIDO=$(echo $INFO | jq -r '.cache.stats.unique_csize // 0')

# Escribir métricas para el node exporter de Prometheus
cat > /var/lib/node_exporter/borg_backup.prom << METRICS
# HELP borg_backup_total_chunks Total de chunks en el repositorio
# TYPE borg_backup_total_chunks gauge
borg_backup_total_chunks $ARCHIVOS

# HELP borg_backup_original_bytes Tamaño original de los datos
# TYPE borg_backup_original_bytes gauge
borg_backup_original_bytes $ORIGINAL

# HELP borg_backup_compressed_bytes Tamaño comprimido/deduplicado
# TYPE borg_backup_compressed_bytes gauge
borg_backup_compressed_bytes $COMPRIMIDO

# HELP borg_backup_last_success Timestamp del último backup exitoso
# TYPE borg_backup_last_success gauge
borg_backup_last_success $(date +%s)
METRICS
EOF

chmod +x /usr/local/bin/borg-metrics.sh

Operaciones Paralelas

# Borg en sí no soporta múltiples repositorios en paralelo de forma nativa
# pero puedes usar herramientas de shell para paralelizar

# Backup a múltiples repositorios en paralelo
backup_paralelo() {
    source /etc/borg/backup.env
    
    # Repositorio primario (S3 via SFTP)
    BORG_REPO="ssh://[email protected]/backups/borg" \
    borg create --compression zstd,5 "$BORG_REPO::backup-$(date +%Y%m%d)" /var/www &
    PID1=$!
    
    # Repositorio secundario (servidor diferente)
    BORG_REPO="ssh://[email protected]/backups/borg" \
    borg create --compression zstd,5 "$BORG_REPO::backup-$(date +%Y%m%d)" /var/www &
    PID2=$!
    
    # Esperar ambos backups
    wait $PID1 && echo "Backup 1 exitoso" || echo "Error en Backup 1"
    wait $PID2 && echo "Backup 2 exitoso" || echo "Error en Backup 2"
}

Recuperación ante Desastres

# Listar archivos disponibles para restaurar
source /etc/borg/backup.env
borg list $BORG_REPO

# Ver el contenido de un archivo específico
borg list $BORG_REPO::web-2024-01-15T03:00:00

# Restaurar un archivo específico
borg extract \
    $BORG_REPO::web-2024-01-15T03:00:00 \
    var/www/miapp/config.yml

# Restaurar un directorio completo
borg extract \
    $BORG_REPO::web-2024-01-15T03:00:00 \
    --target /tmp/restauracion \
    var/www/miapp/

# Restaurar el sistema completo (en servidor nuevo)
# 1. Instalar Borg en el servidor nuevo
# 2. Configurar SSH para acceder al repositorio de backup
# 3. Restaurar desde el archivo más reciente
borg extract --progress \
    $BORG_REPO::sistema-2024-01-15T03:00:00 \
    --target / \
    etc/ home/ var/www/

# Montar el repositorio como sistema de archivos (para recuperación selectiva)
mkdir -p /mnt/borg-mount
borg mount $BORG_REPO /mnt/borg-mount
ls /mnt/borg-mount  # Ver todos los archivos
# Copiar los archivos que necesitas
cp /mnt/borg-mount/web-2024-01-15T03:00:00/var/www/miapp/archivo.txt /var/www/miapp/
# Desmontar
borg umount /mnt/borg-mount

Solución de Problemas

Error: Repository does not exist

# El repositorio no está inicializado o la ruta es incorrecta
borg info $BORG_REPO

# Si es correcto pero no existe, inicializar:
borg init --encryption=repokey-blake2 $BORG_REPO

Error de bloqueo (lock)

# Un proceso de backup anterior se interrumpió
borg break-lock $BORG_REPO

# Verificar que no hay otro proceso de Borg activo
ps aux | grep borg

# Después de desbloquear, verificar integridad
borg check $BORG_REPO

Backup muy lento

# Reducir el nivel de compresión (velocidad vs. espacio)
# zstd,1 es muy rápido, zstd,3 es un buen balance

# Usar el parámetro --remote-path si Borg no está en el PATH remoto
borg create \
    --remote-path /usr/local/bin/borg \
    $BORG_REPO::backup-{now} \
    /var/www

# Verificar la velocidad de conexión SSH
borg create --verbose $BORG_REPO::test-velocidad /etc 2>&1 | grep "Transfer"

Repositorio corrupto

# Verificar y reparar lo que se pueda
borg check --repair $BORG_REPO

# Si hay segmentos dañados, reconstruir el índice
borg rebuild-manifest $BORG_REPO

# Lista de archivos rotos
borg check --verify-data 2>&1 | grep "ERROR"

Conclusión

BorgBackup con modo append-only, repositorios remotos y verificación periódica de integridad proporciona un sistema de backup de nivel enterprise resistente a los escenarios de amenaza más exigentes, incluyendo ransomware y compromisos del servidor. La combinación de deduplicación eficiente y compresión adaptativa por tipo de datos permite mantener años de historial de backups con un uso razonable de almacenamiento, mientras que el sistema de montaje facilita recuperaciones selectivas sin necesidad de restaurar el sistema completo.