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
- Qué se respalda y qué no: el inventario de Tramontana
- RPO y RTO: cuánto podemos perder y cuánto tardar
- La regla 3-2-1 y la retención por generaciones
- Completa, incremental y diferencial
- Consistencia: el fichero que se escribe mientras lo copias
- Herramientas:
tar,rsync,ddyrestic - Copias del sistema frente a reconstruir por código
- Cifrado, custodia y obligaciones legales
- Verificación y la prueba de restauración
- Automatizar y vigilar la edad de la última copia
- Restaurar: los tres escenarios de Tramontana
- El runbook de recuperación
- 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)
- 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.
- 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.
- 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.
- 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-copiaLa 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.
- Herramientas:
tar, rsync, dd y restic
tar, rsync, dd y restictar 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/sharedEl .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:
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-19Aparenta 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.
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 savedFí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.
- 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:
- 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.csvy 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.
- 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 foundLa 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.
- 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.
- 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.shEl 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 # 200Aquí 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:
- Máquina nueva: Ubuntu Server 24.04 LTS, mismo
hostname, mismo esquema de particionado con/varaislada (01-04). - 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ásoperadoryluis(05-01). - Paquetes:
xargs -a paquetes-2026-08-19.txt sudo apt install --no-install-recommends -y, con elholdde la base de datos (05-03). - Discos: recrear PV, VG y LV, formatear y montar
/srv/tramontana/backupspor UUID connofail, ymount -aantes de reiniciar (05-04). - Datos:
restic restore <snapshot> --target /, y el volcado de la base de datos conpsql < volcado.sql. - 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). - Verificar:
revision_salud.sh, contar las 25 reservas, comprobar la suma de 7.842,50 €,systemctl --failedvacío, y probar una reserva real de principio a fin. - 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.
- 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.
FINErrores 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
.snardetar --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
- 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.
- Verificar sin restaurar del todo. Escribe los comandos que comprueban, sin tocar producción, que la copia de anoche contiene
reservas.csvcon las 25 reservas y que su suma de importes es correcta. Explica por qué esto no sustituye a una prueba de restauración. - 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 EURrestic 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 -tzfysha256sum), 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 yrestic check --read-datadetecta 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 serviciosvc-tramontana(uid 997, sin shell ni contraseña) existen de verdad, conoperadoryluisen el grupo y la propiedad de/opt/tramontanay/srv/tramontana/backupsen su sitio. - 05-02 —
sudodejó 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 enadm, capabilities en lugar de SUID ychattr +isobreapp.conf. - 05-03 — El software tiene procedencia: repositorios deb822 con claves en
/etc/apt/keyrings/, la base de datos fijada conholdy 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 unfstabprobado conmount -a. - 05-05 — La aplicación es un servicio de verdad:
tramontana.serviceendurecido, con reinicio automático y límites de cgroup, y la copia nocturna convertida entramontana-respaldo.service+.timerconPersistent=true;desplegar.shpor fin reinicia. - 05-06 — El servidor tiene memoria: journal persistente y acotado,
/etc/logrotate.d/tramontanaprobado 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,
sysstatguardando 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,
resticcon 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
- ¿Qué es Linux?
- Historia de Linux
- Distribuciones de Linux
- Instalando Linux
- Primer Contacto con el Sistema
- Estructura del Sistema de Archivos de Linux
Módulo 2: Comandos Básicos de Linux
- Introducción a la Línea de Comandos
- Obtener Ayuda y Documentación del Sistema
- Navegando el Sistema de Archivos
- Operaciones con Archivos y Directorios
- Visualización y Edición de Archivos
- Enlaces Duros y Simbólicos
- Permisos y Propiedad de Archivos
Módulo 3: Habilidades Avanzadas en la Línea de Comandos
- El Entorno del Shell: Variables, Alias e Historial
- Uso de Comodines y Expresiones Regulares
- Búsqueda de Archivos y Contenido: find, locate y grep
- Tuberías y Redirección
- Procesamiento de Texto: cut, sort, uniq, sed y awk
- Gestión de Procesos
- Programación de Tareas con Cron
- Comandos de Redes
Módulo 4: Scripting en Shell
- Introducción al Scripting en Shell
- Variables y Tipos de Datos
- Entrada, Salida y Argumentos de un Script
- Estructuras de Control
- Funciones y Librerías
- Depuración y Manejo de Errores
- Scripts de Producción: Buenas Prácticas
Módulo 5: Administración del Sistema
- Gestión de Usuarios y Grupos
- sudo y Permisos Especiales
- Gestión de Paquetes
- Gestión de Discos
- systemd y la Gestión de Servicios
- Registros del Sistema: journald y syslog
- Monitoreo del Sistema y Optimización del Rendimiento
- Respaldo y Restauración
Módulo 6: Redes y Seguridad
- Configuración de Redes
- SSH y Acceso Remoto
- Firewall y Seguridad Perimetral
- Sistemas de Detección de Intrusos
- Gestión de Secretos y Certificados TLS
- Asegurando Sistemas Linux
Módulo 7: Temas Avanzados
- El Proceso de Arranque y la Recuperación del Sistema
- Diagnóstico Avanzado: strace, perf y eBPF
- Optimización del Kernel de Linux
- Virtualización con Linux
- Contenedores de Linux y Docker
- Automatización con Ansible
- Alta Disponibilidad y Balanceo de Carga
