Curso de Linux / Automatizar copias de seguridad y comprobaciones del servidor

En la operación del servidor, se necesitan tanto copias de seguridad recuperables como revisiones de estado que permitan detectar fallos. Cree archivos de respaldo, verifique la integridad de los archivos, realice restauraciones reales y compruebe por separado la respuesta HTTP y el espacio en disco, además de establecer un camino desde fuera del servidor para detectar fallas o ejecuciones no realizadas.

Parta de un procedimiento que haya superado la prueba manual de copia y restauración antes de conectarlo a la ejecución programada. Compruebe por separado el archivo generado, una restauración de prueba y la detección de fallos; una tarea registrada no demuestra que se haya ejecutado correctamente.

Los ejemplos se orientan a máquinas virtuales con instalaciones habituales de Ubuntu 26.04 LTS y Rocky Linux 9. En contenedores, WSL y otras versiones pueden cambiar los servicios y paquetes. Prepare el acceso de recuperación y compruebe la versión como se explica en crear un entorno de práctica con una máquina virtual.

Datos que protege esta práctica y sus límites

El objetivo son archivos normales con cambios limitados durante la ejecución, como el contenido estático del capítulo 33. La configuración del servicio, certificados, DNS y procedimientos de despliegue deben respaldarse y documentarse por separado, y las bases de datos deben utilizar el método de respaldo consistente del producto correspondiente. El respaldo local que se muestra a continuación es una etapa para aprender la estructura de ejecución y no es un almacén final capaz de soportar fallos de disco del servidor o compromisos de cuenta.

Seleccione un directorio de origen que los usuarios normales puedan leer y un directorio de respaldo que solo usted pueda escribir. No programe todo el script como root solo para leer cómodamente archivos que requieren root. Los respaldos operativos requieren una cuenta dedicada y definir por separado la ruta permitida, la gestión de claves de cifrado y el período de retención.

Crear un script de respaldo que reciba rutas como parámetros

Necesita Bash y las utilidades GNU realpath, tar, sha256sum y date. Compruebe que no existan ~/bin/course-backup.sh ni ~/bin/course-health.sh; si existen, conserve esos archivos y elija nombres distintos en toda la práctica. Use un directorio concreto de datos de prueba como origen, nunca / ni una copia completa del sistema. Ejecute la preparación por pasos y deténgase si falla una orden.

