No existen las copias de seguridad; solo existen las restauraciones probadas. Guarda esa frase, porque es la única idea de esta lección que no puedes permitirte olvidar. En srv-tramontana hay copias desde hace semanas: respaldo_tramontana.sh las genera, verifica sus sha256sum, las deja en un volumen propio y un timer de systemd lo dispara cada madrugada. Todo eso suena muy bien y no demuestra absolutamente nada, porque nadie ha restaurado nunca ninguna. Una copia que no se ha restaurado es una hipótesis, no una protección. Esta lección cierra el módulo convirtiendo esa hipótesis en un procedimiento probado, con RPO y RTO acordados, retención por generaciones, copias incrementales que no crecen sin control, cifrado, verificación y un runbook que alguien podría seguir aunque tú estuvieras de vacaciones.

Contenido

  1. Qué se respalda y qué no: el inventario de Tramontana
  2. RPO y RTO: cuánto podemos perder y cuánto tardar
  3. La regla 3-2-1 y la retención por generaciones
  4. Completa, incremental y diferencial
  5. Consistencia: el fichero que se escribe mientras lo copias
  6. Herramientas: tar, rsync, dd y restic
  7. Copias del sistema frente a reconstruir por código
  8. Cifrado, custodia y obligaciones legales
  9. Verificación y la prueba de restauración
  10. Automatizar y vigilar la edad de la última copia
  11. Restaurar: los tres escenarios de Tramontana
  12. El runbook de recuperación

  1. Qué se respalda y qué no: el inventario de Tramontana

La primera decisión no es técnica: es decidir qué merece copiarse. La regla es sencilla: se respalda lo que no se puede reconstruir.

Categoría ¿Se copia? Por qué
Datos de negocio (reservas, base de datos, subidas) Sí, lo primero Irrecuperables: son el negocio
Configuración (/etc, unidades, sudoers, fstab) Sí Reconstruible, pero cuesta horas y se olvidan detalles
Secretos (claves, certificados, db_password) Sí, cifrados y aparte Sin ellos no arranca nada; con ellos en claro, la copia es una bomba
Sistema operativo y paquetes No: basta la lista apt-mark showmanual los reinstala
Releases de la aplicación Solo el activo Los demás están en el repositorio de artefactos
Logs Según retención acordada Valor forense y legal, no operativo
Cachés, temporales, /proc, /sys Nunca Se regeneran; solo ocupan y ralentizan

El inventario concreto de Tramontana, que es lo que va a copiarse:

/home/operador/datos/reservas.csv       # datos personales de huéspedes  (CRÍTICO)
base de datos tramontana                # volcado lógico diario         (CRÍTICO)
/opt/tramontana/shared/uploads/         # documentos subidos             (CRÍTICO)
/etc/tramontana/                        # app.conf, desplegar.conf      (ALTO)
/etc/systemd/system/tramontana*         # unidades y timers             (ALTO)
/etc/sudoers.d/tramontana, /etc/fstab, /etc/logrotate.d/tramontana   (ALTO)
/home/operador/scripts/ y bin/          # ya versionados en git          (MEDIO)
/opt/tramontana/releases/3.2.1/         # solo el release activo         (MEDIO)
/opt/tramontana/HISTORIAL               # la memoria de los cambios      (ALTO)
lista de paquetes: apt-mark showmanual                                  (MEDIO)

  1. RPO y RTO: cuánto podemos perder y cuánto tardar

Dos siglas que hay que acordar con Marta, no decidir en solitario:

  • RPO (Recovery Point Objective): cuántos datos podemos permitirnos perder, medido en tiempo. Si la copia es diaria a las 02:30 y el servidor muere a las 18:00, se pierden 15,5 horas de reservas. ¿Es aceptable?
  • RTO (Recovery Time Objective): cuánto puede estar caído el servicio mientras se restaura.

Traducido a Tramontana con cifras reales: entran unas 25 reservas al día, con un importe medio de 313,70 €. Perder un día completo son unos 7.842,50 € en reservas que habría que reconstruir a mano desde los correos de confirmación, con el coste reputacional de llamar a los huéspedes.

