Tutorial

Estrategia 3-2-1 para tu VPS con Restic y S3

Seguridad y monitorización11 min de lectura8 pasos

Activar los snapshots de tu proveedor de alojamiento no es una estrategia 3-2-1: es una sola copia, en un solo soporte, en un solo proveedor. Si la VM desaparece, tu cuenta se ve comprometida o el centro de datos sufre un incidente, tus datos desaparecen con ellos. La regla 3-2-1 aborda este riesgo: tres copias, en dos soportes distintos, una de ellas fuera del proveedor y cifrada antes de salir del servidor. Esta guía cubre la implementación completa con Restic, un timer systemd, una política de retención calibrada y una prueba de restauración automatizada que falla cuando la copia de seguridad está corrupta.

Contenido· Por qué los snapshots del proveedor no son suficientes: tres límites concretos1/8
  1. 01Por qué los snapshots del proveedor no son suficientes: tres límites concretos
  2. 02Lo que garantiza una estrategia 3-2-1 y lo que no garantiza un snapshot
  3. 03Las tres copias explicadas: local, proveedor, fuera del sitio
  4. 04Backblaze B2 vs Cloudflare R2: elegir tu backend S3
  5. 05Implementación completa: Restic + S3 en tu VPS
  6. 06Secretos de Restic: archivo .env aislado, nunca en duro en el servicio
  7. 07Resolución de problemas: cuatro errores comunes
  8. 08Plan de recuperación: ¿cuánto tiempo lleva restaurar desde B2 o R2?

Por qué los snapshots del proveedor no son suficientes: tres límites concretos

Un snapshot de alojamiento es práctico, pero comparte el mismo plano de fallo que tu VM. Primer límite: si la VM se elimina — por error, por parte del proveedor, o tras un impago — los snapshots asociados desaparecen con ella. Segundo límite: si un atacante compromete tu cuenta de alojamiento, puede eliminar snapshots y VM en segundos a través de la API o el panel de control. Tercer límite: los snapshots del centro de datos nunca prueban la restauración. Un snapshot «coherente» puede contener un sistema de archivos corrupto o una base de datos en estado inconsistente; solo lo descubrirás cuando lo necesites.

Lo que garantiza una estrategia 3-2-1 y lo que no garantiza un snapshot

  • Tres copias: la original en disco local, una en snapshots del proveedor, una fuera del proveedor en S3 — ningún punto de fallo único puede borrar todo.
  • Dos soportes distintos: el disco NVMe de tu VPS y el almacenamiento de objetos de otro proveedor están separados física y lógicamente.
  • Cifrado antes de la transferencia: Restic cifra del lado del cliente con AES-256; el proveedor de almacenamiento S3 solo ve blobs opacos, ilegibles sin tu clave.
  • Prueba de restauración: una copia de seguridad no probada es una promesa, no una garantía. Un timer systemd puede verificar automáticamente que un archivo centinela sea restaurable.
  • Independencia del proveedor: tu bucket B2 o R2 no puede eliminarse desde el panel de control de tu proveedor VPS.
  • Un snapshot de alojamiento no cifra antes de la transferencia: los datos son legibles por el proveedor.
  • Un snapshot de alojamiento nunca verifica la coherencia a nivel de aplicación de tus bases de datos.

Las tres copias explicadas: local, proveedor, fuera del sitio

La regla 3-2-1 no es una receta rígida — es un principio de diversificación de riesgos.

Copia 1 — disco local de tu VPS. Esta es tu primera línea: el original, en NVMe. Sirve para restauraciones rápidas de un archivo eliminado accidentalmente sin latencia de red.

Copia 2 — snapshots del proveedor. La copia de seguridad automática gestionada por tu proveedor VPS cubre accidentes de configuración y eliminaciones accidentales a nivel de sistema. Es tu red de seguridad en el sitio.

Copia 3 — almacenamiento de objetos fuera del sitio, cifrado con Restic. Este es el eslabón que la mayoría de los equipos olvida, y el único que sobrevive a la pérdida completa de la cuenta de alojamiento. Restic cifra los datos antes de cualquier transferencia, los deduplica para minimizar costes y los envía a un bucket compatible con S3 en un proveedor externo. Esta tercera copia es lo que construye esta guía.

Backblaze B2 vs Cloudflare R2: elegir tu backend S3

Desplace la tabla

CriterioBackblaze B2Cloudflare R2
AlmacenamientoTarifa pública por GBGratis hasta 10 GB/mes, luego tarifa pública por GB
Egress (tráfico saliente)Gratis hacia Cloudflare y socios CDN seleccionados; facturado fuera de sociosGratis sin límite — sin coste de salida
Compatibilidad S3API compatible con S3 nativa; endpoint `s3.us-west-004.backblazeb2.com`API compatible con S3 nativa; endpoint `<account>.r2.cloudflarestorage.com`
Variable `RESTIC_REPOSITORY``s3:https://s3.us-west-004.backblazeb2.com/nombre-bucket``s3:https://<account>.r2.cloudflarestorage.com/nombre-bucket`
Claves de accesoB2 Application Key (Key ID + Application Key)R2 API Token con permisos Object Read & Write
Caso de uso recomendadoAlto volumen con egress limitado o desde infraestructura CloudflareEgress frecuente o pruebas de restauración regulares desde cualquier lugar