mkdir -p "$HOME/bin"
cat > "$HOME/bin/course-backup.sh" <<'EOF'
#!/usr/bin/env bash
set -u
set -o pipefail
umask 077
if (( $# != 2 )); then
  printf "Usage: %s SOURCE_DIRECTORY BACKUP_DIRECTORY\n" "$0" >&2
  exit 2
fi
source_dir=$(realpath -e -- "$1") || exit 1
backup_dir=$(realpath -e -- "$2") || exit 1
[[ -d "$source_dir" && -d "$backup_dir" ]] || exit 1
case "$backup_dir/" in
  "$source_dir/"*) printf "Backup must be outside source\n" >&2; exit 1 ;;
esac
work=$(mktemp -d "$backup_dir/backup.XXXXXXXX") || exit 1
if ! tar -czf "$work/data.tar.gz" -C "$source_dir" .; then
  printf "Archive failed: %s\n" "$work" >&2; exit 1
fi
if ! tar -tzf "$work/data.tar.gz" > /dev/null; then
  printf "Archive listing failed\n" >&2; exit 1
fi
if ! (cd "$work" && sha256sum data.tar.gz > data.tar.gz.sha256); then
  printf "Checksum creation failed\n" >&2; exit 1
fi
if ! date --iso-8601=seconds > "$work/created-at.txt"; then exit 1; fi
printf "complete\n" > "$work/COMPLETE" || exit 1
printf "Backup ready: %s\n" "$work"
EOF
bash -n "$HOME/bin/course-backup.sh"

El script crea un directorio único y escribe el archivo COMPLETE al terminar el archivado y sus comprobaciones. Esa marca identifica una ejecución completada, pero todavía debe probar la restauración y el funcionamiento de los datos. Investigue los directorios incompletos y exclúyalos de los puntos de recuperación. El script registra la fecha y conserva las copias anteriores.

Probar ejecución, integridad y restauración por separado

lab=$(mktemp -d "$HOME/linux-ops-lab.XXXXXX")
mkdir "$lab/site" "$lab/backups" "$lab/restored"
printf "site version 1\n" > "$lab/site/index.html"
bash "$HOME/bin/course-backup.sh" "$lab/site" "$lab/backups"
find "$lab/backups" -maxdepth 2 -type f -print

Sustituya ACTUAL_BACKUP_DIRECTORY por la ruta que aparece tras Backup ready:. Verifique cada orden y deténgase si falta COMPLETE o falla el checksum; no continúe con la extracción en ese caso. La integridad y el listado de tar no demuestran que la aplicación funcione: restaure en el directorio vacío, compare los archivos y pruebe después su uso.

backup=ACTUAL_BACKUP_DIRECTORY
test -f "$backup/COMPLETE"
(cd "$backup" && sha256sum -c data.tar.gz.sha256)
tar -xzf "$backup/data.tar.gz" -C "$lab/restored"
diff -r "$lab/site" "$lab/restored"

El resultado normal es que exista COMPLETE, la suma de comprobación esté OK y no haya diferencias en diff. La restauración se realiza en un directorio vacío y se deben verificar permisos, propietario y etiquetas necesarias. Incluso después de moverlo a un repositorio remoto, repita la verificación de suma de comprobación y la prueba de restauración. No elimine aleatoriamente todas las copias antiguas cuando falte espacio, sino que aplique una política que conserve los puntos de recuperación necesarios.

Script para verificar la respuesta HTTP y el espacio disponible

El script necesita curl, df y awk, y recibe tres argumentos: URL, espacio libre mínimo en kibibytes (KiB, 1024 bytes) y ruta del almacenamiento que debe comprobar. Considera satisfactorios los estados HTTP 200–299; una redirección o un inicio de sesión pueden exigir otro criterio. No comprueba el contenido esperado ni el estado de una base de datos.

cat > "$HOME/bin/course-health.sh" <<'EOF'
#!/usr/bin/env bash
set -u
set -o pipefail
if (( $# != 3 )); then
  printf "Usage: %s URL MIN_FREE_KIB STORAGE_PATH\n" "$0" >&2; exit 2
fi
url=$1
minimum=$2
path=$3
[[ "$minimum" =~ ^[0-9]+$ ]] || exit 2
if ! status=$(curl -sS -o /dev/null -w "%{http_code}" --connect-timeout 5 --max-time 15 "$url"); then
  printf "HTTP transport failed\n" >&2; exit 1
fi
[[ "$status" =~ ^2[0-9][0-9]$ ]] || { printf "HTTP status=%s\n" "$status" >&2; exit 1; }
available=$(df -Pk -- "$path" | awk 'NR==2 {print $4}') || exit 1
[[ "$available" =~ ^[0-9]+$ ]] || exit 1
(( 10#$available >= 10#$minimum )) || { printf "Low storage: %s KiB\n" "$available" >&2; exit 1; }
printf "OK http=%s free_kib=%s\n" "$status" "$available"
EOF
bash -n "$HOME/bin/course-health.sh"
bash "$HOME/bin/course-health.sh" http://127.0.0.1/ 102400 "$HOME"

El umbral de 102400 KiB equivale a 100 MiB y es solo un valor de práctica. Ajústelo al crecimiento y al espacio de recuperación; revise también los inodos. Use un entero que quepa en el rango aritmético de Bash: el script comprueba dígitos, pero no detecta todos los desbordamientos posibles. En Nginx con sitios por nombre, use el dominio real o la cabecera Host necesaria para no confundir la página predeterminada con la aplicación objetivo.

Conexión de temporizador y detección de fallos externos

Reutilice el servicio y el temporizador de la lección sobre cron y systemd. Por ejemplo, el valor de ExecStart puede ser /bin/bash %h/bin/course-backup.sh RUTA_ORIGEN RUTA_COPIAS. Sustituya ambas rutas por directorios existentes y, si contienen espacios, cite cada argumento según la sintaxis de systemd. Pruebe primero la misma orden manualmente y ejecute la comprobación de estado en otra unidad.

Verifique por separado la próxima ejecución del temporizador, el estado de finalización del servicio y la última hora de creación de COMPLETE. La revisión dentro del mismo servidor se detendrá si el servidor entero se detiene, por lo que un monitor externo debe verificar la URL real y la última hora de respaldo. Pruebe también las rutas de recepción y los tiempos de fallo de las notificaciones por correo o mensajería, y decida quién y qué se recuperará cuando se genere una alerta.

Experimento de fallos y limpieza

Verifique una condición a la vez para ver si el respaldo falla con una ruta de origen inexistente, si la verificación falla con una ruta HTTP inexistente, o si falla con un umbral de espacio libre excesivamente grande, y luego restaure los valores originales. También verifique que los respaldos sin indicación de finalización no se reporten como exitosos. Detenga y desactive primero el temporizador de práctica y luego limpie solo los scripts y la nueva carpeta de trabajo.

Documentación oficial