Escenario RPO acordado RTO acordado Qué implica técnicamente
Borrado accidental de un fichero 24 h 30 min Copia diaria basta
Release corrupto 0 15 min Copia previa al despliegue (ya existe)
Pérdida total del servidor 4 h 8 h Copia cada 4 horas de la base de datos y copia fuera del servidor

Ese RPO de 4 horas para la base de datos es la decisión que cambia el diseño: la copia diaria de las 02:30 no lo cumple, y hace falta un volcado cada cuatro horas. Cada mejora de RPO o RTO cuesta dinero y complejidad; por eso la decisión es del negocio, con tu asesoramiento técnico.

  1. La regla 3-2-1 y la retención por generaciones

La regla 3-2-1 resume décadas de desastres:

  • 3 copias de los datos (el original y dos más).
  • En 2 soportes o sistemas distintos.
  • 1 de ellas fuera del emplazamiento.

Hoy en srv-tramontana tenemos una copia, en el mismo servidor, en el mismo edificio. Si el disco falla en un modo que se lleve por delante el VG, o si alguien cifra la máquina, o si se incendia la oficina, no hay copia. /srv/tramontana/backups es una comodidad, no una protección. La variante moderna añade un 1-0: al menos una copia inmutable o sin conexión, y cero errores en la última verificación, porque el ransomware moderno busca y cifra los destinos de copia accesibles desde el servidor.

Retención GFS (Grandfather-Father-Son): no todas las copias valen lo mismo con el tiempo.

Generación Frecuencia Se conservan Para qué
Hijas (diarias) Cada día 14 Errores recientes: un borrado de ayer
Padres (semanales) Domingo 8 Corrupción detectada semanas después
Abuelas (mensuales) Día 1 12 Requisitos legales y auditoría

Con eso, restic forget --keep-daily 14 --keep-weekly 8 --keep-monthly 12 deja el histórico exacto que acordaste, sin decisiones improvisadas.

  1. Completa, incremental y diferencial

Tipo Qué copia Espacio Tiempo de copia Restauración
Completa Todo, cada vez Máximo Máximo La más rápida: un solo conjunto
Incremental Lo cambiado desde la copia anterior (sea cual sea) Mínimo Mínimo La más lenta: completa + todas las incrementales, en orden
Diferencial Lo cambiado desde la última completa Intermedio, creciente Intermedio Media: completa + una diferencial

El compromiso clásico: completa semanal + incrementales diarias. La cadena incremental tiene un riesgo real que hay que decir en voz alta: si se pierde o corrompe un eslabón, todo lo posterior es irrecuperable. Por eso se verifican todas, no solo la última. Las herramientas modernas con deduplicación (restic, borg) eliminan casi todo este dilema: cada copia se comporta como completa a la hora de restaurar y ocupa como una incremental.

  1. Consistencia: el fichero que se escribe mientras lo copias

Copiar un fichero mientras alguien lo escribe produce basura: la primera mitad del fichero es de antes del cambio y la segunda de después. En una base de datos, esa mezcla es una copia que no se puede abrir. Tres soluciones, en orden de preferencia:

Solución Cómo Corte de servicio Cuándo usarla
Volcado en caliente de la aplicación pg_dump, mysqldump, exportación propia Ninguno La mejor: la aplicación garantiza coherencia
Snapshot LVM (05-04) Congela el volumen en un instante Segundos Ficheros que no tienen volcado propio
Parar el servicio systemctl stop, copiar, start El que dure la copia Último recurso

El snapshot en la práctica, aplicando lo de 05-04 y aprovechando los 5 GiB libres que dejamos en el VG a propósito:

sudo lvcreate -L 2G -s -n snap-copia /dev/vg-datos/lv-backups
sudo mkdir -p /mnt/snap && sudo mount -o ro /dev/vg-datos/snap-copia /mnt/snap
# ... copiar desde /mnt/snap, con la tranquilidad de un estado congelado ...
sudo umount /mnt/snap && sudo lvremove -y /dev/vg-datos/snap-copia

La secuencia correcta y completa para la base de datos de Tramontana combina las dos primeras: volcado lógico con pg_dump (coherente por definición) y snapshot para los ficheros de uploads, que no tienen volcado propio.

  1. Herramientas: tar, rsync, dd y restic

