Como hacer backups con restic en un VPS
Configura restic en Ubuntu 24.04 para enviar snapshots cifrados a un repositorio externo vía SFTP o S3 usando systemd timers para automatizar el proceso.
Por qué un backup en el mismo servidor no es un backup
Restic es una herramienta de backup de código abierto que envía snapshots cifrados y deduplicados de sus archivos a un repositorio externo: un segundo VPS, una máquina local o un almacenamiento de objetos compatible con S3. Esta guía lo configura en Ubuntu 24.04, desde la instalación hasta un repositorio vía SFTP, un primer backup, un timer de systemd nocturno, una política de retención y la prueba de restauración para verificar el funcionamiento. El destino debe ser otra máquina, porque una copia en el mismo servidor se pierde si el servidor falla.
Un directorio backup/ en el mismo equipo que se respalda solo protege contra un escenario: borrar un archivo por accidente. No sobrevive a un fallo de disco, porque reside en ese disco. No sobrevive a un atacante con privilegios root, ya que borrará las copias primero. No sobrevive a un error de cuenta que elimine el VPS. El centro de datos menos eficiente del mundo bromea sobre un archivo tar llamado backup_final_v2_REAL ubicado en el mismo array que los datos; la broma es real porque muchos hemos cometido ese error. La regla es usar un equipo externo, y restic es la forma más sencilla de cumplirla.
Restic en cuatro conceptos
Repository. El lugar donde restic escribe los datos. Es un directorio con el formato propio de restic, lleno de blobs cifrados, y solo restic puede leerlo. Nunca debe editarlo manualmente; se interactúa con él mediante comandos de restic y la dirección -r.
Snapshot. Una captura de los archivos en un momento específico. Cada ejecución de backup crea un snapshot; cada snapshot puede restaurarse de forma independiente y cada uno funciona como una copia completa de sus datos en ese instante.
Deduplication. Restic divide los archivos en fragmentos definidos por contenido y sube únicamente los fragmentos que el repositorio no tiene. El primer backup sube todo; cada ejecución posterior sube aproximadamente solo lo que ha cambiado. Un snapshot nocturno de 20 GB donde han cambiado 50 MB consume unos 50 MB, por lo que mantener decenas de snapshots es económico.
Encryption by default. Un repositorio de restic siempre está cifrado (AES-256) y cada comando requiere la contraseña del repositorio. El host de backup o el proveedor de almacenamiento solo ven blobs cifrados. La consecuencia directa: si pierde la contraseña, los datos se pierden de forma permanente por diseño. Guarde una copia de la contraseña en un lugar distinto a este servidor. Este punto es tan importante que se menciona dos veces más a continuación.
Instalar restic en Ubuntu 24.04
sudo apt update && sudo apt install -y restic
restic versionEn Ubuntu 24.04 se instala restic 0.16.4, mientras que la versión actual de upstream es 0.19.1. La diferencia existe porque una versión LTS (long term support) congela las versiones de sus paquetes; esto no afecta el proceso, ya que la versión 0.16.4 permite realizar todas las tareas de esta guía. Si requiere la versión más reciente por sus mejoras de rendimiento, descargue el binario oficial desde la página de releases de GitHub del proyecto restic, descomprímalo con bunzip2 e instálelo en /usr/local/bin/restic; la instalación de restic no requiere pasos adicionales.
Crear el repositorio en otro servidor mediante SFTP
Necesitas una máquina de destino: un segundo VPS pequeño es la opción habitual, pero cualquier equipo con un servidor SSH y espacio en disco es suficiente. Restic utiliza SFTP (transferencia de archivos sobre SSH), por lo que el host de backup no requiere ninguna instalación adicional. En esta guía, el host de backup es 10.0.0.12 con un usuario llamado restic. No nombres a ese usuario backup: Ubuntu y Debian incluyen una cuenta de sistema reservada llamada backup (uid 34, sin shell de inicio de sesión) en cada instalación, por lo que adduser backup fallará y ssh backup@... se guardará en nologin.
El proceso nocturno se ejecutará como root en el servidor que se respalda, por lo que root necesita acceso mediante llave al host de backup. Crea una llave dedicada sin frase de paso (passphrase), ya que no habrá una persona disponible a las 3am para escribirla, y cópiala:
sudo ssh-keygen -t ed25519 -f /root/.ssh/id_ed25519 -N "" -C "web1-restic"
sudo ssh-copy-id -i /root/.ssh/id_ed25519.pub restic@10.0.0.12
sudo ssh restic@10.0.0.12 true && echo key login worksSi no tienes experiencia con llaves, conceptos básicos de gestión de llaves SSH explica el modelo, los permisos y cómo revocar una llave posteriormente.
A continuación, la contraseña del repositorio. Genera una contraseña robusta en un archivo accesible solo por root:
openssl rand -base64 32 | sudo tee /root/.restic-password
sudo chmod 600 /root/.restic-passwordCopia esa contraseña en tu gestor de contraseñas antes de continuar. Si este VPS falla, el repositorio junto con esta contraseña permite restaurar todo; el repositorio sin la contraseña no permite restaurar nada.
Inicializa el repositorio:
sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password initcreated restic repository 9f3c2a1b0d at sftp:restic@10.0.0.12:/srv/restic/web1La alternativa de destino es el almacenamiento de objetos compatible con S3, que es la opción adecuada si no quieres gestionar una segunda máquina. Cualquier bucket compatible con S3 funciona de la misma manera; solo cambian la dirección y dos variables de credenciales:
export AWS_ACCESS_KEY_ID=your-key-id
export AWS_SECRET_ACCESS_KEY=your-secret-key
sudo -E restic -r s3:https://s3.example.com/web1-backups --password-file /root/.restic-password initTodo lo que sigue a init es idéntico para ambos destinos. El resto de esta guía muestra la dirección SFTP; sustitúyela por la tuya.
La primera copia de seguridad, con exclusiones
Realice la copia de seguridad de los datos que no puede reinstalar, no de todo el filesystem. El sistema operativo se recupera mediante una reinstalación; su configuración y sus datos no. Para un VPS típico, esto significa /etc, /home, y cualquier directorio donde sus aplicaciones guarden su estado, como /srv o /var/www. Excluya los caches, ya que son grandes, cambian cada día y se reconstruyen solos:
sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password backup /etc /home /srv --exclude '/home/*/.cache'Files: 4181 new, 0 changed, 0 unmodified
Added to the repository: 731.204 MiB (312.418 MiB stored)
snapshot 5b8a3f2c savedLa primera ejecución sube todo el contenido, por lo que tarda un tiempo. Ejecute el mismo comando nuevamente y finalizará en segundos, reportando pocos archivos cambiados y pocos MiB añadidos, debido a que la deduplicación solo sube los chunks nuevos. Liste su contenido:
sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password snapshotsCada snapshot muestra un ID, una hora y las rutas que contiene. Esos IDs son los que se utilizan para la restauración.
Ejecuciones nocturnas con un timer de systemd
Escribir la dirección del repositorio en cada comando es tedioso, y un backup manual suele olvidarse en menos de un mes. Ambos problemas se resuelven con un script y un timer. El script define las dos variables de entorno que lee restic, RESTIC_REPOSITORY y RESTIC_PASSWORD_FILE, para que cada comando interno sea breve:
sudo nano /usr/local/bin/restic-backup.sh#!/usr/bin/env bash
set -euo pipefail
export RESTIC_REPOSITORY='sftp:restic@10.0.0.12:/srv/restic/web1'
export RESTIC_PASSWORD_FILE=/root/.restic-password
restic backup /etc /home /srv --exclude '/home/*/.cache'
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
restic checksudo chmod 700 /usr/local/bin/restic-backup.shLas líneas forget y check se explican en las siguientes dos secciones. Sobre la programación: un servicio oneshot que ejecuta el script y un timer que lo activa a las 03:00 cada noche. Un timer es preferible a una línea de cron en este caso porque los logs se guardan en el journal, y Persistent=true ejecuta un backup pendiente en cuanto el servidor se reinicia tras un tiempo de inactividad.
# /etc/systemd/system/restic-backup.service
[Unit]
Description=Nightly restic backup
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/restic-backup.sh# /etc/systemd/system/restic-backup.timer
[Unit]
Description=Run the nightly restic backup
[Timer]
OnCalendar=*-*-* 03:00:00
RandomizedDelaySec=15m
Persistent=true
[Install]
WantedBy=timers.targetHabilita el timer, ejecuta el servicio manualmente una vez y verifica su funcionamiento:
sudo systemctl daemon-reload
sudo systemctl enable --now restic-backup.timer
sudo systemctl start restic-backup.service
sudo journalctl -u restic-backup.service -fsystemctl list-timers muestra cuándo será la próxima ejecución. También puedes generar el par de archivos unit en lugar de escribirlos manualmente:
El patrón completo de estos dos archivos, incluyendo la sintaxis de calendario y las directivas de hardening para un servicio, se encuentra en ejecutar un programa como un servicio de systemd en un VPS.
Una copia de seguridad es solo un rumor hasta que se restaura
Considere esa frase como una regla fundamental. Un trabajo de backup que finaliza correctamente cada noche solo demuestra que el proceso se ejecutó; no garantiza que los datos se puedan recuperar. Dos comprobaciones eliminan esa incertidumbre.
Primero, restic check, que el script ya ejecuta cada noche. Este verifica la estructura del repositorio y el índice, permitiendo detectar la corrupción silenciosa en el host de backup durante la siguiente ejecución en lugar de en el momento de la restauración. Una vez al mes, ejecute la versión profunda, que descarga y verifica criptográficamente una décima parte aleatoria de los datos reales:
sudo -i
export RESTIC_REPOSITORY='sftp:restic@10.0.0.12:/srv/restic/web1'
export RESTIC_PASSWORD_FILE=/root/.restic-password
restic check --read-data-subset=10%Debido a que el subconjunto es aleatorio en cada ejecución, los procesos mensuales recorren todo el repositorio sin necesidad de realizar una descarga completa.
Segundo, el simulacro de restauración. Desde la shell de root mencionada anteriormente, restaure un directorio real desde el último snapshot a una ubicación temporal y compárelo con los archivos en vivo:
restic restore latest --target /srv/restore-drill --include /etc/ssh
diff -r /etc/ssh /srv/restore-drill/etc/sshSi diff no muestra salida, significa que cada byte se recuperó de forma idéntica, que es la única evidencia válida. Elimine /srv/restore-drill después de finalizar. Realice este simulacro mensualmente y, una o dos veces al año, realice la versión completa: restaure el snapshot completo en un VPS temporal y verifique que su aplicación se inicia correctamente desde él. El día que necesite que esto funcione bajo presión, debe ser una rutina que ya haya ejecutado.
Retención: forget y prune
Sin una política, los snapshots se acumulan indefinidamente y el repositorio solo crece. La línea forget del script aplica una política cada noche: --keep-daily 7 mantiene un snapshot por día durante los últimos siete días, --keep-weekly 4 uno por semana durante cuatro semanas, y --keep-monthly 6 uno por mes durante seis meses. Todo lo que no esté protegido por una regla se elimina.
forget por sí solo solo elimina los registros de los snapshots; los chunks de datos permanecen en el repositorio hasta que algo los borre. Eso es lo que hace --prune: busca chunks sin referencias de snapshots restantes y los elimina, que es cuando se recupera el espacio en disco. Prune realiza el trabajo real en el repositorio, por lo que en repositorios grandes algunos usuarios ejecutan forget cada noche y --prune cada semana; para tamaños típicos de VPS, la ejecución nocturna es suficiente.
Bases de datos: realizar el volcado primero y luego respaldar el volcado
Restic copia los archivos mientras los lee, mientras que una base de datos escribe en sus archivos de forma continua. Un archivo de base de datos capturado durante una escritura se restaurará como una base de datos corrupta, porque la copia mezcla páginas de antes y después de la escritura. La solución es estándar: hacer que el motor de la base de datos genere un exportación consistente en un archivo y luego dejar que restic respalde ese archivo.
Para PostgreSQL, añada una línea de volcado (dump) al principio de restic-backup.sh, antes del comando restic backup, e incluya el directorio del volcado en las rutas de respaldo:
mkdir -p /var/backups/db
sudo -u postgres pg_dump myapp | gzip > /var/backups/db/myapp.sql.gzmysqldump cumple la misma función para MariaDB y MySQL. Para un ejemplo práctico de todo el patrón, la sección de respaldo de Nextcloud activa el modo de mantenimiento, realiza el volcado de Postgres y copia los archivos como un conjunto consistente, exactamente el conjunto que restic debe extraer del equipo cada noche. SQLite sigue la misma lógica con un método más simple: la guía de Vaultwarden detiene el contenedor durante unos segundos para realizar una copia en frío de db.sqlite3, y ese archivo es lo que restic envía fuera del servidor.
FAQ
¿Están cifrados los backups de restic?
Sí, siempre. Cada repositorio de restic está cifrado con AES-256. No existe un modo sin cifrar y cada comando requiere la contraseña del repositorio. El equipo o proveedor que almacena el repositorio solo contiene blobs cifrados; por lo tanto, un host de backup comprometido no expone sus archivos. El compromiso es total: sin la contraseña nadie puede recuperar los datos, así que guarde una copia lejos del servidor.
¿Realiza restic backups incrementales?
Cada snapshot de restic funciona como un backup completo, pero consume almacenamiento incremental. Restic divide los archivos en chunks y sube solo los chunks que el repositorio no tiene almacenados; así, una ejecución nocturna transfiere aproximadamente lo que cambió ese día. A diferencia de los esquemas incrementales tradicionales, no hay una cadena que reproducir: cualquier snapshot restaura directamente y borrar un snapshot antiguo nunca rompe uno más reciente.
¿Cómo restauro archivos de un backup de restic?
Ejecute restic snapshots para encontrar el ID del snapshot, luego restic restore <id> --target /some/empty/dir para restaurarlo, añadiendo --include /path para restaurar solo una parte. latest funciona en lugar de un ID. Restic recrea la estructura de directorios original bajo el destino, por lo que restaurar /etc/ssh termina en /some/empty/dir/etc/ssh. Practique esto antes de necesitarlo, porque un backup no probado es solo un rumor.
¿Con qué frecuencia debo ejecutar restic backup?
Una ejecución nocturna es el mínimo razonable para un servidor, y la deduplicación lo hace económico: cada ejecución sube solo los chunks que cambiaron desde la última. Los datos que cambian rápido, o cuya pérdida de un solo día sea crítica, pueden ejecutarse cada pocas horas con el mismo patrón de temporizador. La frecuencia es la parte sencilla; ejecute también restic check regularmente y realice un simulacro de restauración mensualmente, porque un cronograma sin verificación es una falsa seguridad.
¿Qué sucede si pierdo mi contraseña del repositorio de restic?
Los backups son irrecuperables. El cifrado de restic no tiene puerta trasera ni opción de restablecimiento, por lo que la contraseña es tan importante como los backups mismos. Guarde una copia en su gestor de contraseñas y en cualquier otro lugar duradero que no sea el servidor respaldado. Mientras mantenga el acceso, restic key add puede registrar una segunda contraseña para el mismo repositorio, lo que le proporciona un respaldo.