Bacula es un sistema de copias de seguridad en red pensado para gestionar muchos servidores desde un punto central. Se compone de un Director que planifica los trabajos, un Storage Daemon que escribe los volúmenes, un File Daemon en cada equipo que se respalda y un catálogo en base de datos donde se registra qué archivo está en qué volumen. En este tutorial montarás un servidor Bacula 13 en Ubuntu 24.04 con catálogo PostgreSQL y almacenamiento en disco, harás una copia y una restauración de prueba del propio servidor y después añadirás un cliente remoto.

Requisitos previos

  • Un servidor con Ubuntu 24.04 LTS para Bacula (por ejemplo un VPS de CubePath), con 2 GB de RAM como mínimo y espacio en disco suficiente para los volúmenes.
  • Opcionalmente, un segundo servidor Ubuntu 24.04 que actuará como cliente remoto.
  • Un usuario no root con privilegios sudo en ambos.
  • Conectividad por red privada entre ellos si es posible. Bacula usa los puertos TCP 9101 (Director), 9102 (File Daemon) y 9103 (Storage Daemon).

En esta guía el servidor Bacula se llama backup01 y el cliente web01. Los paquetes de Ubuntu nombran cada demonio con el nombre de host, así que verás recursos como backup01-dir, backup01-sd y backup01-fd. Sustituye esos nombres por los de tus equipos.

Cómo encajan las piezas

ComponentePaqueteServicioPuertoFunción
Directorbacula-directorbacula-director9101Programa trabajos, aplica retenciones, habla con el catálogo
Storage Daemonbacula-sdbacula-sd9103Escribe y lee los volúmenes en disco o cinta
File Daemonbacula-fdbacula-fd9102Lee y restaura archivos en cada cliente
Consolabacula-console--bconsole, la interfaz de administración

Cada demonio se autentica ante los demás con un nombre y una contraseña. El nombre y la contraseña que aparecen en un recurso deben coincidir exactamente en el otro extremo; casi todos los errores de Bacula vienen de ahí.

Paso 1: Instalar PostgreSQL

El catálogo guarda los metadatos de cada archivo respaldado. Instala PostgreSQL antes que Bacula para que el asistente de dbconfig-common pueda crear la base de datos en local:

sudo apt update
sudo apt install postgresql

Comprueba que está en marcha:

systemctl is-active postgresql
active

Paso 2: Instalar Bacula

Instala el Director con soporte PostgreSQL, el Storage Daemon, el File Daemon local y la consola:

sudo apt install bacula-director-pgsql bacula-director bacula-sd bacula-fd bacula-console

Durante la instalación, dbconfig-common preguntará si quieres configurar la base de datos de bacula-director-pgsql. Responde Sí y deja la contraseña en blanco para que genere una aleatoria. El paquete crea la base de datos bacula, sus tablas y los archivos de configuración en /etc/bacula/ con contraseñas aleatorias entre demonios.

Verifica los tres servicios:

systemctl is-active bacula-director bacula-sd bacula-fd
active
active
active

Y que la consola conecta con el Director:

sudo bconsole
Connecting to Director localhost:9101
1000 OK: 10002 backup01-dir Version: 13.0.4
Enter a period to cancel a command.
*

Escribe quit para salir.

Paso 3: Configurar el almacenamiento en disco

La configuración de Ubuntu define dispositivos de disco que apuntan a una ruta inexistente a propósito (/nonexistent/path/to/file/archive/dir), para que elijas dónde guardar los volúmenes. Crea el directorio de volúmenes y otro para restauraciones:

sudo mkdir -p /srv/bacula/volumes /srv/bacula/restores
sudo chown bacula:bacula /srv/bacula/volumes
sudo chmod 750 /srv/bacula/volumes

El Storage Daemon se ejecuta como usuario bacula, por eso el directorio de volúmenes le pertenece. Las restauraciones las escribe el File Daemon, que se ejecuta como root.

Sustituye la ruta de ejemplo en la configuración del Storage Daemon:

sudo sed -i 's#/nonexistent/path/to/file/archive/dir#/srv/bacula/volumes#' /etc/bacula/bacula-sd.conf

Comprueba la sintaxis y reinicia el servicio:

sudo bacula-sd -t -c /etc/bacula/bacula-sd.conf
sudo systemctl restart bacula-sd

Si la prueba no imprime nada, la configuración es válida.

Haz el mismo cambio en el Director, donde la ruta aparece en el trabajo de restauración RestoreFiles y en las exclusiones:

sudo sed -i 's#/nonexistent/path/to/file/archive/dir/bacula-restores#/srv/bacula/restores#; s#/nonexistent/path/to/file/archive/dir#/srv/bacula/volumes#' /etc/bacula/bacula-dir.conf

Paso 4: Definir pool, FileSet y trabajo