tar con incrementales

# Copia completa: crea el fichero de estado (snar) que registra qué se copió
sudo tar --listed-incremental=/srv/tramontana/backups/estado.snar \
     -czf /srv/tramontana/backups/completa-$(date +%F).tar.gz /etc/tramontana /opt/tramontana/shared

# Incremental: el MISMO fichero .snar; tar copia solo lo cambiado desde entonces
sudo tar --listed-incremental=/srv/tramontana/backups/estado.snar \
     -czf /srv/tramontana/backups/inc-$(date +%F).tar.gz /etc/tramontana /opt/tramontana/shared

El .snar es el cerebro de la operación: si lo pierdes, la siguiente «incremental» será una completa, y si lo mezclas entre cadenas, la copia será inconsistente. Guárdalo con las copias y hazle una copia aparte. Y la inspección antes de extraer, como manda la convención del curso:

tar -tzvf /srv/tramontana/backups/completa-2026-08-19.tar.gz | head -5

rsync --link-dest: el truco que hay que conocer

Aquí se cierra el círculo con los enlaces duros de 02-06. --link-dest compara con una copia anterior y, para cada fichero que no ha cambiado, crea un enlace duro en lugar de copiar los datos. Resultado: cada copia se ve y se restaura como una copia completa, pero en disco solo ocupa lo que ha cambiado.

ayer=$(date -d yesterday +%F)
hoy=$(date +%F)
rsync -aHAX --delete \
      --link-dest="/srv/tramontana/backups/diarias/$ayer" \
      /opt/tramontana/shared/ \
      "/srv/tramontana/backups/diarias/$hoy/"
$ du -sh --apparent-size /srv/tramontana/backups/diarias/2026-08-19
2,1G	/srv/tramontana/backups/diarias/2026-08-19
$ du -sh /srv/tramontana/backups/diarias/2026-08-19
118M	/srv/tramontana/backups/diarias/2026-08-19

Aparenta 2,1 GiB —y al restaurar lo son—, pero solo consume 118 MiB de disco nuevo. Dos avisos: los enlaces duros no protegen de la corrupción de un bloque (todas las copias comparten el mismo inodo y, por tanto, el mismo daño), y borrar la copia base no rompe nada, porque el inodo sobrevive mientras quede un enlace.

dd: imágenes completas y su peligro

dd copia bloque a bloque, sin entender de ficheros. Sirve para clonar un disco entero o el sector de arranque, y es la orden más peligrosa de esta lección: invertir if= y of= destruye el destino sin preguntar. Se le llama «disk destroyer» por algo.

sudo dd if=/dev/sdb of=/srv/imagenes/sdb.img bs=4M status=progress conv=fsync

Requiere el dispositivo desmontado o congelado para que la imagen sea consistente, y copia también el espacio vacío. Para copias regulares de datos, casi nunca es la respuesta.

restic: la solución moderna

Deduplicación, cifrado de serie, verificación de integridad y retención declarativa. Uso real completo:

export RESTIC_REPOSITORY=/srv/copias-remotas/tramontana
export RESTIC_PASSWORD_FILE=/root/.restic-clave      # modo 0600, NUNCA en el script

restic init                                            # crear el repositorio (una vez)
restic backup --tag diaria /home/operador/datos /etc/tramontana /opt/tramontana/shared
restic snapshots                                       # qué hay guardado
restic ls latest /home/operador/datos                  # navegar sin restaurar
restic restore latest --target /tmp/restauracion --include /home/operador/datos/reservas.csv
restic forget --keep-daily 14 --keep-weekly 8 --keep-monthly 12 --prune
restic check --read-data-subset=10%                    # verificación real de los datos
$ restic backup --tag diaria /home/operador/datos /etc/tramontana
Files:        142 new,     3 changed,  1204 unmodified
Added to the repository: 41.882 MiB (12.204 MiB stored)
snapshot 8a3f2c19 saved

