--- title: "Copias cifradas con BorgBackup en Ubuntu 24.04" description: "Configura BorgBackup en Ubuntu 24.04 para hacer copias cifradas y deduplicadas en un servidor remoto por SSH, automatizarlas con systemd y restaurar archivos." category: "Recuperación de copias" language: es source: https://cubepath.com/es/docs/recuperación-de-copias/respaldo-con-borgbackup-deduplicacion updated: 2026-09-25 --- # Copias cifradas con BorgBackup en Ubuntu 24.04 BorgBackup (Borg) es una herramienta de copias de seguridad que divide los archivos en fragmentos, guarda cada fragmento una sola vez (deduplicación), los comprime y los cifra antes de enviarlos al repositorio. Así, copiar un servidor cada día apenas ocupa algo más que los cambios de ese día, y el servidor de copias no puede leer los datos. En este tutorial configurarás Borg en Ubuntu 24.04 para enviar copias cifradas a un servidor remoto por SSH, las automatizarás con un timer de systemd, aplicarás una política de retención y restaurarás archivos. ## Requisitos previos Para seguir esta guía necesitas: - Dos servidores con Ubuntu 24.04 LTS, por ejemplo dos VPS de CubePath: - El **servidor a respaldar** (en esta guía, `web01`). - El **servidor de copias**, con espacio suficiente para el repositorio. Idealmente en otra ubicación o centro de datos. - Un usuario no root con privilegios `sudo` en ambos. - Conectividad SSH desde el servidor a respaldar hacia el servidor de copias. En los ejemplos, `backup_server_ip` es la IP del servidor de copias. ## Cómo organiza Borg las copias Conviene tener claros tres conceptos antes de empezar: - **Repositorio**: el directorio que contiene todos los datos deduplicados y cifrados. Normalmente se usa un repositorio por servidor respaldado. - **Archivo** (archive): cada copia que haces con `borg create`. Tiene un nombre, por ejemplo `web01-2026-09-25T02:00`, y contiene la vista completa de los directorios copiados en ese momento. - **Clave y frase de paso**: con el modo `repokey`, la clave de cifrado se guarda dentro del repositorio, protegida por una frase de paso. Necesitas ambas para restaurar. Si pierdes la frase de paso, los datos son irrecuperables. ## Paso 1: Instalar BorgBackup en ambos servidores Borg debe estar instalado en los dos servidores, porque en el servidor de copias se ejecuta `borg serve` para recibir los datos. Ejecuta en ambos: ```bash sudo apt update sudo apt install borgbackup ``` Comprueba la versión: ```bash borg --version ``` ```output borg 1.2.8 ``` Usa la misma versión principal (1.2.x) en ambos servidores. Los comandos de esta guía son para Borg 1.2. ## Paso 2: Preparar el servidor de copias En el servidor de copias, crea un usuario de sistema `borg` sin contraseña, que solo servirá para recibir copias, y el directorio de los repositorios: ```bash sudo adduser --system --group --shell /bin/bash --home /srv/borg borg sudo install -d -m 700 -o borg -g borg /srv/borg/.ssh ``` Comprueba que el directorio pertenece al nuevo usuario: ```bash ls -ld /srv/borg /srv/borg/.ssh ``` En ambas líneas deben aparecer `borg borg` como propietario y grupo, y `drwx------` en `.ssh`. ## Paso 3: Crear la clave SSH del servidor a respaldar Las copias se ejecutan como root en `web01`, porque hay que leer archivos como `/etc` o los directorios de todos los usuarios. En `web01`, crea una clave SSH para root sin frase de paso, para que el timer pueda usarla sin intervención: ```bash sudo ssh-keygen -t ed25519 -f /root/.ssh/borg_ed25519 -N '' -C 'borg-web01' sudo cat /root/.ssh/borg_ed25519.pub ``` Copia la línea que empieza por `ssh-ed25519`. En el servidor de copias, añade esa clave a `authorized_keys` del usuario `borg`, pero restringida: con la opción `command`, esa clave solo puede ejecutar `borg serve` y solo sobre su propio repositorio. Aunque alguien robe la clave de `web01`, no obtendrá una shell ni podrá tocar los repositorios de otros servidores: ```bash sudo nano /srv/borg/.ssh/authorized_keys ``` ```text command="borg serve --restrict-to-path /srv/borg/web01",restrict ssh-ed25519 AAAAC3Nza... borg-web01 ``` Ajusta los permisos del archivo: ```bash sudo chown borg:borg /srv/borg/.ssh/authorized_keys sudo chmod 600 /srv/borg/.ssh/authorized_keys ``` Si el servidor de copias tiene UFW activo, asegúrate de que el puerto SSH está permitido (`sudo ufw allow OpenSSH`). ## Paso 4: Inicializar el repositorio cifrado El resto de pasos se ejecutan en `web01` como root. Abre una shell de root: ```bash sudo -i ``` Genera una frase de paso aleatoria y guárdala en un archivo que solo root pueda leer: ```bash install -m 600 /dev/null /root/.borg-passphrase openssl rand -base64 32 > /root/.borg-passphrase ``` Define las variables que Borg lee del entorno: la URL del repositorio, cómo obtener la frase de paso y qué clave SSH usar: ```bash export BORG_REPO='ssh://borg@backup_server_ip/srv/borg/web01' export BORG_PASSCOMMAND='cat /root/.borg-passphrase' export BORG_RSH='ssh -i /root/.ssh/borg_ed25519' ``` Inicializa el repositorio con cifrado `repokey-blake2` (autenticado con BLAKE2b, más rápido que SHA-256 en la mayoría de CPU sin aceleración específica): ```bash borg init --encryption=repokey-blake2 ``` La primera vez SSH te pedirá aceptar la huella del servidor de copias. Borg muestra después un aviso como este: ```output IMPORTANT: you will need both KEY AND PASSPHRASE to access this repo! ... ``` Comprueba que el repositorio responde: ```bash borg info ``` ```output Repository ID: 5c1e0f... Location: ssh://borg@backup_server_ip/srv/borg/web01 Encrypted: Yes (repokey BLAKE2b) ... ``` ## Paso 5: Exportar la clave y guardar la frase de paso Aunque la clave está dentro del repositorio, si este se corrompe perderías el acceso a todos los datos. Exporta una copia de la clave: ```bash borg key export "$BORG_REPO" /root/borg-web01.key ``` Guarda **fuera de ambos servidores** el archivo `/root/borg-web01.key` y el contenido de `/root/.borg-passphrase`, por ejemplo en tu gestor de contraseñas. Si `web01` se pierde por completo, son lo único que necesitarás, junto con el repositorio, para restaurar. > Advertencia: sin la frase de paso no hay forma de descifrar las copias. No continúes hasta haberla guardado en un lugar seguro. ## Paso 6: Hacer la primera copia Crea un archivo con los directorios importantes. `{hostname}` y `{now}` son marcadores que Borg sustituye por el nombre del host y la fecha; el `::` indica que el repositorio se toma de `BORG_REPO`: ```bash borg create --stats --compression zstd,6 --exclude-caches \ --exclude '/home/*/.cache' \ --exclude '/var/tmp/*' \ ::'{hostname}-{now:%Y-%m-%dT%H:%M}' \ /etc /home /root /var/www ``` Qué hacen las opciones: - `--compression zstd,6` comprime con zstd, un buen equilibrio entre velocidad y tamaño. - `--exclude-caches` omite los directorios marcados con un archivo `CACHEDIR.TAG`. - `--exclude` omite rutas con patrones de tipo shell. Al terminar, `--stats` muestra un resumen: ```output Archive name: web01-2026-09-25T10:31 Number of files: 18342 Original size Compressed size Deduplicated size This archive: 1.92 GB 842.13 MB 801.77 MB All archives: 1.92 GB 842.13 MB 801.77 MB ``` Ejecuta el mismo comando otra vez y observa la columna `Deduplicated size` de `This archive`: al no haber cambios, será de unos pocos kilobytes. Esa es la cantidad de espacio nuevo que ocupa cada copia. Lista los archivos del repositorio: ```bash borg list ``` ```output web01-2026-09-25T10:31 Thu, 2026-09-25 10:31:02 [3b0c...] web01-2026-09-25T10:36 Thu, 2026-09-25 10:36:44 [9e41...] ``` > Consejo: no copies los archivos de datos de MySQL o PostgreSQL en caliente. Genera antes un volcado con `mysqldump` o `pg_dump` en un directorio incluido en la copia. ## Paso 7: Automatizar las copias con un script y systemd Crea un script que haga la copia, aplique la retención y libere espacio. Sal de la shell de root con `exit` y crea el archivo: ```bash sudo nano /usr/local/sbin/borg-backup.sh ``` ```bash #!/usr/bin/env bash set -uo pipefail export BORG_REPO='ssh://borg@backup_server_ip/srv/borg/web01' export BORG_PASSCOMMAND='cat /root/.borg-passphrase' export BORG_RSH='ssh -i /root/.ssh/borg_ed25519' borg create --stats --compression zstd,6 --exclude-caches \ --exclude '/home/*/.cache' \ --exclude '/var/tmp/*' \ ::'{hostname}-{now:%Y-%m-%dT%H:%M}' \ /etc /home /root /var/www create_exit=$? borg prune --list --glob-archives '{hostname}-*' \ --keep-daily 7 --keep-weekly 4 --keep-monthly 6 prune_exit=$? borg compact compact_exit=$? # Borg devuelve 0 (correcto), 1 (aviso) o 2 (error). Se devuelve el peor. exit_code=$(( create_exit > prune_exit ? create_exit : prune_exit )) exit_code=$(( compact_exit > exit_code ? compact_exit : exit_code )) exit "$exit_code" ``` El script no usa `set -e` a propósito: si `borg create` termina con un aviso (código 1, por ejemplo porque un archivo cambió durante la lectura), la retención y la compactación deben ejecutarse igualmente. - `borg prune` conserva las últimas 7 copias diarias, 4 semanales y 6 mensuales, y marca el resto para borrar. `--glob-archives` limita la retención a los archivos de este host. - `borg compact` libera en disco el espacio de los archivos borrados. En Borg 1.2 es un paso obligatorio tras `prune`. Hazlo ejecutable y solo accesible por root: ```bash sudo chmod 700 /usr/local/sbin/borg-backup.sh ``` Crea la unidad de servicio: ```bash sudo nano /etc/systemd/system/borg-backup.service ``` ```ini [Unit] Description=Copia de seguridad con BorgBackup Wants=network-online.target After=network-online.target [Service] Type=oneshot ExecStart=/usr/local/sbin/borg-backup.sh Nice=10 IOSchedulingClass=idle ``` Y el timer, que la ejecuta cada noche a las 02:00 con un retraso aleatorio de hasta 15 minutos: ```bash sudo nano /etc/systemd/system/borg-backup.timer ``` ```ini [Unit] Description=Copia diaria con BorgBackup [Timer] OnCalendar=*-*-* 02:00:00 RandomizedDelaySec=15m Persistent=true [Install] WantedBy=timers.target ``` `Persistent=true` hace que, si el servidor estaba apagado a esa hora, la copia se ejecute al arrancar. Activa el timer y lanza una ejecución manual para probar el servicio: ```bash sudo systemctl daemon-reload sudo systemctl enable --now borg-backup.timer sudo systemctl start borg-backup.service ``` Revisa el resultado en el registro: ```bash sudo journalctl -u borg-backup.service -n 20 --no-pager ``` La salida debe incluir las estadísticas de `borg create` y la lista de `borg prune` sin errores. Comprueba la próxima ejecución programada: ```bash systemctl list-timers borg-backup.timer ``` ```output NEXT LEFT LAST PASSED UNIT ACTIVATES Fri 2026-09-26 02:07:13 CEST 15h left - - borg-backup.timer borg-backup.service ``` ## Paso 8: Restaurar archivos Para trabajar con el repositorio de forma interactiva, abre una shell de root y exporta de nuevo las tres variables del paso 4. Lista el contenido de un archivo concreto, filtrando por ruta: ```bash borg list ::web01-2026-09-25T10:36 etc/nginx ``` Borg guarda las rutas sin la `/` inicial y `borg extract` restaura en el directorio actual. Por eso lo más seguro es extraer en un directorio temporal y copiar después lo que necesites: ```bash mkdir -p /tmp/restore && cd /tmp/restore borg extract --list ::web01-2026-09-25T10:36 etc/nginx ``` ```output etc/nginx etc/nginx/nginx.conf etc/nginx/sites-available/default ... ``` Compara con la versión actual y, si es la correcta, cópiala a su sitio: ```bash diff -r /tmp/restore/etc/nginx /etc/nginx cp -a /tmp/restore/etc/nginx/. /etc/nginx/ ``` Para restaurar un servidor completo, instala Borg en el servidor nuevo, importa la clave si el repositorio estuviera dañado (`borg key import`), configura el acceso SSH y extrae los directorios necesarios de la misma forma. ## Paso 9: Verificar el repositorio `borg check` comprueba la consistencia del repositorio y de los archivos. Ejecútalo periódicamente, por ejemplo una vez al mes: ```bash borg check ``` Si no muestra errores y termina con código 0, el repositorio está bien. La opción `--verify-data` además descifra y verifica todos los datos, lo que es más fiable pero mucho más lento en repositorios grandes. Una comprobación no sustituye a una restauración de prueba: extrae de vez en cuando un directorio completo y verifica que la aplicación funciona con él. ## Solución de problemas **`Remote: borg: command not found`.** Borg no está instalado en el servidor de copias. Instala el paquete `borgbackup` allí. **`Failed to create/acquire the lock`.** Otra ejecución sigue en curso o una anterior se interrumpió. Si estás seguro de que no hay ningún `borg` en marcha en ningún servidor, libera el bloqueo con `borg break-lock`. **`passphrase supplied in BORG_PASSCOMMAND is incorrect`.** El archivo `/root/.borg-passphrase` no contiene la frase con la que se creó el repositorio o tiene un salto de línea de más. Recupérala desde tu gestor de contraseñas. **`Repository path not allowed`.** La ruta de `BORG_REPO` no está dentro de la indicada en `--restrict-to-path` en `authorized_keys`. ## Conclusión Tienes copias diarias cifradas y deduplicadas de `web01` en un servidor remoto, con una clave SSH que solo puede ejecutar `borg serve`, retención automática y un procedimiento de restauración probado. Como siguientes pasos, añade `borg check` mensual a otro timer, envía una alerta cuando `borg-backup.service` falle (por ejemplo con `OnFailure=` en la unidad) y respalda más servidores creando un repositorio y una clave restringida para cada uno.