La configuración por defecto trae un trabajo de ejemplo (BackupClient1) que solo respalda /usr/sbin. En lugar de modificarlo, añade tus propios recursos en un archivo aparte, lo que facilita las actualizaciones.

Crea el directorio y el archivo:

sudo mkdir -p /etc/bacula/conf.d
sudo nano /etc/bacula/conf.d/backup01.conf

Añade este contenido, sustituyendo backup01-fd por el nombre del File Daemon local (lo ves en el recurso Client de /etc/bacula/bacula-dir.conf):

Pool {
  Name = Diario
  Pool Type = Backup
  Recycle = yes
  AutoPrune = yes
  Volume Retention = 30 days
  Maximum Volume Bytes = 5G
  Maximum Volumes = 40
  Label Format = "Diario-"
}

FileSet {
  Name = "Servidor"
  Include {
    Options {
      signature = MD5
      compression = LZO
    }
    File = /etc
    File = /home
    File = /var/www
  }
  Exclude {
    File = /var/lib/bacula
    File = /srv/bacula
  }
}

Job {
  Name = "Backup-backup01"
  JobDefs = "DefaultJob"
  Client = backup01-fd
  FileSet = "Servidor"
  Pool = Diario
}

Qué hace cada recurso:

  • Pool Diario: agrupa volúmenes de hasta 5 GB con etiqueta automática (Diario-0001, Diario-0002...). Un volumen se puede reciclar 30 días después de su último uso.
  • FileSet Servidor: define qué se respalda, con compresión LZO y firma MD5 de cada archivo.
  • Job Backup-backup01: hereda de DefaultJob el tipo, el almacenamiento File1 y la programación WeeklyCycle (completa el primer domingo del mes, diferencial el resto de domingos e incremental de lunes a sábado a las 23:05).

Incluye el archivo al final de /etc/bacula/bacula-dir.conf:

echo '@/etc/bacula/conf.d/backup01.conf' | sudo tee -a /etc/bacula/bacula-dir.conf

El Director se ejecuta como bacula, así que ajusta los permisos del nuevo archivo:

sudo chown root:bacula /etc/bacula/conf.d/backup01.conf
sudo chmod 640 /etc/bacula/conf.d/backup01.conf

Valida y recarga el Director:

sudo bacula-dir -t -c /etc/bacula/bacula-dir.conf
sudo systemctl reload bacula-director

Paso 5: Ejecutar la primera copia

Abre la consola y lanza el trabajo. Como es la primera ejecución, Bacula la convertirá en completa aunque el nivel por defecto sea incremental:

sudo bconsole

Dentro de bconsole:

run job=Backup-backup01 yes
wait
messages

wait espera a que termine el trabajo y messages muestra el informe. Al final debes ver algo así:

  Backup Level:           Full (upgraded from Incremental)
  Client:                 "backup01-fd"
  FileSet:                "Servidor"
  Pool:                   "Diario" (From Job resource)
  Storage:                "File1" (From Job resource)
  Volume name(s):         Diario-0001
  SD Errors:              0
  Termination:            Backup OK

Comprueba también el volumen en disco y el historial de trabajos:

sudo ls -lh /srv/bacula/volumes
-rw-r----- 1 bacula tape 182M Sep 25 10:13 Diario-0001

En bconsole, list jobs muestra cada trabajo con su estado (T significa terminado correctamente) y list volumes pool=Diario los volúmenes del pool.

Paso 6: Restaurar archivos

Restaura /etc/ssh en /srv/bacula/restores para comprobar que la copia es útil. En bconsole:

restore client=backup01-fd where=/srv/bacula/restores

Bacula mostrará un menú. Elige la opción 5 (seleccionar la copia más reciente de un cliente) y, si pregunta por el FileSet, elige Servidor. Se abrirá un árbol de archivos virtual donde marcas lo que quieres:

cd /etc
mark ssh
done

Revisa el resumen y confirma con yes. Cuando termine, sal de la consola y compara:

sudo diff -r /etc/ssh /srv/bacula/restores/etc/ssh && echo "Restauración correcta"
Restauración correcta

Paso 7: Añadir un cliente remoto

Para respaldar web01, instala en él solo el File Daemon:

sudo apt update
sudo apt install bacula-fd

El paquete genera /etc/bacula/bacula-fd.conf con el nombre de host del cliente y una contraseña aleatoria. Muéstrala:

sudo grep -A2 '^Director' /etc/bacula/bacula-fd.conf

Edita el archivo en el cliente:

sudo nano /etc/bacula/bacula-fd.conf

Haz tres cambios: el primer recurso Director y el recurso Messages deben usar el nombre del Director del servidor (backup01-dir), y FDAddress debe escuchar en la IP privada del cliente en lugar de 127.0.0.1. El resultado queda así:

Director {
  Name = backup01-dir
  Password = "contraseña_generada_en_el_cliente"
}

FileDaemon {
  Name = web01-fd
  FDport = 9102
  WorkingDirectory = /var/lib/bacula
  Pid Directory = /run/bacula
  Maximum Concurrent Jobs = 20
  Plugin Directory = /usr/lib/bacula
  FDAddress = web01_private_ip
}

Messages {
  Name = Standard
  director = backup01-dir = all, !skipped, !restored, !verified, !saved
}

Valida, reinicia y permite el puerto 9102 solo desde el servidor Bacula:

sudo bacula-fd -t -c /etc/bacula/bacula-fd.conf
sudo systemctl restart bacula-fd
sudo ufw allow from backup01_private_ip to any port 9102 proto tcp

Ahora, en el servidor, el File Daemon remoto se conectará directamente al Storage Daemon para enviar los datos. Por defecto el Storage Daemon escucha solo en 127.0.0.1 y el Director anuncia su dirección como localhost, lo que para web01 apuntaría a sí mismo. Cambia ambos valores por la IP privada del servidor.

En /etc/bacula/bacula-sd.conf, dentro del recurso Storage:

  SDAddress = backup01_private_ip

En /etc/bacula/bacula-dir.conf, dentro del recurso Autochanger llamado File1:

  Address = backup01_private_ip

Abre el puerto 9103 para el cliente:

sudo ufw allow from web01_private_ip to any port 9103 proto tcp

Por último, crea /etc/bacula/conf.d/web01.conf en el servidor con el cliente y su trabajo. La contraseña es la que viste en el cliente:

Client {
  Name = web01-fd
  Address = web01_private_ip
  FDPort = 9102
  Catalog = MyCatalog
  Password = "contraseña_generada_en_el_cliente"
  File Retention = 60 days
  Job Retention = 6 months
  AutoPrune = yes
}

Job {
  Name = "Backup-web01"
  JobDefs = "DefaultJob"
  Client = web01-fd
  FileSet = "Servidor"
  Pool = Diario
}

Inclúyelo, ajusta permisos, valida y reinicia los demonios del servidor:

echo '@/etc/bacula/conf.d/web01.conf' | sudo tee -a /etc/bacula/bacula-dir.conf
sudo chown root:bacula /etc/bacula/conf.d/web01.conf
sudo chmod 640 /etc/bacula/conf.d/web01.conf
sudo bacula-sd -t -c /etc/bacula/bacula-sd.conf
sudo bacula-dir -t -c /etc/bacula/bacula-dir.conf
sudo systemctl restart bacula-sd bacula-director

Comprueba la conexión con el cliente y lanza su primera copia desde bconsole:

status client=web01-fd
run job=Backup-web01 yes
wait
messages

status client debe mostrar la versión del File Daemon de web01 y Termination: Backup OK al final del informe.

Sin catálogo, restaurar es mucho más laborioso. La configuración por defecto ya incluye el trabajo BackupCatalog, que vuelca la base de datos con make_catalog_backup.pl y la guarda en un volumen cada noche a las 23:10, después de los demás trabajos. Compruébalo en bconsole con show job=BackupCatalog.

Guarda además fuera del servidor una copia de /etc/bacula/ y de los archivos .bsr de /var/lib/bacula/: son los que te permiten reconstruir el servidor y leer los volúmenes con bextract si pierdes el catálogo.

Solución de problemas

Authorization key rejected o Director authorization problem. El nombre o la contraseña no coinciden entre dos demonios. Compara el recurso Director del cliente o del Storage Daemon con el Client o Autochanger correspondiente en bacula-dir.conf.

El trabajo de un cliente remoto se queda esperando o falla al conectar con el almacenamiento. El cliente intenta hablar con el Storage Daemon en localhost. Revisa Address en el Autochanger File1 y SDAddress en bacula-sd.conf, y que el puerto 9103 esté abierto para el cliente.

Could not open device o errores de permisos al escribir volúmenes. El directorio /srv/bacula/volumes debe pertenecer al usuario bacula. Revisa con ls -ld /srv/bacula/volumes.

El Director no arranca tras un cambio. La unidad valida la configuración antes de arrancar. Ejecuta sudo bacula-dir -t -c /etc/bacula/bacula-dir.conf para ver la línea exacta del error y revisa sudo journalctl -u bacula-director -n 30.

Conclusión

Has desplegado un servidor Bacula en Ubuntu 24.04 con catálogo PostgreSQL, almacenamiento en disco con pools de retención, copia y restauración verificadas y un cliente remoto. A partir de aquí puedes crear programaciones propias en lugar de WeeklyCycle, activar el cifrado de datos en el File Daemon con PKI Encryption o copiar los volúmenes a un segundo destino con trabajos de tipo Copy para tener una copia fuera del servidor.