> /home/jd

Automated Rsync Backup from Synology NAS to USB via Proxmox LXC

Sistema automatizado de contingencia incremental usando rsync entre Synology DSM y un contenedor LXC.

📌 Contexto y Arquitectura

🔙 Contexto Principal: Esta guía forma parte de la arquitectura detallada en Infrastructure MOC.

Objetivo: Crear un sistema de respaldo automatizado, local y resistente a cortes de internet, que copie de forma incremental las carpetas Dropbox y G-Drive desde el Synology NAS (Fuente madre) hacia un disco externo. Hardware Destino: HDD Externo de 320GB. Se utiliza el formato exFAT para portabilidad, de modo que ante un fallo catastrófico del servidor, el disco pueda ser desconectado y leído de forma nativa e inmediata en el sistema principal (Hackintosh). Arquitectura: NAS Synology -> Red Local -> Nodo Proxmox -> LXC Privilegiado -> HDD USB (320GB).


⚙️ Fase 1: Preparación de la Fuente Madre (Synology DSM)

Para mantener la seguridad y el principio de menor privilegio, el contenedor no accederá con la cuenta de administrador, sino con un usuario exclusivo y restringido.

  1. Ir a Panel de control > Usuario y grupo > Crear.
  2. Credenciales: * Usuario: backupjd
    • Contraseña segura asignada (ej. Generic2026Sys).
  3. Permisos de carpeta compartida: Asignar Solo lectura (Read Only) estrictamente a la carpeta Drive (donde residen los datos).
  4. Permisos de aplicaciones: Asegurar que el servicio SMB esté marcado en Allow (Permitido).

💽 Fase 2: Montaje Persistente del HDD en Proxmox (Host)

Evita el error común donde Proxmox cambia la letra de la unidad (de /dev/sdb a /dev/sde) al reconectar el USB en caliente. Se debe anclar por su identidad única (UUID).

  1. Obtener el UUID del disco:
Bash
   blkid /dev/sde2  # Reemplazar por la partición correcta

(Anotar el código alfanumérico, ej: 69A3-7677).

  1. Editar la tabla de montaje del sistema:
Bash
nano /etc/fstab
  1. Agregar la regla de montaje (Al final del archivo):
Text
    UUID=69A3-7677 /mnt/backup_contingencia exfat defaults,nofail 0 0

Nota: El flag nofail es vital. Si el servidor arranca tras un corte de luz y el USB no está conectado, Proxmox ignorará el montaje y continuará el inicio sin quedarse bloqueado en un kernel panic.

  1. Recargar el daemon y montar:
Bash
    systemctl daemon-reload
    mount -a

📦 Fase 3: Creación y Configuración del Contenedor (LXC)

El contenedor que hace de intermediario debe tener permisos elevados para interactuar con protocolos de red a nivel de kernel.

  1. Crear el LXC:

    • ID: 102 (Nombre: rsync-backup).
    • OS: Debian 12.
    • Recursos: 1 Core, 1024MB RAM, Red DHCP.
    • ⚠️ CRÍTICO: En la pestaña General, DESTILDAR obligatoriamente la opción Unprivileged container.
  2. Habilitar características de red:

    • Con el LXC creado (pero apagado), ir a Options > Features.
    • Tildar la casilla SMB/CIFS. (Sin esto, AppArmor bloqueará cualquier intento de usar mount.cifs).
  3. Crear el puente (Bind Mount) del Host al LXC:

    Ejecutar en la consola principal del nodo Proxmox (no dentro del LXC):

Bash
    pct set 102 -mp0 /mnt/backup_contingencia,mp=/mnt/usb_contingencia

📜 Fase 4: Scripting y Automatización interna (LXC)

  1. Encender el LXC, abrir su consola e instalar dependencias:
Bash
    apt update && apt install rsync cifs-utils nano -y
    mkdir -p /mnt/dsm_drive
  1. Crear el script bash:
Bash
    nano /root/backup.sh
  1. Código definitivo (backup.sh):
Bash
#!/bin/bash

LOG_GENERAL="/var/log/backup_estado.log"
echo "========================================" >> $LOG_GENERAL
echo "Iniciando contingencia: $(date)" >> $LOG_GENERAL