Fíjate en 41.882 MiB añadidos que ocupan 12.204 MiB reales: eso es deduplicación más compresión. borg es equivalente en prestaciones; rsnapshot es la versión clásica del truco de --link-dest, útil si prefieres copias navegables con ls sin herramienta intermedia.

  1. Copias del sistema frente a reconstruir por código

Copiar el sistema entero (imagen o tar de /) permite volver exactamente al estado anterior, pero produce copias enormes y arrastra la basura acumulada, incluido cualquier problema latente. La alternativa moderna es reconstruir el servidor por código: una máquina limpia, un playbook que instale y configure todo, y encima solo los datos restaurados de la copia.

Enfoque Ventajas Inconvenientes
Imagen del sistema Vuelta exacta, rápida Enorme; restaura también los problemas
Datos + reconstrucción por código Copias pequeñas, entorno limpio, reproducible Exige mantener el código de aprovisionamiento y probarlo

Tramontana va camino de lo segundo, y esa es la razón de que el inventario incluya /etc/tramontana, las unidades de systemd y la lista de paquetes: son la entrada del futuro playbook de Ansible que verás en 07-06. Mientras tanto, la lista de paquetes es tu seguro:

apt-mark showmanual > /srv/tramontana/backups/paquetes-$(date +%F).txt

  1. Cifrado, custodia y obligaciones legales

Una copia sin cifrar es una fuga esperando a ocurrir. El original vive en un servidor con permisos, sudo, ACL y endurecimiento de systemd; la copia acaba en un disco USB, en un bucket o en la casa de alguien, sin ninguna de esas protecciones. Y contiene exactamente los mismos datos.

Cifra en origen, antes de que la copia salga del servidor: restic y borg lo hacen de serie, y con tar se encadena gpg o age. La gestión de las claves —dónde viven, quién las custodia, cómo se rotan, qué pasa si se pierden— es materia de 06-05, y no es un detalle menor: una copia cifrada cuya clave se ha perdido es exactamente igual de útil que no tener copia.

Advertencia de cumplimiento (RGPD). reservas.csv y la base de datos contienen datos personales de huéspedes (nombre, contacto, fechas de estancia). Las copias heredan todas las obligaciones del original: cifrado en reposo y en tránsito, control de acceso documentado, registro de quién accede, retención limitada al tiempo necesario, y —el punto que casi siempre se olvida— el derecho de supresión alcanza también a las copias de seguridad, lo que obliga a tener una política escrita de cómo se atiende una solicitud de borrado cuando el dato está en copias inmutables. Si además la copia sale a un proveedor en la nube, entra en juego el encargado del tratamiento y la ubicación de los datos. Nada de esto lo decides tú: debe definirlo y aprobarlo el responsable de protección de datos o de cumplimiento, y tu trabajo es implementarlo y poder demostrarlo.

  1. Verificación y la prueba de restauración

Una copia no verificada es un fichero de tamaño tranquilizador. Hay tres niveles, y hay que hacer los tres:

Nivel Qué comprueba Comando
Integridad Los bits no se han corrompido sha256sum -c copia.sha256
Estructura El archivo se puede leer entero tar -tzf, restic check --read-data
Utilidad Los datos restaurados sirven Restauración real y comprobación funcional

Solo el tercero demuestra algo. Los dos primeros se automatizan; el tercero se agenda:

$ sha256sum -c /srv/tramontana/backups/tramontana-2026-08-19.tar.gz.sha256
/srv/tramontana/backups/tramontana-2026-08-19.tar.gz: La suma coincide
$ tar -tzf /srv/tramontana/backups/tramontana-2026-08-19.tar.gz >/dev/null && echo "estructura OK"
estructura OK
$ restic check --read-data-subset=10%
no errors were found

La prueba de restauración periódica es parte del procedimiento, no un extra: una vez al trimestre, restaurar en una VM limpia, arrancar la aplicación, comprobar que las 25 reservas están y que la suma de importes da 7.842,50 €, cronometrar cuánto se ha tardado (¿cumple el RTO de 8 h?) y anotar el resultado con fecha y nombre de quien la hizo. Una prueba de restauración que nadie ha cronometrado no permite prometer ningún RTO.

  1. Automatizar y vigilar la edad de la última copia

