Bacularis is a fully loaded Bacula CE suite that comes with a successor of highly popular Baculum GUI. It can be installed by a one-liner Docker command thereby short-cutting hours of tedious installation steps like the ones I described in one of my previous posts.
1 Creating the container
1.1 with docker run
By default, the docker container mounts six volumes that it labels with non-intuitive random alphanumeric uuids. To get meaningful volumes that we can later identify on the host machine, we add a set of --mount
options so that volumes are not created with anonymous uuid labels.
Furthermore, we open not only the Bacularis port 9097 but also ports 9101-9103 which are needed for communication between the director, the file daemons and the storage daemons.
1 2 3 4 5 6 7 8 9 10 |
ilek@q556:~$ docker run -d -p 9097:9097 -p 9101-9103:9101-9103 \ --name bacuprod \ --mount source=bacuprod_etc,destination=/etc/bacula \ --mount source=bacuprod_archive,destination=/var/lib/bacula \ --mount source=bacuprod_postgre,destination=/var/lib/postgresql/data \ --mount source=bacuprod_api_conf,destination=/var/www/bacularis/protected/vendor/bacularis/bacularis-api/API/Config \ --mount source=bacuprod_api_log,destination=/var/www/bacularis/protected/vendor/bacularis/bacularis-api/API/Logs \ --mount source=bacuprod_web_conf,destination=/var/www/bacularis/protected/vendor/bacularis/bacularis-web/Web/Config \ --mount source=bacuprod_web_log,destination=/var/www/bacularis/protected/vendor/bacularis/bacularis-web/Web/Logs \ bacularis/bacularis-standalone |
1.2 with docker compose
From my experience, it is more convenient to keep the container configuration in a docker-compose.yml
file: The complete configuration is stored readily available on disk, so there is no need to look it up. Besides having to enter multi-line commands with dozens of parameters at the console is cumbersome and prone to syntax errors.
- Save the
docker-compose.yml
file below in a directory like~/docker/bacuprod
- Launch by issuing the command
docker compose up --detach
from the directory - Stop by issuing the command
docker compose down
Failure to provide the hostname will result in slow DNS resolution, timeouts, and connection aborts both at the level of the bacularis web interface and bconsole level (even if executed from inside the container).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
name: bacuprod services: bacuprod: image: 'bacularis/bacularis-standalone:2.1.0-alpine' container_name: 'bacuprod' hostname: 'q556.fritz.box' ports: - '9097:9097' - '9101:9101' - '9102:9102' - '9103:9103' volumes: - etc:/etc/bacula - archive:/var/lib/bacula - postgre:/var/lib/postgresql/data - api_conf:/var/www/bacularis/protected/vendor/bacularis/bacularis-api/API/Config - api_log:/var/www/bacularis/protected/vendor/bacularis/bacularis-api/API/Logs - web_conf:/var/www/bacularis/protected/vendor/bacularis/bacularis-web/Web/Config - web_log:/var/www/bacularis/protected/vendor/bacularis/bacularis-web/Web/Logs volumes: etc: archive: postgre: api_conf: api_log: web_conf: web_log: |
2 Set meaningful daemon names
The default name of the director is simply the host name of the docker container’s Alpine Linux OS plus an appended -dir
. So you get unintuitive names like build-3-16-x86_64-dir
. To better identify the machine, …
… stop the Bacularis container, as sudo
change to the host machine’s local bacula_etc
volume (the path may differ on your machine, depending on the docker installation it might be /var/lib/docker/volumes while in my case it’s ~/.local/share/docker/volumes).
1 2 3 4 5 6 7 8 |
ilek@q556:~/bacuprod$ docker stop bacuprod bacuprod ilek@q556:~/bacuprod$ sudo su [sudo] password for ilek: root@q556:/home/ilek/bacuprod# cd /home/ilek/.local/share/docker/volumes/bacuprod_etc/_data root@q556:/home/ilek/.local/share/docker/volumes/bacuprod_etc/_data# ls bacula-dir.conf bacula-fd.conf bacula-sd.conf bconsole.conf scripts root@q556:/home/ilek/.local/share/docker/volumes/bacuprod_etc/_data# vim bacula-dir.conf |
First thing we have to edit is the bconsole.conf
file. Replace Name and address directives as follows:
2 |
Name = q556_d-dir |
Save and continue editing bacula-dir.conf
as follows:
%s/build-3-16-x86_64-dir/q556_d-dir/gc
(c
option will have each substitution confirmed)
1 2 3 4 5 6 7 8 9 10 |
Director { # define myself Name = q556_d-dir DIRport = 9101 # where we listen for UA connections QueryFile = "/etc/bacula/scripts/query.sql" WorkingDirectory = "/var/lib/bacula" PidDirectory = "/run/bacula" Maximum Concurrent Jobs = 20 Password = "yRtfeKlgyBI7lXuDRXJJ3XuE718Nz/M7cg2zeuSgUNuy" # Console password Messages = Daemon } |
In the same file, we can already change the name of the local client (file daemon) in the JobDef Resource:
%s/build-3-16-x86_64-fd/q556_d-fd/gc
which will also replace all of the three -fd
occurences below in one shot.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
JobDefs { Name = "DefaultJob" Type = Backup Level = Incremental Client = q556_d-fd FileSet = "Full Set" Schedule = "WeeklyCycle" Storage = File1 Messages = Standard Pool = File SpoolAttributes = yes Priority = 10 Write Bootstrap = "/var/lib/bacula/%c.bsr" } |
Still in bacula-dir.conf we change the client name in the Job Resource for the Restore operation:
1 2 3 4 5 6 7 8 9 10 11 12 |
Job { Name = "RestoreFiles" Type = Restore Client = q556_d-fd Storage = File1 # The FileSet and Pool directives are not used by Restore Jobs # but must not be removed FileSet="Full Set" Pool = File Messages = Standard Where = /var/lib/bacula/archive/bacula-restores } |
And, still in bacula-dir.conf we change the client name in the Client
Ressource:
1 2 3 4 5 6 7 8 9 10 11 |
# Client (File Services) to backup Client { Name = q556_d-fd Address = localhost FDPort = 9102 Catalog = MyCatalog Password = "9jTOS+av7cVucWfwyVKSxKVFWF45xgArseso98h6EBO1" # password for FileDaemon File Retention = 60 days # 60 days Job Retention = 6 months # six months AutoPrune = yes # Prune expired Jobs/Files } |
For the sake of house-keeping, we also amend the Name
directive of the Console resource in bacula-conf.dir
:
1 2 3 4 5 |
Console { Name = q556_d-mon Password = "W2lr7PKwCsd2WRAXN8/rAGFXMGB6XplIyMXlamqfYwaU" CommandACL = status, .status } |
Don’t forget that director name also needs to be set for any daemon which the director should talk to. In our default installation, this should be the local file daemon and the storage daemon.
Save the changes in bacula-dir.conf
and continue with editing bacula-fd.conf
:
%s/build-3-16-x86_64/q556_d/gc
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Director { Name = q556_d-dir Password = "9jTOS+av7cVucWfwyVKSxKVFWF45xgArseso98h6EBO1" } [...] Director { Name = q556_d-mon Password = "G+UhGCVuxrajBJAU0yyIDFY+KiUBlA/9n2u/qfJq84NW" Monitor = yes } [...] # Send all messages except skipped files back to Director Messages { Name = Standard director = q556_d-dir = all, !skipped, !restored, !saved } |
Save and continue with editing bacula-sd.conf
:
%s/build-3-16-x86_64/q556_d/gc
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
Storage { # definition of myself Name = q556_d-sd SDPort = 9103 # Director's port WorkingDirectory = "/var/lib/bacula" Pid Directory = "/run/bacula" Plugin Directory = "/usr/lib" Maximum Concurrent Jobs = 20 } [...] # List Directors who are permitted to contact Storage daemon # Director { Name = q556_d-dir Password = "X2FRyPJvCMGw8phX2/GkvkTOUxcgfAkTjfILgYFWbIhP" } [...] # Restricted Director, used by tray-monitor to get the # status of the storage daemon # Director { Name = q556_d-mon Password = "V/dvYvy+gzV5dAiA7a8wptnVP/zfDFIejzoCkpMB2Ett" Monitor = yes } |
Save and exit.
3 Further amendments
3.1 Add host ip and name to /etc/hosts
As we use host names instead of IP addresses we make sure that the q556 host’s IP address is known to bacularis. We therefore have to edit /etc/hosts inside the bacularis container.
For convenience we first install vim
inside the bacularis container.
1 2 3 4 5 |
root@q556:/var/lib/docker/volumes/bacuprod_etc/_data# docker exec -it bacuprod bash bash-5.1# apk add vim fetch https://dl-cdn.alpinelinux.org/alpine/v3.16/main/x86_64/APKINDEX.tar.gz fetch https://dl-cdn.alpinelinux.org/alpine/v3.16/community/x86_64/APKINDEX.tar.gz OK: 114 MiB in 95 packages |
We can then invoke vim /etc/hosts and add the host machine’s name and IP:
3 |
192.168.4.64 q556 |
/etc/hosts
and reamend if necessary.3.2 Wrong database name in script of BackupCatalog
job
In my case the default BackupCatalog failed when I tried to run it from the console:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
ilek@q556:~/docker/bacudock$ docker exec -it bacutest bconsole Connecting to Director localhost:9101 1000 OK: 10002 build-3-16-x86_64-dir Version: 11.0.6 (10 March 2022) Enter a period to cancel a command. *run Automatically selected Catalog: MyCatalog Using Catalog "MyCatalog" A job name must be specified. The defined Job resources are: 1: BackupClient1 2: BackupCatalog 3: RestoreFiles Select Job resource (1-3): 2 Run Backup job JobName: BackupCatalog Level: Full Client: build-3-16-x86_64-fd FileSet: Catalog Pool: File (From Job resource) Storage: File1 (From Job resource) When: 2022-09-19 15:46:09 Priority: 11 OK to run? (yes/mod/no): yes Job queued. JobId=1 *messages 19-Sep 15:46 build-3-16-x86_64-dir JobId 1: shell command: run BeforeJob "/etc/bacula/scripts/make_catalog_backup MyCatalog" 19-Sep 15:46 build-3-16-x86_64-dir JobId 1: BeforeJob: pg_dump: error: connection to server on socket "/run/postgresql/.s.PGSQL.5432" failed: FATAL: database "MyCatalog" does not exist |
For me the term ‘catalog’ is somewhat confusing. According to the Bacula MRG (Section 22.17), the terms catalog and database are apparently used as synonyms. The error message above FATAL: datatbase "MyCatalog" does not exist
corroborates such an assumption.
This leads to two questions:
- What is the actual name of the Bacula database as set up by the Docker container? – Answer: The name of the Bacula PostgreSQL database is (unsurprisingly)
bacula
. - In which Ressource(s) of which config file(s) has this ressource been incorrectly referred to as MyCatalog?
Looking at /etc/bacula-dir.conf
, we realize that the Job
Ressource BackupCatalog contains a directive that is passed MyCatalog as a command line argument.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# Backup the catalog database (after the nightly save) Job { Name = "BackupCatalog" JobDefs = "DefaultJob" Level = Full FileSet="Catalog" Schedule = "WeeklyCycleAfterBackup" # This creates an ASCII copy of the catalog # Arguments to make_catalog_backup are: # make_catalog_backup <catalog-name> RunBeforeJob = "/etc/bacula/scripts/make_catalog_backup MyCatalog" # This deletes the copy of the catalog RunAfterJob = "/etc/bacula/scripts/delete_catalog_backup" Write Bootstrap = "/var/lib/bacula/%n.bsr" Priority = 11 # run after main backup } |
Let’s check the content of the script that is called with MyCatalog. And here’s the relevant line:
91 92 93 94 |
# you could also add --compress for compression. See man pg_dump exec ${BINDIR}/pg_dump -c $PGHOST -U $user $1 >$1.sql ;; esac |
Clearly, the pg_dump command expects the database name – which by default is bacula – and not some externally assigned label or alias from a config file.
So to fix the problem, we simply have to replace MyCatalog
by bacula
in the RunBeforeJob
Directive of the Job Resource for BackupCatalog
in bacula-dir.conf
:
1 |
RunBeforeJob = "/etc/bacula/scripts/make_catalog_backup bacula" |
3.3 No contact to SD when backing up external clients
bacula-dir.conf
of the Bacularis host features two Storage
resources with an Address
directive pointing to localhost
. If you try to connect a client from outside the Docker container the job will stall / spin forever and can only be stopped by cancelling it. You will then get an error message that looks as follows:
1 2 |
q556_d-dir JobId 73: Fatal error: Bad response to Storage command: wanted 2000 OK storage , got Jmsg JobId=73 type=4 level=1664154685 x220-fd JobId 73: Fatal error: job.c:2720 Failed to connect to Storage daemon: localhost:9103 |
The solution is to replace the localhost
Address
directive in the Storage
resource of bacula-dir.conf
on host q556
by the host’s hostname – which is q556
.
bacula-dir.conf
file does not have any Storage
resource, but this is directly included in the Autochanger
sections.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
Storage { Name = "File1" SdPort = 9103 Address = q556 Password = "X2FRyPJvCMGw8phX2/GkvkTOUxcgfAkTjfILgYFWbIhP" Device = "FileChgr1" MediaType = "File1" Autochanger = "File1" MaximumConcurrentJobs = 10 } Storage { Name = "File2" SdPort = 9103 Address = q556 Password = "X2FRyPJvCMGw8phX2/GkvkTOUxcgfAkTjfILgYFWbIhP" Device = "FileChgr2" MediaType = "File2" Autochanger = "File2" MaximumConcurrentJobs = 10 } |
4 First test: running local jobs
We now access the Bacula director from the Docker host machine to start with local backups:
1 |
ilek@q556:~$ docker exec -it bacuprod bconsole |
4.1 Catalog backup
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
Connecting to Director localhost:9101 1000 OK: 10002 q556_d-dir Version: 11.0.6 (10 March 2022) Enter a period to cancel a command. *run Automatically selected Catalog: MyCatalog Using Catalog "MyCatalog" A job name must be specified. The defined Job resources are: 1: BackupClient1 2: BackupCatalog 3: RestoreFiles Select Job resource (1-3): 2 Run Backup job JobName: BackupCatalog Level: Full Client: q556_d-fd FileSet: Catalog Pool: File (From Job resource) Storage: File1 (From Job resource) When: 2022-09-22 13:09:43 Priority: 11 OK to run? (yes/mod/no): yes Job queued. JobId=2 *message 22-Sep 13:09 q556_d-dir JobId 2: shell command: run BeforeJob "/etc/bacula/scripts/make_catalog_backup bacula" *messages 22-Sep 13:09 q556_d-dir JobId 2: Start Backup JobId 2, Job=BackupCatalog.2022-09-22_13.09.45_03 22-Sep 13:09 q556_d-dir JobId 2: Using Device "FileChgr1-Dev1" to write. 22-Sep 13:09 q556_d-sd JobId 2: Volume "Vol-0001" previously written, moving to end of data. 22-Sep 13:09 q556_d-sd JobId 2: Ready to append to end of Volume "Vol-0001" size=61,640 22-Sep 13:09 q556_d-sd JobId 2: Elapsed time=00:00:01, Transfer rate=64.64 K Bytes/second 22-Sep 13:09 q556_d-sd JobId 2: Sending spooled attrs to the Director. Despooling 219 bytes ... 22-Sep 13:09 q556_d-dir JobId 2: Bacula q556_d-dir 11.0.6 (10Mar22): Build OS: x86_64-alpine-linux-musl unknown unknown JobId: 2 Job: BackupCatalog.2022-09-22_13.09.45_03 Backup Level: Full Client: "q556_d-fd" 11.0.6 (10Mar22) x86_64-alpine-linux-musl,unknown,unknown FileSet: "Catalog" 2022-09-22 11:50:13 Pool: "File" (From Job resource) Catalog: "MyCatalog" (From Client resource) Storage: "File1" (From Job resource) Scheduled time: 22-Sep-2022 13:09:43 Start time: 22-Sep-2022 13:09:50 End time: 22-Sep-2022 13:09:51 Elapsed time: 1 sec Priority: 11 FD Files Written: 1 SD Files Written: 1 FD Bytes Written: 64,532 (64.53 KB) SD Bytes Written: 64,643 (64.64 KB) Rate: 64.5 KB/s Software Compression: None Comm Line Compression: 76.1% 4.2:1 Snapshot/VSS: no Encryption: no Accurate: no Volume name(s): Vol-0001 Volume Session Id: 1 Volume Session Time: 1663852175 Last Volume Bytes: 126,753 (126.7 KB) Non-fatal FD errors: 0 SD Errors: 0 FD termination status: OK SD termination status: OK Termination: Backup OK 22-Sep 13:09 q556_d-dir JobId 2: Begin pruning Jobs older than 6 months . 22-Sep 13:09 q556_d-dir JobId 2: No Jobs found to prune. 22-Sep 13:09 q556_d-dir JobId 2: Begin pruning Files. 22-Sep 13:09 q556_d-dir JobId 2: No Files found to prune. 22-Sep 13:09 q556_d-dir JobId 2: End auto prune. 22-Sep 13:09 q556_d-dir JobId 2: shell command: run AfterJob "/etc/bacula/scripts/delete_catalog_backup" |
4.2 Local FileSet backup
We now try to run a file backup job of the local client. Still in bconsole
proceed as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
*run A job name must be specified. The defined Job resources are: 1: BackupClient1 2: BackupCatalog 3: RestoreFiles Select Job resource (1-3): 1 Run Backup job JobName: BackupClient1 Level: Incremental Client: q556_d-fd FileSet: Full Set Pool: File (From Job resource) Storage: File1 (From Job resource) When: 2022-09-22 13:25:19 Priority: 10 OK to run? (yes/mod/no): yes Job queued. JobId=3 You have messages. *messages 22-Sep 13:25 q556_d-dir JobId 3: No prior or suitable Full backup found in catalog. Doing FULL backup. 22-Sep 13:25 q556_d-dir JobId 3: Start Backup JobId 3, Job=BackupClient1.2022-09-22_13.25.48_43 22-Sep 13:25 q556_d-dir JobId 3: Using Device "FileChgr1-Dev2" to write. 22-Sep 13:25 q556_d-sd JobId 3: Volume "Vol-0001" previously written, moving to end of data. 22-Sep 13:25 q556_d-sd JobId 3: Ready to append to end of Volume "Vol-0001" size=126,753 22-Sep 13:25 q556_d-sd JobId 3: Elapsed time=00:00:01, Transfer rate=12.04 M Bytes/second 22-Sep 13:25 q556_d-sd JobId 3: Sending spooled attrs to the Director. Despooling 9,909 bytes ... 22-Sep 13:25 q556_d-dir JobId 3: Bacula q556_d-dir 11.0.6 (10Mar22): Build OS: x86_64-alpine-linux-musl unknown unknown JobId: 3 Job: BackupClient1.2022-09-22_13.25.48_43 Backup Level: Full (upgraded from Incremental) Client: "q556_d-fd" 11.0.6 (10Mar22) x86_64-alpine-linux-musl,unknown,unknown FileSet: "Full Set" 2022-09-22 13:25:49 Pool: "File" (From Job resource) Catalog: "MyCatalog" (From Client resource) Storage: "File1" (From Job resource) Scheduled time: 22-Sep-2022 13:25:19 Start time: 22-Sep-2022 13:25:52 End time: 22-Sep-2022 13:25:53 Elapsed time: 1 sec Priority: 10 FD Files Written: 56 SD Files Written: 56 FD Bytes Written: 12,044,152 (12.04 MB) SD Bytes Written: 12,049,525 (12.04 MB) Rate: 12044.2 KB/s Software Compression: None Comm Line Compression: 57.8% 2.4:1 Snapshot/VSS: no Encryption: no Accurate: no Volume name(s): Vol-0001 Volume Session Id: 2 Volume Session Time: 1663852175 Last Volume Bytes: 12,186,782 (12.18 MB) Non-fatal FD errors: 0 SD Errors: 0 FD termination status: OK SD termination status: OK Termination: Backup OK 22-Sep 13:25 q556_d-dir JobId 3: Begin pruning Jobs older than 6 months . 22-Sep 13:25 q556_d-dir JobId 3: No Jobs found to prune. 22-Sep 13:25 q556_d-dir JobId 3: Begin pruning Files. 22-Sep 13:25 q556_d-dir JobId 3: No Files found to prune. 22-Sep 13:25 q556_d-dir JobId 3: End auto prune. |
5 Adding an (external) client
Any client must have a Bacula File Daemon running on the system which allows to the machine to connect with the Bacula Director and the Storage Daemon.
5.1 Installing bacula-fd on a client machine
Why not Docker for external file daemons?
The fastest way to install bacula-fd
on a client machine is to pull the bacularis-api-fd from Docker and run a container with the file daemon.
The disadvantage is though, that by default, such a file daemon can only see what is inside the container while we are typically interested in the data on the host which runs the container. Granting the container access to the host data comes with a lot of problems:
- We would need to come up with some NFS stunt to (ideally) mount the client’s complete file system as a volume into the container – but exclude the Docker container files it would produce some kind of “circular reference”.
- Even if this would work, we would have to worry about file ownership and access privileges in the backup process
- There may be older client machines that run a 32 bit OS, while Docker generally requires 64 bit architectures. (Still, Bacula’s deb packages are only provided for 64 bit machines, too).
Direct deployment
All this looks pretty nasty, so installing the file daemon on the client machine in a direct deployment from some deb packages (or whatever installs on the client machine’s OS) looks more suitable.
The first thing is to arm the GPG key and set up the repo information on the client machine. proceed as in section 2 of my post Bacula testing installation. Once you have pulled the apt update from the new repositories, you can install bacula-fd
:
1 |
ilek@x220:/media/ramdisk$ sudo apt install bacula-client |
Check if the client is already running:
1 2 3 4 5 6 7 8 9 10 11 12 |
ilek@x220:/media/ramdisk$ sudo service bacula-fd status ● bacula-fd.service - Bacula File Daemon service Loaded: loaded (/lib/systemd/system/bacula-fd.service; enabled; vendor preset: enabled) Active: active (running) since Sun 2022-09-18 12:27:03 CEST; 1 day 13h ago Main PID: 1088 (bacula-fd) Tasks: 3 (limit: 4484) Memory: 960.0K CPU: 501ms CGroup: /system.slice/bacula-fd.service └─1088 /opt/bacula/bin/bacula-fd -fP -c /opt/bacula/etc/bacula-fd.conf Sep 18 12:27:03 x220 systemd[1]: Started Bacula File Daemon service. |
5.2 Configuration of the client
We first make sure that the client has the bacula director machine’s IP address mapped to the director machine’s host name, so we check if /etc/hosts on the client has an entry with q556 192.196.4.64
.
Next, edit the config file in /opt/bacula/etc/bacula-fd.conf
(you need to be root
to get access to that file).
In the Director Resource, set the correct Name directive by putting in the Name of the director that runs inside the Bacularis Docker container on our main Bacula Server (which is q556
in my case).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# List Directors who are permitted to contact this File daemon # Director { Name = q556_d-dir Password = "YSJfJkw_X9kfEOT8oFd0LvDgdjT-VoQjo" } [...] # Send all messages except skipped files back to Director Messages { Name = Standard director = q556_d-dir = all, !skipped, !restored, !verified, !saved } |
Todo: Clarify the role and function of the Bacula monitor.
Save and restart the client machine’s file daemon:
1 2 |
ilek@x220:/media/ramdisk$ sudo service bacula-fd restart ilek@x220:/media/ramdisk$ sudo service bacula-fd status |
5.3 Amending bacula-dir.conf
on the Bacula director machine
Now change to the machine running the Bacula Director (our Bacularis container) and amend bacula-dir.conf
as shown below. The Password
directive must match the Password directive we set on the external client machine in the previous step.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# Second Client (File Services) to backup # You should change Name, Address, and Password before using # Client { Name = x220-fd Address = x220 FDPort = 9102 Catalog = MyCatalog Password = "YSJfJkw_X9kfEOT8oFd0LvDgdjT-VoQjo" # password for FileDaemon 2 File Retention = 60 days # 60 days Job Retention = 6 months # six months AutoPrune = yes # Prune expired Jobs/Files } |
Restart the Bacula director in the Docker container to activate the amendments:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
ilek@q556:~$ docker restart bacuprod bacuprod ilek@q556:~$ docker exec -it bacuprod bconsole Connecting to Director localhost:9101 1000 OK: 10002 q556_d-dir Version: 11.0.6 (10 March 2022) Enter a period to cancel a command. *status client The defined Client resources are: 1: q556_d-fd 2: x220-fd Select Client (File daemon) resource (1-2): 2 Connecting to Client x220-fd at x220:9102 x220-fd Version: 13.0.1 (05 August 2022) x86_64-pc-linux-gnu-bacula-enterprise ubuntu 22.04 Daemon started 22-Sep-22 15:58. Jobs: run=0 running=0. Heap: heap=966,656 smbytes=197,860 max_bytes=197,877 bufs=101 max_bufs=101 Sizes: boffset_t=8 size_t=8 debug=0 trace=0 mode=0,0 bwlimit=0kB/s Crypto: fips=N/A crypto=OpenSSL 3.0.2 15 Mar 2022 Plugin: bpipe-fd.so(2) Running Jobs: Director connected using TLS at: 22-Sep-22 16:13 No Jobs running. ==== |
5.4 Opening and forwarding ports
Client side
On the client side, we the Bacula file daemon we installed will listen on port 9102. Use the netstat
command to confirm that this port has already been opened when we installed the bacula-client
package from the repository.
1 2 3 4 5 6 7 8 9 10 11 |
ilek@x220:~$ netstat -an | grep LISTEN [..] tcp 0 0 0.0.0.0:43457 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:43283 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:2049 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:9102 0.0.0.0:* LISTEN tcp 0 0 10.126.44.1:53 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:631 0.0.0.0:* LISTEN [...] |
Docker host side
While Docker usually takes care of opening and forwarding all necessary ports between a container and its host, we also have to make sure that the host machine for the docker container has ports 9101-9103 opened for traffic from and to file and storage daemons.
1 2 3 4 5 6 7 8 9 10 11 |
ilek@q556:~$ sudo netstat -tulpn | grep LISTEN [...] tcp 0 0 0.0.0.0:9101 0.0.0.0:* LISTEN 17542/rootlesskit tcp 0 0 0.0.0.0:9103 0.0.0.0:* LISTEN 17542/rootlesskit tcp 0 0 0.0.0.0:9102 0.0.0.0:* LISTEN 17542/rootlesskit tcp 0 0 0.0.0.0:9097 0.0.0.0:* LISTEN 17542/rootlesskit [...] tcp6 0 0 :::9101 :::* LISTEN 17542/rootlesskit tcp6 0 0 :::9103 :::* LISTEN 17542/rootlesskit tcp6 0 0 :::9102 :::* LISTEN 17542/rootlesskit tcp6 0 0 :::9097 :::* LISTEN 17542/rootlesskit |
After making sure that the host machine is actually accepting traffic on ports 9101-9103, we have to ensure that this traffic is actually forwarded to the Docker container.
First we check if the host machine has activated port forwarding per se. Check if the file /etc/sysctl.conf
on the Docker host has the following line uncommented. Detailed instructions on principally allowing port forwarding can be found in my Bacula testing installation post.
Next we check the ufw status:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
ilek@q556:~$ sudo ufw status Status: active To Action From -- ------ ---- 9096 ALLOW Anywhere 9095 ALLOW Anywhere 22/tcp LIMIT Anywhere 9097 ALLOW Anywhere 9096 (v6) ALLOW Anywhere (v6) 9095 (v6) ALLOW Anywhere (v6) 22/tcp (v6) LIMIT Anywhere (v6) 9097 (v6) ALLOW Anywhere (v6) |
Surprisingly, although the previous iptables
command showed that the host is listening on ports 9101-9103, ufw does not list these ports under the allowed ports. We therefore allow these ports explicitly under ufw and remove ports 9095 and 9096 as these look like leftovers from a previous legacy Baculum installation:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
ilek@q556:~$ sudo ufw delete allow 9095 Rule deleted Rule deleted (v6) ilek@q556:~$ sudo ufw delete allow 9096 Rule deleted Rule deleted (v6) ilek@q556:~$ sudo ufw allow 9101 Rule added Rule added (v6) ilek@q556:~$ sudo ufw allow 9102 Rule added Rule added (v6) ilek@q556:~$ sudo ufw allow 9103 Rule added Rule added (v6) |