Backups con restic: sencillo, cifrado y automatizado
Los backups son como las copias de seguridad dentales: todo el mundo sabe que debería hacerlos con frecuencia, casi nadie los hace bien, y cuando los necesitas, el que no los tiene paga carísimo. He tenido suficientes sustos en veinte años como para haber convertido los backups en una parte no negociable de cualquier servidor que me importe. Y desde hace cuatro años, mi herramienta para todo es restic. Este post cuenta por qué y cómo la uso.
Qué es restic

Restic es un programa de backups escrito en Go, de código abierto, que hace cuatro cosas fundamentales bien:
-
Snapshots incrementales con deduplicación. Cada backup guarda solo lo que ha cambiado desde el anterior. Si un fichero no cambia, no ocupa espacio adicional. Si dos ficheros son idénticos (en distintas carpetas o en distintos días), se guarda solo una copia.
-
Cifrado de extremo a extremo. Los datos se cifran antes de salir de tu máquina. El repositorio puede vivir en un servicio público (S3, Backblaze B2, Google Drive) y el proveedor no puede ver nada de tu contenido.
-
Restauración granular. Puedes restaurar un fichero concreto de un snapshot concreto sin restaurar todo. Muy útil cuando lo que necesitas es solo una carpeta.
-
Multiplataforma. Funciona igual en Linux, macOS y Windows. Los repositorios son portátiles entre sistemas.
Restic no es la única herramienta que hace esto (están borg, duplicity, kopia). Elegí restic por la simplicidad de la interfaz y por el soporte de backends (S3, B2, SFTP, local, y más). Pero cualquiera de las tres es decente.
El modelo conceptual
Entender restic es entender tres cosas:
Repositorio: el sitio donde guardas los backups. Puede ser un directorio local, un SFTP, un bucket S3, un Backblaze B2. Está cifrado con una contraseña que solo tú conoces.
Snapshot: una foto del estado de los ficheros en un momento dado. Cada restic backup crea un snapshot nuevo.
Política de retención: cuántos snapshots guardas y cuáles tiras. Esto se hace con restic forget y restic prune.
Con estos tres conceptos ya puedes usar el 95% de restic.
Instalación

En Debian/Ubuntu moderno, restic está en los repositorios:
sudo apt install restic
Si la versión del repo es vieja (revisa con restic version), descarga el binario directamente:
wget https://github.com/restic/restic/releases/download/v0.17.0/restic_0.17.0_linux_amd64.bz2
bunzip2 restic_0.17.0_linux_amd64.bz2
sudo mv restic_0.17.0_linux_amd64 /usr/local/bin/restic
sudo chmod +x /usr/local/bin/restic
Con eso ya tienes restic funcionando.
Inicialización del repositorio
Lo primero es crear un repositorio. En mi caso uso Backblaze B2 porque es barato (seis dólares al mes por un terabyte), con amplia disponibilidad y con soporte nativo en restic.
export RESTIC_REPOSITORY="b2:mi-bucket:backups/servidor"
export B2_ACCOUNT_ID="xxxxxxxx"
export B2_ACCOUNT_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxx"
export RESTIC_PASSWORD="una-contraseña-fuerte-y-larga"
restic init
Guarda la RESTIC_PASSWORD en un sitio seguro (password manager, papel en caja fuerte). Si la pierdes, los backups son inútiles: no hay backdoor. Esto es una feature, no un bug, pero exige disciplina.
Para un repositorio local:
export RESTIC_REPOSITORY="/mnt/backup-drive/restic"
export RESTIC_PASSWORD="contraseña"
restic init
Para SFTP a otro servidor:
export RESTIC_REPOSITORY="sftp:[email protected]:/backups/restic"
export RESTIC_PASSWORD="contraseña"
restic init
El primer backup