# Se agregaron echo_interval=60 y serverino para mantener vivo el tunel CIFS
if mount -t cifs -o username=[TU_USUARIO], password=[TU_PASSWORD], ro,vers=3.0,echo_interval=60,serverino //192.168.X.X/Drive /mnt/dsm_drive; then
    
    echo "Conexion OK. Copiando..." >> $LOG_GENERAL

    # Espejar Dropbox con tolerancia a latencia de I/O (--timeout)
    rsync -rtvh --delete --timeout=600 --log-file=/var/log/backup_archivos.log /mnt/dsm_drive/Dropbox/ /mnt/usb_contingencia/Dropbox/

    # Espejar G-Drive con tolerancia a latencia de I/O (--timeout)
    rsync -rtvh --delete --timeout=600 --log-file=/var/log/backup_archivos.log /mnt/dsm_drive/G-Drive/ /mnt/usb_contingencia/G-Drive/

    umount /mnt/dsm_drive
    echo "Exito total. Red desconectada: $(date)" >> $LOG_GENERAL

else
    echo "ERROR CRITICO: No se pudo conectar a DSM." >> $LOG_GENERAL
    exit 1
fi
  1. Dar permisos de ejecución:
Bash
    chmod +x /root/backup.sh
  1. Programar el Cronjob (A las 1:00 AM todos los días):
Bash
    crontab -e
  • Agregar al final del archivo:
Text
    0 1 * * * /root/backup.sh > /var/log/cron_backup.log 2>&1

🛑 Bitácora de Problemas y Soluciones (Troubleshooting)

Durante el desarrollo de esta arquitectura surgieron múltiples bloqueos. A continuación, la documentación de cada código de error y su resolución:

  • Error: mount error(1): Operation not permitted

    • Diagnóstico: El contenedor fue creado como “Unprivileged” (Sin privilegios). El kernel de Linux le prohíbe montar sistemas de archivos de red (SMB/CIFS) por seguridad perimetral.

    • Solución: Eliminar el LXC y rehacerlo destildando “Unprivileged container” en la configuración inicial.

  • Error: mount error(13): Permission denied (Con credenciales 100% correctas).

    • Diagnóstico (AppArmor): El módulo de seguridad interno de Proxmox bloqueaba la operación. Se comprobó revisando los logs del kernel (dmesg | tail -n 10), que mostraban: apparmor="DENIED" operation="mount" fstype="cifs".

    • Solución: En las opciones del LXC > Features, marcar la casilla SMB/CIFS. Reiniciar el contenedor.

  • Error: mount error(13): Permission denied (Rechazo de protocolo).

    • Diagnóstico: Conflicto de “dialectos” NTLM entre Debian 12 (moderno) y Synology DSM.

    • Solución: Inyectar el parámetro vers=3.0 en el comando mount.cifs del script.

  • Error: rsync error: some files/attrs were not transferred (code 23)

    • Diagnóstico: Se utilizó el flag estándar -a (archive) en rsync, el cual intenta replicar los propietarios (chown) y permisos (chmod) de Linux. El disco destino, al estar formateado en exFAT, no entiende de permisos y devuelve error al final de la transferencia.

    • Solución: Modificar la línea de rsync cambiando -avh por -rtvh (recursivo, preserva tiempos de modificación, verbose, human-readable).

  • Error: Al desconectar el USB para verificar datos y volver a conectarlo, arroja can't find in /etc/fstab al intentar montar.

    • Diagnóstico: Asignación dinámica de bloques (/dev/sdb pasó a ser /dev/sde).

    • Solución: Extraer el UUID con blkid e incrustarlo permanentemente en /etc/fstab (Fase 2).

  • Error: rsync: [sender] write error: Broken pipe (32) y code 23 constante.

    • Diagnóstico: Microcortes de red por timeout entre el contenedor LXC y Synology DSM al procesar miles de archivos pequeños (ej. entornos virtuales de Python). La conexión se cierra por inactividad.
    • Solución: Modificar el túnel CIFS agregando echo_interval=60,serverino al comando mount para mantener el ping activo. En el comando rsync, inyectar el parámetro --timeout=600 para tolerar picos de latencia en la lectura.
  • Error: rsync: [receiver] mkstemp ... failed: Invalid argument (22)

    • Diagnóstico: Conflicto de formato. El disco destino de contingencia utiliza exFAT, el cual prohíbe por arquitectura el uso de caracteres especiales en los nombres de archivos (?, ", |, <, >, *, :, \, /). Rsync no logra escribirlos y aborta el archivo.
    • Solución: Renombrar los archivos problemáticos en la fuente madre (Synology/Local) eliminando los caracteres prohibidos.