Implementación completa: Restic + S3 en tu VPS

  1. Exportar variables de entorno a un archivo seguro

    Crea /root/.restic-env con las variables necesarias. Para Backblaze B2:

    export RESTIC_REPOSITORY="s3:https://s3.us-west-004.backblazeb2.com/tu-bucket"
    export RESTIC_PASSWORD="tu-contraseña-de-repositorio"
    export AWS_ACCESS_KEY_ID="tu-b2-key-id"
    export AWS_SECRET_ACCESS_KEY="tu-b2-application-key"

    Para Cloudflare R2, reemplaza la URL del repositorio y las claves:

    export RESTIC_REPOSITORY="s3:https://<account-id>.r2.cloudflarestorage.com/tu-bucket"
    export RESTIC_PASSWORD="tu-contraseña-de-repositorio"
    export AWS_ACCESS_KEY_ID="tu-r2-access-key-id"
    export AWS_SECRET_ACCESS_KEY="tu-r2-secret-access-key"

    Restringe inmediatamente los permisos: chmod 600 /root/.restic-env. Este archivo nunca debe ser commiteado en un repositorio Git.

  2. Inicializar el repositorio Restic en S3

    Carga el entorno, luego inicializa el repositorio cifrado en tu bucket:

    source /root/.restic-env
    restic init

    Restic crea la estructura del repositorio y sella el cifrado con tu contraseña. Guarda la contraseña del repositorio fuera del VPS: en un gestor de contraseñas o una bóveda cifrada en una máquina separada. Sin ella, ninguna restauración es posible, incluso si tienes acceso completo al bucket.

  3. Ejecutar una primera copia de seguridad hacia S3

    Prueba el camino completo con una copia manual:

    source /root/.restic-env
    restic backup /etc /var/www /opt/docker-data

    Para bases de datos, genera un dump primero o usa el modo stdin. Ejemplo para PostgreSQL:

    pg_dump -U postgres mibd | restic backup --stdin --stdin-filename mibd.sql

    Verifica que el snapshot fue creado: restic snapshots.

  4. Definir la política de retención

    El comando forget elimina referencias a snapshots antiguos; --prune libera físicamente los bloques huérfanos en el backend:

    restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 3 --prune

    Justificación de los valores. Siete diarios cubren una semana completa — suficiente para detectar una corrupción silenciosa que solo aparece días después del incidente. Cuatro semanales ofrecen una ventana de un mes para detectar un problema a nivel de aplicación. Tres mensuales permiten restaurar a un estado anterior al trimestre actual. --prune es esencial: sin él, forget marca snapshots para eliminación pero no libera espacio en el bucket.

  5. Distinguir restic check de restic check --read-data

    Estos dos comandos no verifican lo mismo.

    restic check valida los metadatos del repositorio — estructura de packs, coherencia de índices, integridad de punteros. Rápido (segundos a minutos según el tamaño del repositorio). Ejecútalo después de cada forget --prune.

    restic check

    restic check --read-data descarga y verifica cada blob de datos comparándolos con su hash criptográfico. Lento (proporcional al volumen del repositorio) y potencialmente costoso en egress. Resérvalo para una verificación mensual o tras dudas sobre la integridad del bucket.

    restic check --read-data
  6. Crear la unidad systemd de copia de seguridad (.service)

    Crea /etc/systemd/system/restic-backup.service:

    [Unit]
    Description=Restic backup a S3
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    Type=oneshot
    EnvironmentFile=/root/.restic-env
    ExecStartPre=/bin/sh -c 'curl -sf --max-time 10 https://one.one.one.one > /dev/null || exit 1'
    ExecStart=/usr/bin/restic backup /etc /var/www /opt/docker-data
    ExecStartPost=/usr/bin/restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 3 --prune
    ExecStartPost=/usr/bin/restic check
    StandardOutput=journal
    StandardError=journal

    ExecStartPre verifica la conectividad de red antes de intentar la copia — si el VPS está aislado o el bucket es inaccesible, el servicio falla de forma limpia.

  7. Crear la unidad systemd de planificación (.timer)

    Crea /etc/systemd/system/restic-backup.timer:

    [Unit]
    Description=Timer diario para restic-backup.service
    
    [Timer]
    OnCalendar=*-*-* 03:00:00
    Persistent=true
    RandomizedDelaySec=900
    
    [Install]
    WantedBy=timers.target

    Persistent=true garantiza que si el VPS está apagado a las 03:00, la copia se ejecutará en el siguiente arranque. Activa y arranca:

    systemctl daemon-reload
    systemctl enable --now restic-backup.timer

    Verifica el estado del timer: systemctl status restic-backup.timer y los logs del último run: journalctl -u restic-backup.service.

  8. Crear una prueba de restauración automatizada con archivo centinela

    Crea el archivo centinela e inclúyelo en tu copia de seguridad:

    echo "sentinel-$(date +%s)" > /opt/restic-sentinel.txt

    Crea /etc/systemd/system/restic-restore-test.service:

    [Unit]
    Description=Prueba de restauración Restic
    After=network-online.target
    
    [Service]
    Type=oneshot
    EnvironmentFile=/root/.restic-env
    ExecStart=/bin/sh -c '
      rm -rf /tmp/restic-test-restore && \
      restic restore latest --target /tmp/restic-test-restore && \
      test -f /tmp/restic-test-restore/opt/restic-sentinel.txt && \
      echo "Restauración OK" || \
      (echo "FALLO restauración centinela" && exit 1)
    '
    StandardOutput=journal
    StandardError=journal

    Crea el timer semanal /etc/systemd/system/restic-restore-test.timer:

    [Unit]
    Description=Prueba semanal de restauración Restic
    
    [Timer]
    OnCalendar=Sun 04:00:00
    Persistent=true
    
    [Install]
    WantedBy=timers.target

    Activa: systemctl enable --now restic-restore-test.timer.

