Backups automáticos en Linux con restauración de prueba
Automatizar backups consiste en preparar una recuperación repetible, no solo en generar archivos de madrugada. Antes del script define cuánto dato puedes perder, cuánto tiempo puedes tardar en recuperar y qué necesitas para reconstruir el servicio.
El ejemplo copia archivos estáticos de un sitio y configuración de Apache. No respalda una base de datos en ejecución ni promete cifrado. Ajusta las rutas, prepara los permisos y utiliza datos de práctica antes de incorporar información importante.
Elige qué debe ser consistente
Los archivos que cambian durante tar pueden producir una copia incompleta o incoherente. Para aplicaciones activas utiliza un procedimiento de pausa, snapshot coordinado o exportación apropiado.
Una base MariaDB necesita una exportación o herramienta compatible con su motor y requisitos de recuperación. Copiar directamente su directorio de datos mientras escribe no equivale a un respaldo consistente.
Anota también dependencias, versiones, secretos y procedimiento de recuperación. Guarda los secretos con acceso restringido; no los incluyas en un documento público.
Prepara un destino protegido
El script se ejecutará como root para leer la configuración y escribirá en un directorio local privado. Comprueba capacidad antes:
sudo install -d -m 0700 /var/backups/sitio
df -h /var/backups/sitio
sudo nano /usr/local/sbin/backup-sitio
Guarda el siguiente contenido. Las rutas var/www/ejemplo y etc/apache2 deben existir; son relativas a / por el uso de -C.
#!/bin/bash
set -Eeuo pipefail
umask 077
export PATH=/usr/sbin:/usr/bin:/sbin:/bin
destino=/var/backups/sitio
exec 9>"$destino/.backup.lock"
flock -n 9 || { echo "Ya existe un backup en curso" >&2; exit 1; }
temporal=$(mktemp "$destino/.archivo.XXXXXX")
trap 'rm -f -- "$temporal"' EXIT
marca=$(date -u +%Y%m%dT%H%M%SZ)
final="$destino/archivos-$marca-$$.tar.gz"
tar -czf "$temporal" -C / var/www/ejemplo etc/apache2
gzip -t "$temporal"
tar -tzf "$temporal" >/dev/null
mv -- "$temporal" "$final"
(
cd "$destino"
sha256sum -- "${final##*/}" > "${final##*/}.sha256"
)
printf 'Backup completado: %s\n' "$final"
El nombre temporal evita anunciar como final una compresión fallida. set -o pipefail ayuda a detectar fallos en tuberías que añadas más adelante. El bloqueo impide dos ejecuciones simultáneas de este script.
La comprobación gzip y el listado tar detectan algunos problemas del archivo; no prueban que la aplicación pueda recuperarse. Aquí no se borran respaldos antiguos automáticamente.
Haz una primera ejecución visible
sudo chmod 0750 /usr/local/sbin/backup-sitio
sudo /usr/local/sbin/backup-sitio
sudo ls -lh /var/backups/sitio
Revisa el estado de salida, tamaño y fecha. Si falla por archivos modificados, no cambies el script para ignorar cualquier error: corrige la coherencia del origen.
Restaura en un directorio aislado
Utiliza el nombre real de la copia recién creada. Primero verifica su checksum desde el directorio que contiene ambos archivos:
sudo -i
cd /var/backups/sitio
sha256sum -c archivos-NOMBRE_REAL.tar.gz.sha256
tar -tzf archivos-NOMBRE_REAL.tar.gz
prueba=$(mktemp -d /var/tmp/restauracion-sitio.XXXXXX)
tar --no-same-owner -xzf archivos-NOMBRE_REAL.tar.gz -C "$prueba"
printf 'Revisa la restauración en %s\n' "$prueba"
exit
No extraigas una copia no confiable como root. En esta práctica el archivo es propio, sus rutas se han listado y el destino está vacío. Compara archivos importantes y realiza una prueba del servicio en otro entorno antes de afirmar que puedes recuperarlo.
Copia fuera del servidor y controla retención
Configura un destino rclone con una cuenta autorizada y permisos mínimos. Para ensayar una copia, ajustando el nombre remoto:
rclone copy /var/backups/sitio mi-remoto:backups/sitio --include 'archivos-*.tar.gz*' --dry-run
Ejecuta como una cuenta con permiso para leer el origen y usar esa configuración rclone. Tras revisar, realiza la copia quitando --dry-run y comprueba el resultado con rclone check o descargando y restaurando una versión.
copy no elimina archivos antiguos del destino como puede hacer sync. Aun así, un atacante con las mismas credenciales podría modificar copias: considera versiones, separación de cuentas o almacenamiento inmutable. El cifrado del destino depende de su configuración; un tar.gz no cifra datos.
Programa el script con cron después de esta primera restauración y registra su salida. Define retención por separado, preserva generaciones suficientes y elimina solo tras comprobar la copia externa y la política. La ausencia de errores en un log vacío no demuestra que una tarea se haya ejecutado.
Preguntas frecuentes
¿Puedo guardar todo en el mismo disco del servidor?
Sirve como etapa local o recuperación rápida, pero una avería o compromiso del equipo puede afectar también las copias. Mantén otra copia independiente.
¿El checksum confirma que los datos son correctos?
Detecta cambios respecto al archivo que lo generó. No demuestra coherencia de la aplicación, ausencia de datos dañados en origen ni autenticidad si un atacante modifica ambos archivos.
¿Por qué no se añade una contraseña al script de la base de datos?
Las credenciales incrustadas se filtran con facilidad. Usa el mecanismo de autenticación o archivo protegido correspondiente y revisa los permisos de la identidad que ejecutará el backup.
En pocas palabras
Una copia útil necesita origen coherente, errores visibles, destino protegido y una restauración comprobada. El archivo local es una primera etapa; no sustituye almacenamiento externo ni una política de retención.
Conclusión
Automatiza primero un respaldo que puedas recuperar manualmente. Después incorpora copia externa, supervisión y retención, comprobando que cada cambio conserva una ruta de restauración.
Para continuar, revisa Cómo instalar Ubuntu desde una USB: paso a paso y Cómo instalar Docker en Ubuntu 24.04: guía práctica paso a paso.
Fuentes y documentación
Documentación de manpages.debian.org.
Documentación de manpages.debian.org.
