diff options
Diffstat (limited to 'roles/bacula-dir')
6 files changed, 243 insertions, 230 deletions
diff --git a/roles/bacula-dir/files/etc/systemd/system/bacula-director.service.d/override.conf b/roles/bacula-dir/files/etc/systemd/system/bacula-director.service.d/override.conf new file mode 100644 index 0000000..f0d36c4 --- /dev/null +++ b/roles/bacula-dir/files/etc/systemd/system/bacula-director.service.d/override.conf @@ -0,0 +1,13 @@ +[Service] +# Hardening +NoNewPrivileges=yes +PrivateDevices=yes +ProtectHome=yes +ProtectSystem=strict +ReadWriteDirectories=-/var/lib/bacula +ReadWriteDirectories=-/var/log/bacula +PrivateDevices=yes +ProtectControlGroups=yes +ProtectKernelModules=yes +ProtectKernelTunables=yes +RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 diff --git a/roles/bacula-dir/files/lib/systemd/system/bacula-director.service b/roles/bacula-dir/files/lib/systemd/system/bacula-director.service deleted file mode 100644 index 7b34c8b..0000000 --- a/roles/bacula-dir/files/lib/systemd/system/bacula-director.service +++ /dev/null @@ -1,14 +0,0 @@ -[Unit] -Description=Bacula Director service -After=network.target - -[Service] -Type=forking -PIDFile=/var/run/bacula/bacula-dir.9101.pid -StandardOutput=syslog -User=bacula -Group=tape -ExecStart=/usr/sbin/bacula-dir -c /etc/bacula/bacula-dir.conf - -[Install] -WantedBy=multi-user.target diff --git a/roles/bacula-dir/handlers/main.yml b/roles/bacula-dir/handlers/main.yml index 175dfb2..3f3c1bc 100644 --- a/roles/bacula-dir/handlers/main.yml +++ b/roles/bacula-dir/handlers/main.yml @@ -1,9 +1,6 @@ --- - name: systemctl daemon-reload command: /bin/systemctl daemon-reload -- name: Restart stunnel - service: name=stunnel4 pattern=/usr/bin/stunnel4 state=restarted - - name: Restart bacula-director service: name=bacula-director state=restarted diff --git a/roles/bacula-dir/tasks/main.yml b/roles/bacula-dir/tasks/main.yml index cee6fc2..53d44ee 100644 --- a/roles/bacula-dir/tasks/main.yml +++ b/roles/bacula-dir/tasks/main.yml @@ -1,134 +1,65 @@ -- name: Install stunnel - apt: pkg=stunnel4 - -- name: Auto-enable stunnel - lineinfile: dest=/etc/default/stunnel4 - regexp='^(\s*#)?\s*ENABLED=' - line='ENABLED=1' - owner=root group=root - mode=0644 - -- name: Create /etc/stunnel/certs - file: path=/etc/stunnel/certs - state=directory - owner=root group=root - mode=0755 - -- name: Generate a private key and a X.509 certificate for Bacula Dir - command: genkeypair.sh x509 - --pubkey=/etc/stunnel/certs/{{ inventory_hostname_short }}-dir.pem - --privkey=/etc/stunnel/certs/{{ inventory_hostname_short }}-dir.key - --ou=BaculaDir --cn={{ inventory_hostname }} --dns={{ inventory_hostname }} - -t rsa -b 4096 -h sha512 - register: r1 - changed_when: r1.rc == 0 - failed_when: r1.rc > 1 - notify: - - Restart stunnel - tags: - - genkey - -- name: Fetch Bacula Dir X.509 certificate - # Ensure we don't fetch private data - sudo: False - fetch: src=/etc/stunnel/certs/{{ inventory_hostname_short }}-dir.pem - dest=certs/bacula/ - fail_on_missing=yes - flat=yes - tags: - - genkey - -- name: Copy Bacula SD X.509 certificates - copy: src=certs/bacula/{{ hostvars[item].inventory_hostname_short }}-sd.pem - dest=/etc/stunnel/certs/ - owner=root group=root - mode=0644 - with_items: groups['bacula-sd'] | difference([inventory_hostname]) | sort - register: r2 - notify: - - Restart stunnel - -- name: Copy Bacula FD X.509 certificates - copy: src=certs/bacula/{{ hostvars[item].inventory_hostname_short }}-fd.pem - dest=/etc/stunnel/certs/ - owner=root group=root - mode=0644 - with_items: groups.all | difference([inventory_hostname]) | sort - register: r3 - notify: - - Restart stunnel - -- name: Configure stunnel - template: src=etc/stunnel/bacula-dir.conf.j2 - dest=/etc/stunnel/bacula-dir.conf - owner=root group=root - mode=0644 - register: r4 - notify: - - Restart stunnel - -- name: Start stunnel - service: name=stunnel4 pattern=/usr/bin/stunnel4 state=started - when: not (r1.changed or r2.changed or r3.changed or r4.changed) - -- meta: flush_handlers - - - - name: Install bacula-director - apt: pkg={{ item }} - with_items: + apt: pkg={{ packages }} + vars: + packages: - bacula-console + - bacula-director - bacula-director-mysql - name: Create a 'bacula' SQL user - mysql_user2: name=bacula password= auth_plugin=auth_socket - state=present + mysql_user: name=bacula password= plugin=unix_socket + state=present notify: - Restart bacula-director -# Create with: +# Populate with: # echo bconsole $(pwgen -sn 64 1) | sudo tee -a /etc/bacula/passwords-dir # echo $sd-sd $(pwgen -sn 64 1) | sudo tee -a /etc/bacula/passwords-dir # echo $fd-fd $(pwgen -sn 64 1) | sudo tee -a /etc/bacula/passwords-dir # # then add the password for each FD / SD: # echo $director-dir $password | sudo tee /etc/bacula/passwords-sd # echo $director-dir $password | sudo tee /etc/bacula/passwords-fd - name: Ensure /etc/bacula/passwords-dir exists file: path=/etc/bacula/passwords-dir state=file owner=bacula group=bacula mode=0600 - name: Configure bconsole template: src=etc/bacula/bconsole.conf.j2 dest=/etc/bacula/bconsole.conf owner=root group=root mode=0644 - name: Configure bacula template: src=etc/bacula/bacula-dir.conf.j2 dest=/etc/bacula/bacula-dir.conf owner=root group=root mode=0644 register: r notify: - Restart bacula-director -- name: Copy bacula-director.service - copy: src=lib/systemd/system/bacula-director.service - dest=/lib/systemd/system/bacula-director.service +- name: Create /etc/systemd/system/bacula-director.service.d + file: path=/etc/systemd/system/bacula-director.service.d + state=directory + owner=root group=root + mode=0755 + +- name: Copy bacula-director.service override + copy: src=etc/systemd/system/bacula-director.service.d/override.conf + dest=/etc/systemd/system/bacula-director.service.d/override.conf owner=root group=root mode=0644 notify: - systemctl daemon-reload - Restart bacula-director - meta: flush_handlers - name: Enable bacula-director service: name=bacula-director enabled=yes - name: Start bacula-director service: name=bacula-director state=started diff --git a/roles/bacula-dir/templates/etc/bacula/bacula-dir.conf.j2 b/roles/bacula-dir/templates/etc/bacula/bacula-dir.conf.j2 index bfae4c0..ab22375 100644 --- a/roles/bacula-dir/templates/etc/bacula/bacula-dir.conf.j2 +++ b/roles/bacula-dir/templates/etc/bacula/bacula-dir.conf.j2 @@ -1,221 +1,277 @@ # # Default Bacula Director Configuration file -# For Bacula release 5.2.6 (21 February 2012) -- debian jessie/sid +# For Bacula release 9.4.2 (04 February 2019) -- debian buster/sid # Director { # define myself Name = {{ inventory_hostname_short }}-dir @|"sed -n '/^bconsole\\s/ {s//Password = /p; q}' /etc/bacula/passwords-dir" Messages = Daemon Working Directory = /var/lib/bacula - Pid Directory = /var/run/bacula + Pid Directory = /run/bacula QueryFile = "/etc/bacula/scripts/query.sql" Maximum Concurrent Jobs = 1 DirAddress = 127.0.0.1 - DirSourceAddress = 127.0.0.1 DirPort = 9101 + FDConnectTimeout = 5 min + SDConnectTimeout = 5 min } JobDefs { Name = DefaultJob Type = Backup Level = Incremental - Storage = {{ hostvars[ groups['bacula-sd'][0] ].inventory_hostname_short }}-sd + Storage = {{ hostvars[ groups['bacula_sd'][0] ].inventory_hostname_short }}-sd Messages = Standard Accurate = yes + #Rerun Failed Levels = yes Reschedule On Error = yes - Reschedule Interval = 17m + Reschedule Interval = 17 min Reschedule Times = 3 Pool = Default Priority = 10 Write Bootstrap = "/var/lib/bacula/%n.bsr" } JobDefs { Name = DefaultMySQLJob Type = Backup Level = Full - Storage = {{ hostvars[ groups['bacula-sd'][0] ].inventory_hostname_short }}-sd + Storage = {{ hostvars[ groups['bacula_sd'][0] ].inventory_hostname_short }}-sd Messages = Standard FileSet = SQL Schedule = WeeklyCycleAfterBackup Reschedule On Error = yes - Reschedule Interval = 17m + Reschedule Interval = 17 min Reschedule Times = 3 # This creates an ASCII copy of the databases Client Run Before Job = "/usr/bin/mysqldump -r /var/lib/bacula/tmp/dump.sql --events --all-databases" # This deletes the copy of the catalog RunScript { Runs On Client = yes Runs On Success = yes Runs On Failure = yes Runs When = after Command = "/bin/rm -f /var/lib/bacula/tmp/dump.sql" } Pool = database Priority = 20 Write Bootstrap = "/var/lib/bacula/%n.bsr" } JobDefs { Name = DefaultSlapdJob Type = Backup Level = Full - Storage = {{ hostvars[ groups['bacula-sd'][0] ].inventory_hostname_short }}-sd + Storage = {{ hostvars[ groups['bacula_sd'][0] ].inventory_hostname_short }}-sd Messages = Standard FileSet = LDAP Schedule = WeeklyCycleAfterBackup Reschedule On Error = yes - Reschedule Interval = 17m + Reschedule Interval = 17 min Reschedule Times = 3 # This creates an ASCII copy of the databases Client Run Before Job = "/usr/local/sbin/slapcat-all.sh /var/lib/bacula/tmp" # This deletes the copy of the catalog RunScript { Runs On Client = yes Runs On Success = yes Runs On Failure = yes Runs When = after - Command = "/usr/bin/find /var/lib/bacula/tmp -type f -name '*.ldif' -delete" + Command = "/usr/bin/find /var/lib/bacula/tmp -type f \( -name \"*.ldif\" -o -name \"slapd-*\" \) -delete" } Pool = database Priority = 20 Write Bootstrap = "/var/lib/bacula/%n.bsr" } # Backup the director Job { Name = {{ inventory_hostname_short }}-dir Client = {{ inventory_hostname_short }}-fd JobDefs = DefaultJob FileSet = BaculaHome Schedule = WeeklyCycle } # Backup the mailboxes {% for h in groups.IMAP | sort %} Job { Name = {{ hostvars[h].inventory_hostname_short }}-mailboxes Client = {{ hostvars[h].inventory_hostname_short }}-fd JobDefs = DefaultJob + Accurate = no FileSet = Mailboxes Pool = mailboxes-inc Full Backup Pool = mailboxes-full Schedule = Mailboxes13WeeksCycle Max Start Delay = 50 min # To avoid too many overlaps Max Full Interval = 15 weeks } {% endfor %} +# Backup the Nextcloud data +{% for h in groups.nextcloud | sort %} +Job { + Name = {{ hostvars[h].inventory_hostname_short }}-nextcloud + Client = {{ hostvars[h].inventory_hostname_short }}-fd + JobDefs = DefaultJob + FileSet = NextcloudData + Pool = nextcloud-inc + Full Backup Pool = nextcloud-full + Schedule = Nextcloud13WeeksCycle + Max Start Delay = 50 min # To avoid too many overlaps + Max Full Interval = 15 weeks +} +{% endfor %} + # Backup each machine {% for fd in groups.all | sort %} Job { Name = {{ hostvars[fd].inventory_hostname_short }} Client = {{ hostvars[fd].inventory_hostname_short }}-fd JobDefs = DefaultJob FileSet = FileSetRoot Pool = {{ hostvars[fd].inventory_hostname_short }} Priority = 15 Schedule = WeeklyCycle } {% endfor %} -{% for fd in groups['MDA'] | union(groups['webmail']) | union(groups['lists']) | union(groups['bacula-dir']) | sort %} +{% for fd in groups['MDA'] | union(groups['webmail']) | union(groups['lists']) | union(groups['bacula_dir']) | union(groups['nextcloud']) | sort %} Job { Name = {{ hostvars[fd].inventory_hostname_short }}-mysql Client = {{ hostvars[fd].inventory_hostname_short }}-fd JobDefs = DefaultMySQLJob } {% endfor %} -{% for fd in groups['MDA'] | union(groups['MSA']) | union(groups['LDAP-provider']) | union(groups['MX']) | sort %} +{% for fd in groups['MDA'] | union(groups['MSA']) | union(groups['LDAP_provider']) | union(groups['MX']) | sort %} Job { Name = {{ hostvars[fd].inventory_hostname_short }}-slapd Client = {{ hostvars[fd].inventory_hostname_short }}-fd JobDefs = DefaultSlapdJob } {% endfor %} # # Standard Restore template, to be changed by Console program # Only one such job is needed for all Jobs/Clients/Storage ... Job { Name = RestoreFiles Type = Restore Client= {{ inventory_hostname_short }}-fd FileSet = FileSetRoot - Storage = {{ hostvars[ groups['bacula-sd'][0] ].inventory_hostname_short }}-sd + Storage = {{ hostvars[ groups['bacula_sd'][0] ].inventory_hostname_short }}-sd Pool = Default Messages = Standard # NOTE: Files are put on the client (FD) that is being restored. Where = /tmp/bacula-restores } # When to do the backups, full backup on first sunday of the month, # differential (i.e. incremental since full) every other sunday, # and incremental backups other days Schedule { Name = WeeklyCycle Run = Level=Full Messages=Quiet 1st sun at 01:05 Run = Level=Differential Messages=Quiet 2nd-5th sun at 01:05 Run = Level=Incremental Messages=Quiet mon-sat at 01:05 } # Backup mailboxes: full backup every 3 months, hourly incremental backup Schedule { Name = Mailboxes13WeeksCycle Run = Level=Full Pool=mailboxes-full w04 mon at 02:00 Run = Level=Full Pool=mailboxes-full w17 mon at 02:00 Run = Level=Full Pool=mailboxes-full w30 mon at 02:00 Run = Level=Full Pool=mailboxes-full w43 mon at 02:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 01:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet w05-w16 mon-sun at 02:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet w18-w29 mon-sun at 02:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet w31-w42 mon-sun at 02:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet w44-w03 mon-sun at 02:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 03:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 04:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 05:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 06:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 07:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 08:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 09:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 10:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 11:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 12:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 13:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 14:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 15:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 16:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 17:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 18:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 19:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 20:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 21:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 22:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 23:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 00:00 + Run = Level=Differential Pool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet w05-w16 mon at 02:00 + Run = Level=Differential Pool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet w18-w29 mon at 02:00 + Run = Level=Differential Pool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet w31-w42 mon at 02:00 + Run = Level=Differential Pool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet w44-w03 mon at 02:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 00:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 01:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet tue-sun at 02:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 03:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 04:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 05:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 06:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 07:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 08:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 09:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 10:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 11:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 12:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 13:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 14:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 15:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 16:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 17:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 18:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 19:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 20:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 21:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 22:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 23:00 +} + +# Backup Nextcloud data: full backup every 3 months, hourly incremental backup +Schedule { + Name = Nextcloud13WeeksCycle + Run = Level=Full Pool=nextcloud-full w05 mon at 02:30 + Run = Level=Full Pool=nextcloud-full w18 mon at 02:30 + Run = Level=Full Pool=nextcloud-full w31 mon at 02:30 + Run = Level=Full Pool=nextcloud-full w44 mon at 02:30 + Run = Level=Differential Pool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet w06-w17 mon at 02:30 + Run = Level=Differential Pool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet w19-w30 mon at 02:30 + Run = Level=Differential Pool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet w32-w43 mon at 02:30 + Run = Level=Differential Pool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet w45-w04 mon at 02:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 00:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 01:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet tue-sun at 02:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 03:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 04:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 05:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 06:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 07:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 08:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 09:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 10:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 11:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 12:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 13:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 14:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 15:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 16:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 17:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 18:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 19:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 20:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 21:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 22:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 23:30 } # This schedule does the databases. It starts after the WeeklyCycle Schedule { Name = WeeklyCycleAfterBackup Run = Level=Full Messages=Quiet sun-sat at 01:10 } # List of files to be backed up FileSet { Name = BaculaHome Include { Options { signature = SHA1 compression = GZIP verify = pins1 noatime = yes } File = /var/lib/bacula @@ -298,170 +354,270 @@ FileSet { File = /root File = /sbin File = /srv File = /usr File = /var Exclude Dir Containing = .no-backup } Exclude { File = /proc File = /sys File = /run File = /tmp File = /.journal File = /.fsck File = /.autofsck File = /net File = /mnt File = /exports File = /misc File = /media + File = /lost+found } } FileSet { Name = SQL Include { Options { signature = SHA1 compression = GZIP verify = s1 } File = /var/lib/bacula/tmp/dump.sql } } FileSet { Name = LDAP Include { Options { signature = SHA1 compression = GZIP verify = s1 WildFile = "*.ldif" } Options { Wild = "*" Exclude = yes } File = /var/lib/bacula/tmp } } FileSet { Name = Mailboxes Include { + # NOTE: debug FileSet with: + # `sudo -u bacula bconsole <<<"estimate job=mistral-mailboxes level=Full listing" | grep -F -e.{log,cache}` + # we use RegexFile here since bacula's doesn't set FNM_PATHNAME so the `*' and `?' metacharacters match `/' + Options { + Exclude = yes + + # cached mailbox data: $mail_location/mailboxes/INBOX/dbox-Mails/dovecot.index.cache + RegexFile = "^/home/mail/virtual/[^/]+/[^/]+/mail/mailboxes/([^/]+/)+dbox-Mails/dovecot\\.index\\.cache$" + # transaction log file: $mail_location/mailboxes/INBOX/dbox-Mails/dovecot.index.log + RegexFile = "^/home/mail/virtual/[^/]+/[^/]+/mail/mailboxes/([^/]+/)+dbox-Mails/dovecot\\.index\\.log(\\.[0-9])?$" + RegexFile = "^/home/mail/virtual/[^/]+/[^/]+/mail/storage/dovecot\\.map\\.index\\.log(\\.[0-9])?$" + # mailbox list index files: $mail_location/dovecot.list.index.log + RegexFile = "^/home/mail/virtual/[^/]+/[^/]+/mail/dovecot\\.list\\.index\\.log(\\.[0-9])?$" + # mailbox changelog: $mail_location/dovecot.mailbox.log + RegexFile = "^/home/mail/virtual/[^/]+/[^/]+/mail/dovecot\\.mailbox\\.log(\\.[0-9])?$" + # sieve logfile: ~/dovecot.sieve + RegexFile = "^/home/mail/virtual/[^/]+/[^/]+/dovecot\\.sieve\\.log(\\.[0-9])?$" + + # exclude queued files for SiS deduplication + Wild = "/home/mail/attachments/queue/*" + } Options { signature = SHA1 verify = pins1 } File = /home/mail/virtual + File = /home/mail/attachments File = /home/mail/spamspool } + Exclude { + File = "/home/mail/lost+found" + } +} + +FileSet { + Name = NextcloudData + Include { + Options { + Exclude = yes + RegexFile = "^/mnt/nextcloud-data/nextcloud\\.log(\\.[0-9])?$" + RegexFile = "^/mnt/nextcloud-data/updater\\.log(\\.[0-9])?$" + RegexDir = "^/mnt/nextcloud-data/[a-z0-9\\-]+/files_trashbin$" + RegexDir = "^/mnt/nextcloud-data/[a-z0-9\\-]+/files_versions$" + RegexDir = "^/mnt/nextcloud-data/[a-z0-9\\-]+/cache$" + RegexDir = "^/mnt/nextcloud-data/[a-z0-9\\-]+/uploads$" + RegexDir = "^/mnt/nextcloud-data/__groupfolders/trash$" + RegexDir = "^/mnt/nextcloud-data/__groupfolders/versions$" + RegexDir = "^/mnt/nextcloud-data/updater-[[:alnum:]]+$" + RegexDir = "^/mnt/nextcloud-data/appdata_[[:alnum:]]+/preview$" + RegexDir = "^/mnt/nextcloud-data/appdata_[[:alnum:]]+/[^/]+/cache$" + } + Options { + signature = SHA1 + verify = pins1 + } + File = /mnt/nextcloud-data + } + Exclude { + File = "/mnt/nextcloud-data/lost+found" + } } # Client (File Services) to backup -{% set n = 0 %} {% for fd in groups.all | sort %} -{% set n = n + 1 %} Client { Name = {{ hostvars[fd].inventory_hostname_short }}-fd -{% if fd == inventory_hostname %} - Address = 127.0.0.1 -{% else %} - Address = 127.0.{{ n }}.1 -{% endif %} - FDPort = 9112 + Address = {{ ipsec[ hostvars[fd].inventory_hostname_short ] }} + FDPort = 9102 Catalog = MyCatalog @|"sed -n '/^{{ hostvars[fd].inventory_hostname_short }}-fd\\s/ {s//Password = /p; q}' /etc/bacula/passwords-dir" File Retention = 4 months Job Retention = 5 months AutoPrune = yes #Maximum Bandwidth = 1mb/s } {% endfor %} # Definition of file storage device +{% for sd in groups['bacula_sd'] | sort %} Storage { - Name = {{ hostvars[ groups['bacula-sd'][0] ].inventory_hostname_short }}-sd - Address = 127.0.0.1 - SDPort = 9113 - @|"sed -n '/^{{ hostvars[ groups['bacula-sd'][0] ].inventory_hostname_short }}-sd\\s/ {s//Password = /p; q}' /etc/bacula/passwords-dir" + Name = {{ hostvars[sd].inventory_hostname_short }}-sd + Address = {{ ipsec[ hostvars[sd].inventory_hostname_short ] }} + SDPort = 9103 + @|"sed -n '/^{{ hostvars[sd].inventory_hostname_short }}-sd\\s/ {s//Password = /p; q}' /etc/bacula/passwords-dir" Device = FileStorage Media Type = File } +{% endfor %} # Default pool definition Pool { Name = Default Pool Type = Backup Recycle = yes AutoPrune = yes Volume Retention = 3 months Maximum Volume Bytes = 5GB Label Format = "Default-${NumVols:p/4/0/r}" } # Scratch pool definition Pool { Name = Scratch Pool Type = Backup Maximum Volume Bytes = 5GB Label Format = "Scratch-${NumVols:p/4/0/r}" } # System pools definition {% for h in groups.all | sort %} Pool { Name = {{ hostvars[h].inventory_hostname_short }} Pool Type = Backup Recycle = yes AutoPrune = yes Volume Retention = 3 months Maximum Volume Bytes = 5GB Label Format = "{{ hostvars[h].inventory_hostname_short }}-${NumVols:p/4/0/r}" } {% endfor %} # Mailbox pool definition (full backup) Pool { Name = mailboxes-full Pool Type = Backup Recycle = yes AutoPrune = yes - Volume Retention = 26 weeks - Maximum Volume Bytes = 5GB - Label Format = "mailboxes-full-${NumVols:p/4/0/r}" + Volume Retention = 26 weeks # >13 weeks cycle + Maximum Volume Jobs = 1 + Label Format = "mailboxes-full-" + Maximum Volumes = 3 # >2 volumes used at the end of retention period +} + +# Mailbox pool definition (diff backup) +Pool { + Name = mailboxes-diff + Pool Type = Backup + Recycle = yes + AutoPrune = yes + Volume Retention = 15 weeks # >13 weeks cycle + Maximum Volume Jobs = 1 + Label Format = "mailboxes-diff-" + Maximum Volumes = 20 # >15 volumes used at the end of retention period } # Mailbox pool definition (inc backup) Pool { Name = mailboxes-inc Pool Type = Backup Recycle = yes AutoPrune = yes - Volume Retention = 26 weeks - Maximum Volume Bytes = 5GB - Label Format = "mailboxes-inc-${NumVols:p/4/0/r}" + Volume Retention = 8 days # >1 week cycle + Maximum Volume Jobs = 24 # group by day + Label Format = "mailboxes-inc-" + Maximum Volumes = 10 # >8 volumes used at the end of retention period +} + +# Nextcloud pool definition (full backup) +Pool { + Name = nextcloud-full + Pool Type = Backup + Recycle = yes + AutoPrune = yes + Volume Retention = 26 weeks # >13 weeks cycle + Maximum Volume Jobs = 1 + Label Format = "nextcloud-full-" + Maximum Volumes = 3 # >2 volumes used at the end of retention period +} + +# Nextcloud pool definition (diff backup) +Pool { + Name = nextcloud-diff + Pool Type = Backup + Recycle = yes + AutoPrune = yes + Volume Retention = 15 weeks # >13 weeks cycle + Maximum Volume Jobs = 1 + Label Format = "nextcloud-diff-" + Maximum Volumes = 20 # >15 volumes used at the end of retention period +} + +# Nextcloud pool definition (inc backup) +Pool { + Name = nextcloud-inc + Pool Type = Backup + Recycle = yes + AutoPrune = yes + Volume Retention = 8 days # >1 week cycle + Maximum Volume Jobs = 24 # group by day + Label Format = "nextcloud-inc-" + Maximum Volumes = 10 # >8 volumes used at the end of retention period } # Database pool definition Pool { Name = database Pool Type = Backup Recycle = yes AutoPrune = yes Volume Retention = 3 months Maximum Volume Bytes = 5GB Label Format = "database-${NumVols:p/4/0/r}" } # Generic catalog service Catalog { Name = MyCatalog Password = "" DB Name = bacula User = bacula diff --git a/roles/bacula-dir/templates/etc/stunnel/bacula-dir.conf.j2 b/roles/bacula-dir/templates/etc/stunnel/bacula-dir.conf.j2 deleted file mode 100644 index aae49bc..0000000 --- a/roles/bacula-dir/templates/etc/stunnel/bacula-dir.conf.j2 +++ /dev/null @@ -1,70 +0,0 @@ -; ************************************************************************** -; * Global options * -; ************************************************************************** - -; setuid()/setgid() to the specified user/group in daemon mode -setuid = stunnel4 -setgid = stunnel4 - -; PID is created inside the chroot jail -pid = /var/run/stunnel4/bacula-dir.pid - -; Only log messages at severity warning (4) and higher -debug = 4 - -; ************************************************************************** -; * Service defaults may also be specified in individual service sections * -; ************************************************************************** - -; Certificate/key is needed in server mode and optional in client mode -cert = /etc/stunnel/certs/{{ inventory_hostname_short }}-dir.pem -key = /etc/stunnel/certs/{{ inventory_hostname_short }}-dir.key -client = yes -socket = a:SO_BINDTODEVICE=lo - -; Some performance tunings -socket = l:TCP_NODELAY=1 -socket = r:TCP_NODELAY=1 - -; Prevent MITM attacks -verify = 4 - -; Disable support for insecure protocols -options = NO_SSLv2 -options = NO_SSLv3 -options = NO_TLSv1 -options = NO_TLSv1.1 - -; These options provide additional security at some performance degradation -options = SINGLE_ECDH_USE -options = SINGLE_DH_USE - -; Select permitted SSL ciphers -ciphers = EECDH+AES:EDH+AES:!MEDIUM:!LOW:!EXP:!aNULL:!eNULL:!SSLv2:!SSLv3:!TLSv1:!TLSv1.1 - -; ************************************************************************** -; * Service definitions (remove all services for inetd mode) * -; ************************************************************************** - -{% if 'bacula-sd' not in group_names %} -[{{ hostvars[ groups['bacula-sd'][0] ].inventory_hostname_short }}-sd] -accept = 127.0.{{ n }}.1:9113 -connect = {{ groups['bacula-sd'][0] }}:9103 -delay = yes -CAfile = /etc/stunnel/certs/{{ hostvars[ groups['bacula-sd'][0] ].inventory_hostname_short }}-sd.pem -{% endif %} - -{% set n = 0 %} -{% for fd in groups.all | sort %} -{% set n = n + 1 %} -{% if fd != inventory_hostname %} -[{{ hostvars[fd].inventory_hostname_short }}-fd] -accept = 127.0.{{ n }}.1:9112 -connect = {{ fd }}:9102 -delay = yes -CAfile = /etc/stunnel/certs/{{ hostvars[fd].inventory_hostname_short }}-fd.pem -{% endif %} - -{% endfor %} - -; vim:ft=dosini |