Ya tienes la automatización de 05-05: tramontana-respaldo.service con su timer, Persistent=true y RequiresMountsFor. Falta la vigilancia, y aquí está el error más común del sector: vigilar que el trabajo se ejecutó en lugar de vigilar que hay una copia reciente y válida. Un script que falla en silencio y un timer deshabilitado producen el mismo síntoma: nada. La métrica que de verdad importa es la edad de la última copia correcta.

#!/usr/bin/env bash
# /home/operador/scripts/comprobar_copia.sh — silencio si todo va bien
set -euo pipefail
source "$(dirname "$(readlink -f "$0")")/lib/comunes.sh"

readonly DESTINO="/srv/tramontana/backups"
readonly MAX_HORAS="${TRAMONTANA_MAX_HORAS_COPIA:-30}"

main() {
    local ultima edad_h
    ultima=$(find "$DESTINO" -maxdepth 1 -name 'tramontana-*.tar.gz' -printf '%T@ %p\n' \
             | sort -rn | head -1 | cut -d' ' -f2-) || true
    [[ -n "$ultima" ]] || morir 2 "no hay ninguna copia en $DESTINO"
    edad_h=$(( ( $(date +%s) - $(stat -c %Y "$ultima") ) / 3600 ))
    (( edad_h <= MAX_HORAS )) || morir 2 "la última copia tiene ${edad_h}h (máximo ${MAX_HORAS}h)"
    sha256sum -c "${ultima}.sha256" --status || morir 2 "suma incorrecta en $ultima"
    log "copia correcta: $(basename "$ultima") (${edad_h}h)"
}
main "$@"

Se dispara con su propio timer a las 08:00, después de la ventana de copia, y solo notifica cuando hay algo que hacer: es el principio de «silencio si todo va bien» aplicado a la única métrica que importa.

  1. Restaurar: los tres escenarios de Tramontana

(a) Borrado accidental de reservas.csv

RPO 24 h, RTO 30 min. Luis ha ejecutado un mv desafortunado a las 11:40.

# 1. PARAR el daño: que la aplicación no siga escribiendo sobre un estado inconsistente
sudo systemctl stop tramontana.service

# 2. Localizar la copia más reciente y comprobar QUÉ contiene antes de tocar nada
restic snapshots --tag diaria | tail -3
restic ls latest /home/operador/datos | grep reservas

# 3. Restaurar a un directorio APARTE, nunca directamente encima del original
restic restore latest --target /tmp/rest --include /home/operador/datos/reservas.csv

# 4. Verificar el contenido restaurado ANTES de ponerlo en su sitio
wc -l /tmp/rest/home/operador/datos/reservas.csv          # 26 (cabecera + 25 reservas)
awk -F';' 'NR>1 {s+=$6} END {printf "%.2f\n", s}' /tmp/rest/home/operador/datos/reservas.csv
# -> 7842.50

# 5. Colocarlo con propiedad y permisos correctos, y arrancar
sudo install -o operador -g tramontana -m 0640 \
     /tmp/rest/home/operador/datos/reservas.csv /home/operador/datos/reservas.csv
sudo systemctl start tramontana.service && sudo -u operador ~/scripts/revision_salud.sh

El paso 4 es lo que separa una restauración de un acto de fe: 26 líneas y 7.842,50 € son las cifras conocidas del fichero. Si no cuadran, la copia no sirve y hay que ir a la anterior.

(b) Release corrupto que hay que revertir

RPO 0, RTO 15 min. Es el caso de la 3.3.0, que pesa 99,2 MiB y no arranca. desplegar.sh ya revierte solo (05-05), pero si el fallo se detecta más tarde:

ls -l /opt/tramontana/app                     # a qué release apunta ahora
sudo systemctl stop tramontana.service
sudo ln -sfn releases/3.2.1 /opt/tramontana/app.nuevo
sudo mv -T /opt/tramontana/app.nuevo /opt/tramontana/app     # cambio atómico
sudo tar -xzf /srv/tramontana/backups/pre-despliegue/conf-3.2.1.tar.gz -C /   # su config
sudo systemctl start tramontana.service
curl -sf -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/salud   # 200