La sintaxis básica:
restic backup /home /etc /var/www
En mi servidor principal el comando es:
restic backup \
--exclude-file=/etc/restic/excludes.txt \
--tag nightly \
/home /etc /var/www /opt/app
--exclude-file apunta a una lista de patrones a ignorar. Mi fichero típico:
node_modules
*.log
*.tmp
/var/cache
__pycache__
.git
.DS_Store
--tag le pone una etiqueta al snapshot para poder filtrar después.
La primera ejecución tarda (sube todos los datos). Las siguientes son rápidas porque solo suben lo que cambió.
Automatización con systemd
Un cron funciona, pero prefiero systemd timers por tres razones: logs integrados, Persistent=true (si el servidor estaba apagado, ejecuta al encender) y no tengo que lidiar con rutas absolutas y variables de entorno.
El unit file (/etc/systemd/system/restic-backup.service):
[Unit]
Description=Backup con restic
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
EnvironmentFile=/etc/restic/env
ExecStart=/usr/local/bin/restic backup \
--exclude-file=/etc/restic/excludes.txt \
--tag nightly \
/home /etc /var/www /opt/app
ExecStartPost=/usr/local/bin/restic forget --prune \
--keep-daily 7 --keep-weekly 4 --keep-monthly 12
El timer (/etc/systemd/system/restic-backup.timer):
[Unit]
Description=Backup nocturno con restic
[Timer]
OnCalendar=*-*-* 03:30:00
Persistent=true
[Install]
WantedBy=timers.target
El fichero de entorno (/etc/restic/env, modo 600, propietario root):
RESTIC_REPOSITORY=b2:mi-bucket:backups/servidor
B2_ACCOUNT_ID=xxxxxxxx
B2_ACCOUNT_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxx
RESTIC_PASSWORD=contraseña-fuerte
Activar:
sudo systemctl enable --now restic-backup.timer
sudo systemctl list-timers restic-backup.timer
Política de retención
El ExecStartPost de arriba tiene la política que uso:
--keep-daily 7: los últimos 7 backups diarios.--keep-weekly 4: los últimos 4 backups semanales.--keep-monthly 12: los últimos 12 backups mensuales.
Con esta política siempre tengo: la última semana día a día, el último mes semana a semana, y el último año mes a mes. Es suficiente para la mayoría de casos. Si necesito más granularidad en ciertas fechas (por ejemplo, guardar un backup antes de una migración), creo un snapshot manual con --tag manual y luego uso --keep-tag manual en la política para que nunca se borre.
El --prune al final recupera el espacio físico de los snapshots eliminados. Si no lo pones, los snapshots se marcan como eliminados pero el espacio no se libera.
Cómo restauro
La operación que justifica todo el sistema. Primero listo snapshots:
restic snapshots
Output:
ID Time Host Tags Paths
----------------------------------------------------------------
abcd1234 2026-04-01 03:30:00 servidor nightly /home /etc
efgh5678 2026-04-02 03:30:00 servidor nightly /home /etc
ijkl9012 2026-04-03 03:30:00 servidor nightly /home /etc
Para restaurar un snapshot completo a un directorio:
restic restore abcd1234 --target /tmp/restore
Para restaurar solo un fichero o carpeta:
restic restore abcd1234 --target /tmp/restore --include /home/javier/proyectos
Para montar un snapshot como filesystem y navegarlo (muy útil):
mkdir /mnt/restic
restic mount /mnt/restic
Y ahora /mnt/restic/snapshots/ tiene todos los snapshots accesibles como carpetas. Puedes hacer cp, diff, lo que sea. Cuando terminas, Ctrl+C para desmontar.
Verificación
Un backup que no has verificado es un backup que quizás no funciona. Yo ejecuto restic check mensualmente:
restic check --read-data-subset=10%
--read-data-subset=10% lee el 10% de los datos reales y verifica que no hay corrupción. Hacer el check completo sobre un terabyte es carísimo (tienes que descargarlo todo); la muestra estadística del 10% da una señal fiable con coste razonable.
Además, cada seis meses hago una restauración de prueba: bajo un snapshot a una máquina de pruebas y verifico que el contenido es usable. Si los ficheros están cifrados o corruptos, quiero saberlo con seis meses de margen, no el día que lo necesito de verdad.
Costes reales
En mi caso concreto, servidor con unos 80 GB de datos reales:
- Backblaze B2: $0.48/mes en almacenamiento, prácticamente cero en bandwidth (los uploads son gratis, los downloads son $0.01/GB pero raramente descargo nada).
- Tiempo de backup diario: unos 3 minutos.
- Tiempo de restore completo (si alguna vez hiciera falta): alrededor de dos horas.
Total: menos de seis euros al año por tener todo mi trabajo protegido. Es uno de los mejores ratios coste/valor que conozco en infraestructura.
Errores comunes
Cosas que he visto fallar en setups de backup:
No cifrar los backups. Los backups son un objetivo jugoso para un atacante: tienen toda tu información ordenada. Sin cifrado, expones todo. Restic cifra por defecto; no lo desactives.
No probar las restauraciones. Muchos sistemas tienen backups que nadie ha restaurado nunca. La primera restauración no puede ser el día del desastre. Haz una de prueba cada seis meses.
Ubicar el backup en la misma infraestructura. Un snapshot de LVM no es un backup. Un backup en el mismo datacenter no es un backup. El backup tiene que vivir físicamente lejos de los datos originales.
No versionar la configuración del backup. El unit file, los excludes, el script de restauración… todo eso tiene que estar en un sitio versionado y accesible. Si tu máquina arde entera, el backup es inútil si no recuerdas cómo se configuraba.
Olvidarse de la contraseña. El cifrado sin recuperación es un arma de doble filo. La contraseña en un gestor de contraseñas, y el gestor con su propia recuperación. Sin esto, un incidente grave puede dejarte sin acceso a tus propios backups.
Cuándo restic no es la respuesta
Restic es excelente para backup de ficheros en servidores y máquinas personales. Pero tiene escenarios donde no encaja:
- Backup de bases de datos en caliente: restic hace snapshot a nivel de filesystem; para una base de datos en uso, mejor hacer
pg_dumpomysqldumpprimero y después hacer backup del dump. - Réplica en tiempo real: restic es snapshots periódicos, no replicación continua. Si necesitas pérdida de datos cero, necesitas replicación (PostgreSQL streaming, rsync con inotify).
- Archivado legal con retención larga: restic guarda snapshots, pero si tienes requisitos legales específicos (GDPR, HIPAA), valida que la retención cumple los requisitos antes de producción.
La conclusión
Montar restic en una tarde y saber que los datos de tu servidor están a salvo es uno de esos cambios pequeños con impacto desproporcionado. La diferencia entre "sé que tengo backup" y "creo que tengo backup" es la diferencia entre dormir tranquilo y no dormir el día que algo se jode. Seis euros al año por esa tranquilidad es un lujo.