Secretos de Restic: archivo .env aislado, nunca en duro en el servicio

Nunca coloques RESTIC_PASSWORD, AWS_ACCESS_KEY_ID o AWS_SECRET_ACCESS_KEY directamente en una definición de unidad systemd, un script versionado o un Dockerfile. El archivo /root/.restic-env con chmod 600 es la práctica correcta: se carga mediante EnvironmentFile= sin aparecer nunca en systemctl show ni en los logs. Añade /root/.restic-env a tu .gitignore o .dockerignore si tu directorio /root está versionado. Para entornos multiusuario, prefiere un gestor de secretos o las credenciales systemd (LoadCredential=) frente a un archivo plano.

Resolución de problemas: cuatro errores comunes

Fatal: unable to open config file en restic init o el primer restic backup. Restic no puede acceder al bucket. Verifica que las variables están cargadas (echo $RESTIC_REPOSITORY) y que las credenciales son correctas. Verifica los permisos IAM de tu clave B2 o R2: necesita al menos derechos de lectura, escritura y listado en el bucket.

Bucket S3: permisos insuficientes. Si restic init tiene éxito pero restic backup falla con un error de autorización, una política de bucket está anulando los permisos de la clave. En B2, verifica que no haya ninguna regla denyUpload activa. En R2, verifica que el bucket no esté en modo público con restricciones de escritura.

Timer systemd que no se activa. Diagnostica con tres comandos: systemctl status restic-backup.timer, systemctl list-timers --all | grep restic, journalctl -u restic-backup.service --since today. Si el timer está activo pero el servicio no ha corrido, verifica que OnCalendar sea sintácticamente válido: systemd-analyze calendar '*-*-* 03:00:00' debe devolver una fecha de próximo disparo.

restic check --read-data demasiado lento. En un repositorio de decenas de GB, --read-data puede tardar horas y generar costes significativos de egress en B2. Usa --read-data-subset=10% para verificar una muestra aleatoria en cada ejecución semanal, y reserva la verificación completa para un mantenimiento mensual planificado.

Plan de recuperación: ¿cuánto tiempo lleva restaurar desde B2 o R2?

El tiempo de restauración depende de tres factores: el volumen de datos, el ancho de banda disponible entre tu VPS y el bucket, y los posibles costes de egress.

Como estimación: un repositorio Restic de 20 GB en B2 (datos ya deduplicados y comprimidos) se restaura en unos 15 a 30 minutos con una conexión de centro de datos estándar a 1 Gbps. En R2, el egress es gratuito — no hay presión financiera para escalonar la restauración.

Dos prácticas reducen el tiempo de recuperación: primero, mantener una lista de tus directorios críticos separada de los directorios de caché o logs — un repositorio más pequeño se restaura más rápido. Segundo, probar periódicamente la restauración parcial de un solo directorio (restic restore latest --target /tmp/test --include /etc) para calibrar la duración real en tu infraestructura. El comando restic stats muestra el tamaño del repositorio para la planificación.

Un VPS diseñado para estrategias de copia de seguridad serias

Acceso root, almacenamiento local, snapshots automáticos y ancho de banda saliente incluido: un VPS ServOrbit es el punto de partida de cualquier estrategia 3-2-1.

¿Necesita ayuda?

Consulte nuestro centro de ayuda y nuestra FAQ, o contacte con nuestro equipo: llamada, WhatsApp o correo electrónico. Soporte en francés, inglés y árabe.

Escribir por WhatsAppse abre en una pestaña nueva