Aquí no interviene la copia diaria: la que salva el día es la copia previa al despliegue de /srv/tramontana/backups/pre-despliegue/, y el enlace simbólico relativo permite volver atrás en un segundo. Esto es 02-06 y 05-05 trabajando juntos.

(c) Pérdida total del servidor

RPO 4 h, RTO 8 h. El escenario que todo el mundo evita pensar. Procedimiento completo:

  1. Máquina nueva: Ubuntu Server 24.04 LTS, mismo hostname, mismo esquema de particionado con /var aislada (01-04).
  2. Identidades primero, y con los mismos números, o los permisos de la restauración no cuadrarán: groupadd -g 1002 tramontana, useradd -r -u 997 -g tramontana -s /usr/sbin/nologin svc-tramontana, más operador y luis (05-01).
  3. Paquetes: xargs -a paquetes-2026-08-19.txt sudo apt install --no-install-recommends -y, con el hold de la base de datos (05-03).
  4. Discos: recrear PV, VG y LV, formatear y montar /srv/tramontana/backups por UUID con nofail, y mount -a antes de reiniciar (05-04).
  5. Datos: restic restore <snapshot> --target /, y el volcado de la base de datos con psql < volcado.sql.
  6. Configuración y servicios: restaurar /etc/tramontana, las unidades, sudoers.d, logrotate.d; systemctl daemon-reload; systemctl enable --now tramontana.service tramontana-respaldo.timer (05-05, 05-06).
  7. Verificar: revision_salud.sh, contar las 25 reservas, comprobar la suma de 7.842,50 €, systemctl --failed vacío, y probar una reserva real de principio a fin.
  8. Cronometrar y anotar cuánto se ha tardado. Ese número es el RTO real, y es el que puedes prometer.

Fíjate en que este procedimiento usa las ocho lecciones del módulo. Ese es el sentido del Módulo 5.

  1. El runbook de recuperación

Un runbook es el documento que permite que la recuperación la haga otra persona, de madrugada, con prisa y sin ti. Debe contener:

  • Inventario de qué se copia, dónde va y con qué frecuencia.
  • RPO y RTO acordados, con quién los aprobó y cuándo.
  • Dónde están las claves de cifrado y quién las custodia (no la clave: dónde está).
  • Los procedimientos de los tres escenarios, con comandos literales copiables.
  • Contactos: quién decide, quién ejecuta, quién avisa a los clientes.
  • Fecha y resultado de la última prueba de restauración, y quién la hizo.

Y lo más importante: no puede guardarse solo en el servidor que vas a perder. Copia impresa, repositorio git externo, gestor documental de la empresa. Un runbook que solo existe en /opt/tramontana/HISTORIAL es un runbook que desaparece en el escenario (c), justo cuando lo necesitas.

sudo tee -a /opt/tramontana/HISTORIAL >/dev/null <<'FIN'
2026-08-19  Respaldo y restauración (operador, aprobado por Marta Vidal)
  - RPO/RTO: 4h/8h para pérdida total; volcado de BD cada 4h además de la copia diaria
  - restic en /srv/copias-remotas + réplica fuera del servidor (3-2-1 pendiente de destino)
  - Retención GFS: 14 diarias, 8 semanales, 12 mensuales
  - comprobar_copia.sh + timer 08:00: avisa si la última copia supera 30h o falla el sha256
  - Prueba de restauración completa: 2026-08-19, 3h 42min (RTO 8h cumplido). Runbook fuera del servidor.
FIN

Errores Comunes y Consejos

  • No haber restaurado nunca. Es el error de esta lección. Agenda la prueba trimestral hoy, con fecha y responsable.
  • La copia en el mismo servidor. Un incendio, un cifrado por ransomware o un fallo del VG se lleva original y copia. 3-2-1, sin excusas.
  • Perder el fichero .snar de tar --listed-incremental, o mezclarlo entre cadenas: la copia incremental deja de ser recuperable.
  • Copiar una base de datos en caliente con cp. Produce un fichero inservible. Volcado propio o snapshot.
  • Copias sin cifrar que salen del servidor, o cifradas con una clave que nadie custodia. Ambas cosas son igual de graves.
  • Vigilar el trabajo en vez del resultado. Lo que importa es la edad de la última copia correcta, no que el script terminara.
  • Restaurar directamente encima del original. Restaura a un directorio aparte, verifica y luego coloca.
  • Retención infinita «por si acaso». Cuesta dinero y choca con el RGPD: la retención se acuerda y se documenta.
  • Consejo: cronometra cada restauración de prueba. El RTO que puedes prometer es el que has medido, no el que te gustaría.

Ejercicios

  1. Diseñar el esquema. A partir del RPO de 4 h y el RTO de 8 h acordados con Marta, describe el esquema completo de copias de Tramontana: qué se copia, con qué frecuencia, con qué herramienta, dónde va cada copia y qué retención tiene. Justifica dónde falla hoy la regla 3-2-1.
  2. Verificar sin restaurar del todo. Escribe los comandos que comprueban, sin tocar producción, que la copia de anoche contiene reservas.csv con las 25 reservas y que su suma de importes es correcta. Explica por qué esto no sustituye a una prueba de restauración.
  3. El eslabón perdido. Tienes una completa del domingo y seis incrementales de tar. La del miércoles está corrupta. ¿Hasta qué día puedes restaurar y por qué? ¿Qué habrías hecho diferente para que este problema no existiera?

Soluciones

1.

Qué Frecuencia Herramienta Destino Retención
Volcado de la base de datos Cada 4 h pg_dump + restic Repositorio restic local y replicado fuera 14 d / 8 sem / 12 meses
reservas.csv, uploads, /etc Diaria, 02:30 restic backup Igual Igual
Release activo y HISTORIAL Diaria restic backup Igual 14 diarias
Configuración previa a despliegue En cada despliegue tar (desplegar.sh) /srv/tramontana/backups/pre-despliegue 10 despliegues
Lista de paquetes Semanal apt-mark showmanual Con la copia 8 semanales

Dónde falla hoy la 3-2-1: hay una sola copia (falla el «3»), en el mismo servidor y el mismo disco lógico (falla el «2») y sin ninguna fuera del emplazamiento (falla el «1»). El mínimo aceptable es añadir una réplica del repositorio restic a un destino remoto con credenciales de solo añadir, para que un compromiso del servidor no permita borrar el histórico.

2.

$ restic snapshots --latest 1 --json | jq -r '.[0].time'
2026-08-19T02:30:41+02:00
$ restic ls latest /home/operador/datos | grep reservas.csv
/home/operador/datos/reservas.csv
$ restic dump latest /home/operador/datos/reservas.csv | wc -l
26
$ restic dump latest /home/operador/datos/reservas.csv \
    | awk -F';' 'NR>1 {n++; s+=$6} END {printf "%d reservas, %.2f EUR\n", n, s}'
25 reservas, 7842.50 EUR

restic dump extrae un fichero a stdout sin escribir nada en disco, así que la comprobación no toca producción ni requiere espacio.

Por qué no sustituye a una prueba de restauración: esto verifica un fichero, no el conjunto; no comprueba permisos, propietarios ni ACL; no valida que la base de datos restaurada arranque ni que la aplicación funcione con esos datos; y, sobre todo, no cronometra nada, así que no permite afirmar que se cumple el RTO. Verificar es necesario; restaurar es lo que demuestra.

3. Puedes restaurar hasta el martes: la completa del domingo más las incrementales del lunes y el martes. La del miércoles está corrupta, y como cada incremental de tar --listed-incremental contiene solo lo cambiado desde la anterior, las de jueves, viernes y sábado dependen de un estado que ya no puedes reconstruir. Un fichero modificado el miércoles y no vuelto a tocar solo existe en el eslabón roto.

Qué habría evitado el problema, por orden de eficacia:

  • Verificar cada copia al crearla (tar -tzf y sha256sum), no solo la última: el miércoles habrías sabido que había que repetirla.
  • Usar diferenciales en vez de incrementales: cada una depende solo de la completa, así que un eslabón roto cuesta un día, no cuatro.
  • Mejor aún, usar una herramienta con deduplicación y verificación como restic, donde cada snapshot se restaura por sí solo y restic check --read-data detecta la corrupción antes de que la necesites.

Conclusión

Has cerrado el Módulo 5, y con él la distancia entre «tengo scripts» y «gobierno un servidor». Repasa lo que ha cambiado en srv-tramontana desde que empezaste:

  • 05-01 — Las identidades dejaron de ser magia: el grupo tramontana (gid 1002) y la cuenta de servicio svc-tramontana (uid 997, sin shell ni contraseña) existen de verdad, con operador y luis en el grupo y la propiedad de /opt/tramontana y /srv/tramontana/backups en su sitio.
  • 05-02 — sudo dejó de ser una palabra mágica: hay una regla escrita, validada y documentada en /etc/sudoers.d/tramontana, más SGID en los directorios compartidos, ACL para que Luis lea los logs sin entrar en adm, capabilities en lugar de SUID y chattr +i sobre app.conf.
  • 05-03 — El software tiene procedencia: repositorios deb822 con claves en /etc/apt/keyrings/, la base de datos fijada con hold y pinning, y actualizaciones de seguridad desatendidas que avisan sin reiniciar solas.
  • 05-04 — Las copias viven en su propio volumen LVM ampliable en caliente, montado por UUID con nofail, con margen en el VG para snapshots y un fstab probado con mount -a.
  • 05-05 — La aplicación es un servicio de verdad: tramontana.service endurecido, con reinicio automático y límites de cgroup, y la copia nocturna convertida en tramontana-respaldo.service + .timer con Persistent=true; desplegar.sh por fin reinicia.
  • 05-06 — El servidor tiene memoria: journal persistente y acotado, /etc/logrotate.d/tramontana probado en simulación, los scripts escribiendo en el journal, y la respuesta exacta a «¿qué pasó anoche a las tres?».
  • 05-07 — Y tiene termómetro: línea base con umbrales, sysstat guardando historia, el método USE y un procedimiento de once pasos que ya resolvió la lentitud de las mañanas midiendo antes y después.
  • 05-08 — Y ahora tiene red de seguridad: RPO y RTO acordados con Marta, regla 3-2-1, retención GFS, consistencia con volcado y snapshot LVM, restic con deduplicación y cifrado, verificación en tres niveles, vigilancia de la edad de la última copia correcta y tres procedimientos de restauración escritos, probados y cronometrados.

Nada de esto era «saber comandos». Era construir un sistema que se sostiene cuando tú no estás delante, y esa es exactamente la diferencia entre usar Linux y administrarlo.

Y sin embargo, todo lo que has levantado en este módulo tiene una puerta abierta de par en par. srv-tramontana escucha en el 8080 sin cortafuegos, la configuración de red sigue siendo la que dejó el instalador, SSH acepta contraseñas y accesos de root sin que nadie haya revisado sshd_config, la db_password está en claro dentro de app.conf, el tráfico de reservas —con los datos personales de los huéspedes que tanto cuidado te ha costado proteger en las copias— viaja sin cifrar, y en /var/log/btmp ya hay cuarenta y siete intentos de acceso desde una IP que nadie ha bloqueado. En el Módulo 6: Redes y Seguridad cierras esa puerta: configurarás la red de forma persistente con netplan, endurecerás SSH con claves y sin root, levantarás un firewall que solo deje pasar lo imprescindible, detectarás y frenarás las intrusiones, sacarás los secretos de los ficheros de configuración y pondrás TLS delante de la aplicación, y terminarás aplicando un endurecimiento completo con AppArmor y una política de contraseñas que hoy sigue siendo la de fábrica. Has hecho un servidor que funciona; toca hacerlo defendible. Actualiza el snapshot de tu VM, guarda el runbook fuera de la máquina y nos vemos en el Módulo 6.

Curso de Linux: De Principiante a Administrador de Sistemas

Módulo 1: Introducción a Linux

Módulo 2: Comandos Básicos de Linux

Módulo 3: Habilidades Avanzadas en la Línea de Comandos

Módulo 4: Scripting en Shell

Módulo 5: Administración del Sistema

Módulo 6: Redes y Seguridad

Módulo 7: Temas Avanzados

Módulo 8: Proyectos Prácticos

© Copyright 2026. Todos los derechos reservados