From 00d6d904dc26592553ba93710c205603757e3faf Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Wed, 3 Jun 2015 21:13:10 +0200 Subject: Configure Bacula File Daemon / Storage Daemon / Director. Using client-side data signing/encryption and wrapping inter-host communication into stunnel. --- all.yml | 1 + bacula.yml | 16 + common.yml | 2 +- .../lib/systemd/system/bacula-director.service | 14 + roles/bacula-dir/handlers/main.yml | 9 + roles/bacula-dir/tasks/main.yml | 134 ++++++ .../templates/etc/bacula/bacula-dir.conf.j2 | 524 +++++++++++++++++++++ .../templates/etc/bacula/bconsole.conf.j2 | 10 + .../templates/etc/stunnel/bacula-dir.conf.j2 | 70 +++ .../files/lib/systemd/system/bacula-sd.service | 14 + roles/bacula-sd/handlers/main.yml | 9 + roles/bacula-sd/tasks/main.yml | 110 +++++ .../templates/etc/bacula/bacula-sd.conf.j2 | 56 +++ .../templates/etc/stunnel/bacula-sd.conf.j2 | 53 +++ .../files/usr/local/sbin/slapcat-all.sh | 18 + roles/common-LDAP/tasks/main.yml | 6 + .../files/lib/systemd/system/bacula-fd.service | 12 + roles/common/handlers/main.yml | 9 + roles/common/tasks/bacula.yml | 150 ++++++ roles/common/tasks/main.yml | 1 + .../common/templates/etc/bacula/bacula-fd.conf.j2 | 41 ++ roles/common/templates/etc/iptables/services.j2 | 10 + .../common/templates/etc/stunnel/bacula-fd.conf.j2 | 62 +++ 23 files changed, 1330 insertions(+), 1 deletion(-) create mode 100644 bacula.yml create mode 100644 roles/bacula-dir/files/lib/systemd/system/bacula-director.service create mode 100644 roles/bacula-dir/handlers/main.yml create mode 100644 roles/bacula-dir/tasks/main.yml create mode 100644 roles/bacula-dir/templates/etc/bacula/bacula-dir.conf.j2 create mode 100644 roles/bacula-dir/templates/etc/bacula/bconsole.conf.j2 create mode 100644 roles/bacula-dir/templates/etc/stunnel/bacula-dir.conf.j2 create mode 100644 roles/bacula-sd/files/lib/systemd/system/bacula-sd.service create mode 100644 roles/bacula-sd/handlers/main.yml create mode 100644 roles/bacula-sd/tasks/main.yml create mode 100644 roles/bacula-sd/templates/etc/bacula/bacula-sd.conf.j2 create mode 100644 roles/bacula-sd/templates/etc/stunnel/bacula-sd.conf.j2 create mode 100755 roles/common-LDAP/files/usr/local/sbin/slapcat-all.sh create mode 100644 roles/common/files/lib/systemd/system/bacula-fd.service create mode 100644 roles/common/tasks/bacula.yml create mode 100644 roles/common/templates/etc/bacula/bacula-fd.conf.j2 create mode 100644 roles/common/templates/etc/stunnel/bacula-fd.conf.j2 diff --git a/all.yml b/all.yml index dbdc327..9bc36cb 100644 --- a/all.yml +++ b/all.yml @@ -11,3 +11,4 @@ - include: lists.yml - include: git.yml - include: wiki.yml +- include: bacula.yml diff --git a/bacula.yml b/bacula.yml new file mode 100644 index 0000000..3b2eaa9 --- /dev/null +++ b/bacula.yml @@ -0,0 +1,16 @@ +--- +- name: Configure the Bacula Director + hosts: bacula-dir + tags: + - bacula + - bacula-dir + roles: + - bacula-dir + +- name: Configure the Bacula Storage Daemon + hosts: bacula-sd + tags: + - bacula + - bacula-sd + roles: + - bacula-sd diff --git a/common.yml b/common.yml index 3eade06..9593782 100644 --- a/common.yml +++ b/common.yml @@ -13,7 +13,7 @@ - common - name: Common SQL tasks - hosts: MDA:webmail:lists:backup + hosts: MDA:webmail:lists:bacula-dir gather_facts: False tags: mysql,sql roles: diff --git a/roles/bacula-dir/files/lib/systemd/system/bacula-director.service b/roles/bacula-dir/files/lib/systemd/system/bacula-director.service new file mode 100644 index 0000000..7b34c8b --- /dev/null +++ b/roles/bacula-dir/files/lib/systemd/system/bacula-director.service @@ -0,0 +1,14 @@ +[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 new file mode 100644 index 0000000..175dfb2 --- /dev/null +++ b/roles/bacula-dir/handlers/main.yml @@ -0,0 +1,9 @@ +--- +- 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 new file mode 100644 index 0000000..7bcf239 --- /dev/null +++ b/roles/bacula-dir/tasks/main.yml @@ -0,0 +1,134 @@ +- 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: + - bacula-console + - bacula-director-mysql + +- name: Create a 'bacula' SQL user + mysql_user: name=bacula password= auth_plugin=auth_socket + state=present + notify: + - Restart bacula-director + +# Create 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 + 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 new file mode 100644 index 0000000..70712a6 --- /dev/null +++ b/roles/bacula-dir/templates/etc/bacula/bacula-dir.conf.j2 @@ -0,0 +1,524 @@ +# +# Default Bacula Director Configuration file +# For Bacula release 5.2.6 (21 February 2012) -- debian jessie/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 + QueryFile = "/etc/bacula/scripts/query.sql" + Maximum Concurrent Jobs = 1 + DirAddress = 127.0.0.1 + DirSourceAddress = 127.0.0.1 + DirPort = 9101 +} + + +JobDefs { + Name = DefaultJob + Type = Backup + Level = Incremental + Storage = {{ hostvars[ groups['bacula-sd'][0] ].inventory_hostname_short }}-sd + Messages = Standard + Accurate = yes + Reschedule On Error = yes + Reschedule Interval = 17m + 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 + Messages = Standard + FileSet = SQL + Schedule = WeeklyCycleAfterBackup + Reschedule On Error = yes + Reschedule Interval = 17m + 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 = 15 + Write Bootstrap = "/var/lib/bacula/%n.bsr" +} + +JobDefs { + Name = DefaultSlapdJob + Type = Backup + Level = Full + Storage = {{ hostvars[ groups['bacula-sd'][0] ].inventory_hostname_short }}-sd + Messages = Standard + FileSet = LDAP + Schedule = WeeklyCycleAfterBackup + Reschedule On Error = yes + Reschedule Interval = 17m + 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" + } + Pool = database + Priority = 15 + 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 + 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 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 %} +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 %} +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 + 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 = Full 1st sun at 23:05 + Run = Differential 2nd-5th sun at 23:05 + Run = Incremental mon-sat at 23:05 +} + +Schedule { + Name = Mailboxes13WeeksCycle + # Full backup every 3 months + Run = Level=Full Pool=mailboxes-full w04 mon at 03:00 + Run = Level=Full Pool=mailboxes-full w17 mon at 03:00 + Run = Level=Full Pool=mailboxes-full w30 mon at 03:00 + Run = Level=Full Pool=mailboxes-full w43 mon at 03:00 + # Hourly incremental backup otherwise + 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 mon-sun at 02:00 + Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet w05-w16 mon-sun at 03:00 + Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet w18-w29 mon-sun at 03:00 + Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet w31-w42 mon-sun at 03:00 + Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet w44-w03 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 +} + +# This schedule does the databases. It starts after the WeeklyCycle +Schedule { + Name = WeeklyCycleAfterBackup + Run = Full sun-sat at 23: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 + } + Exclude { + File = /var/lib/bacula/tmp + } +} + +FileSet { + Name = FileSetRoot + Include { + # The full /etc/ and /home/, zipped + Options { + WildDir = "/home/backup*" + WildDir = "/home/mail*" + WildFile = "*~" + WildFile = "*#" + Exclude = yes + } + Options { + signature = SHA1 + compression = GZIP + } + File = /etc + File = /home + Exclude Dir Containing = .no-backup + } + Include { + # /var/lib, excluding databases that can be dumped and backed up separately + Options { + WildDir = /var/lib/amavis + WildDir = "/var/lib/apt*" + WildDir = /var/lib/aspell + WildDir = /var/lib/bacula + WildDir = /var/lib/clamav + WildDir = "/var/lib/drupal*" + WildDir = /var/lib/ldap + WildDir = /var/lib/mailman + WildDir = /var/lib/mlocate + WildDir = /var/lib/munin + WildDir = /var/lib/mysql + WildDir = /var/lib/postgresql + WildDir = /var/lib/postgrey + WildDir = /var/lib/rkhunter + WildDir = /var/lib/roundcube + WildDir = /var/lib/tor + WildDir = /var/lib/usbutils + WildFile = "*~" + WildFile = "*#" + Exclude = yes + } + Options { + signature = SHA1 + compression = GZIP + } + File = /var/lib + Exclude Dir Containing = .no-backup + } + Include { + # Other interesting directories + Options { + WildDir = /var/cache + WildDir = "/var/backup*" + WildDir = /var/lib # processed earlier + WildDir = /var/spool + WildDir = "/var/log*" + WildDir = /var/tmp + WildFile = "*~" + WildFile = "*#" + Exclude = yes + } + Options { + signature = SHA1 + } + File = /bin + File = /boot + File = /lib + File = /opt + 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 + } +} + +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 { + Options { + signature = SHA1 + verify = pins1 + } + File = /home/mail/virtual + File = /home/mail/spamspool + } +} + + +# 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 + 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 +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" + Device = FileStorage + Media Type = File +} + + +# 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}" +} + +# 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}" +} + +# 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 +} + + +# Reasonable message delivery -- send most everything to email address +# and to the console +Messages { + Name = Standard +# +# NOTE! If you send to two email or more email addresses, you will need +# to replace the %r in the from field (-f part) with a single valid +# email address in both the mailcommand and the operatorcommand. +# What this does is, it sets the email address that emails would display +# in the FROM field, which is by default the same email as they're being +# sent to. However, if you send email to more than one address, then +# you'll have to set the FROM address manually, to a single address. +# for example, a 'no-reply@mydomain.com', is better since that tends to +# tell (most) people that its coming from an automated source. + +# + MailCommand = "/usr/sbin/bsmtp -h localhost:16132 -f \"\(Bacula\) \<%r\>\" -s \"Bacula: %t %e of %c %l\" %r" + Mail = admin@fripost.org = all, !skipped + OperatorCommand = "/usr/sbin/bsmtp -h localhost:16132 -f \"\(Bacula\) \<%r\>\" -s \"Bacula: Intervention needed for %j\" %r" + Operator = admin@fripost.org = mount + Console = all, !skipped, !saved +# +# WARNING! the following will create a file that you must cycle from +# time to time as it will grow indefinitely. However, it will +# also keep all your messages if they scroll off the console. +# + Append = "/var/log/bacula/bacula.log" = all, !skipped + Catalog = all +} + +# Report upon error only +Messages { + Name = Quiet + MailCommand = "/usr/sbin/bsmtp -h localhost:16132 -f \"\(Bacula\) \<%r\>\" -s \"Bacula [OK]: %t %e of %n %l\" %r" + Mail On Success = admin@fripost.org = all, !info, !fatal, !skipped, !notsaved, !restored + MailCommand = "/usr/sbin/bsmtp -h localhost:16132 -f \"\(Bacula\) \<%r\>\" -s \"Bacula [Fail]: %t %e of %n %l\" %r" + Mail On Error = admin@fripost.org = all, !skipped + OperatorCommand = "/usr/sbin/bsmtp -h localhost:16132 -f \"\(Bacula\) \<%r\>\" -s \"Bacula: Intervention needed for %j\" %r" + Operator = admin@fripost.org = mount + Console = all, !info, !restored, !skipped, !saved + Append = "/var/lib/bacula/log" = all, !skipped + Catalog = all +} + +# +# Message delivery for daemon messages (no job). +Messages { + Name = Daemon + MailCommand = "/usr/sbin/bsmtp -h localhost:16132 -f \"\(Bacula\) \<%r\>\" -s \"Bacula daemon message\" %r" + Mail = admin@fripost.org = all, !skipped + Console = all, !skipped, !saved + Append = "/var/log/bacula/bacula.log" = all, !skipped +} diff --git a/roles/bacula-dir/templates/etc/bacula/bconsole.conf.j2 b/roles/bacula-dir/templates/etc/bacula/bconsole.conf.j2 new file mode 100644 index 0000000..e7f2726 --- /dev/null +++ b/roles/bacula-dir/templates/etc/bacula/bconsole.conf.j2 @@ -0,0 +1,10 @@ +# +# Bacula User Agent (or Console) Configuration File +# + +Director { + Name = {{ inventory_hostname_short }}-dir + DirPort = 9101 + Address = 127.0.0.1 + @|"sed -n '/^bconsole\\s/ {s//Password = /p; q}' /etc/bacula/passwords-dir" +} diff --git a/roles/bacula-dir/templates/etc/stunnel/bacula-dir.conf.j2 b/roles/bacula-dir/templates/etc/stunnel/bacula-dir.conf.j2 new file mode 100644 index 0000000..aae49bc --- /dev/null +++ b/roles/bacula-dir/templates/etc/stunnel/bacula-dir.conf.j2 @@ -0,0 +1,70 @@ +; ************************************************************************** +; * 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 diff --git a/roles/bacula-sd/files/lib/systemd/system/bacula-sd.service b/roles/bacula-sd/files/lib/systemd/system/bacula-sd.service new file mode 100644 index 0000000..4c3f81d --- /dev/null +++ b/roles/bacula-sd/files/lib/systemd/system/bacula-sd.service @@ -0,0 +1,14 @@ +[Unit] +Description=Bacula Storage Daemon service +After=network.target + +[Service] +Type=forking +PIDFile=/var/run/bacula/bacula-sd.9113.pid +StandardOutput=syslog +User=bacula +Group=tape +ExecStart=/usr/sbin/bacula-sd -c /etc/bacula/bacula-sd.conf + +[Install] +WantedBy=multi-user.target diff --git a/roles/bacula-sd/handlers/main.yml b/roles/bacula-sd/handlers/main.yml new file mode 100644 index 0000000..ce391d2 --- /dev/null +++ b/roles/bacula-sd/handlers/main.yml @@ -0,0 +1,9 @@ +--- +- name: systemctl daemon-reload + command: /bin/systemctl daemon-reload + +- name: Restart stunnel + service: name=stunnel4 pattern=/usr/bin/stunnel4 state=restarted + +- name: Restart bacula-sd + service: name=bacula-sd state=restarted diff --git a/roles/bacula-sd/tasks/main.yml b/roles/bacula-sd/tasks/main.yml new file mode 100644 index 0000000..7a6c8c3 --- /dev/null +++ b/roles/bacula-sd/tasks/main.yml @@ -0,0 +1,110 @@ +- 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 SD + command: genkeypair.sh x509 + --pubkey=/etc/stunnel/certs/{{ inventory_hostname_short }}-sd.pem + --privkey=/etc/stunnel/certs/{{ inventory_hostname_short }}-sd.key + --ou=BaculaSD --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 SD X.509 certificate + # Ensure we don't fetch private data + sudo: False + fetch: src=/etc/stunnel/certs/{{ inventory_hostname_short }}-sd.pem + dest=certs/bacula/ + fail_on_missing=yes + flat=yes + tags: + - genkey + +- name: Copy Bacula Dir/FD X.509 certificates + assemble: src=certs/bacula regexp="-(dir|fd)\.pem$" remote_src=no + dest=/etc/stunnel/certs/bacula-dir+fds.pem + owner=root group=root + mode=0644 + register: r2 + notify: + - Restart stunnel + +- name: Configure stunnel + template: src=etc/stunnel/bacula-sd.conf.j2 + dest=/etc/stunnel/bacula-sd.conf + owner=root group=root + mode=0644 + register: r3 + 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) + +- meta: flush_handlers + + + +- name: Install bacula-sd + apt: pkg=bacula-sd + +# Create with: +# echo $director-dir $(pwgen -sn 64 1) | sudo tee -a /etc/bacula/passwords-sd +- name: Ensure /etc/bacula/passwords-sd exists + file: path=/etc/bacula/passwords-sd + state=file + owner=bacula group=bacula + mode=0600 + +- name: Configure bacula + template: src=etc/bacula/bacula-sd.conf.j2 + dest=/etc/bacula/bacula-sd.conf + owner=root group=root + mode=0644 + notify: + - Restart bacula-sd + +- name: Copy bacula-sd.service + copy: src=lib/systemd/system/bacula-sd.service + dest=/lib/systemd/system/bacula-sd.service + owner=root group=root + mode=0644 + notify: + - systemctl daemon-reload + - Restart bacula-sd + +- meta: flush_handlers + +- name: Enable bacula-sd + service: name=bacula-sd enabled=yes + +- name: Start bacula-sd + service: name=bacula-sd state=started + +# To avoid bacula creating archives under /mnt/backup/bacula when it's +# not a mountpoint, use `chmod 0700 /mnt/backup; chown root:root /mnt/backup` +# before mounting the disk. +- name: Create /mnt/backup/bacula + file: path=/mnt/backup/bacula + state=directory + owner=bacula group=tape + mode=0750 diff --git a/roles/bacula-sd/templates/etc/bacula/bacula-sd.conf.j2 b/roles/bacula-sd/templates/etc/bacula/bacula-sd.conf.j2 new file mode 100644 index 0000000..7be783b --- /dev/null +++ b/roles/bacula-sd/templates/etc/bacula/bacula-sd.conf.j2 @@ -0,0 +1,56 @@ +# +# Default Bacula Storage Daemon Configuration file +# +# For Bacula release 5.2.6 (21 February 2012) -- debian jessie/sid +# +# You may need to change the name of your tape drive +# on the "Archive Device" directive in the Device +# resource. If you change the Name and/or the +# "Media Type" in the Device resource, please ensure +# that dird.conf has corresponding changes. +# + +Storage { # define myself + Name = {{ inventory_hostname_short }}-sd + Working Directory = /var/lib/bacula + Pid Directory = /var/run/bacula + Maximum Concurrent Jobs = 20 + SDAddress = 127.0.0.1 + SDPort = 9113 +} + +# +# List Directors who are permitted to contact Storage daemon +# +{% for dir in groups['bacula-dir'] | sort %} +Director { + Name = {{ hostvars[dir].inventory_hostname_short }}-dir + @|"sed -n '/^{{ hostvars[dir].inventory_hostname_short }}-dir\\s/ {s//Password = /p; q}' /etc/bacula/passwords-sd" +} + +# +# Send all messages to the Director, +# mount messages also are sent to the email address +# +Messages { + Name = Standard + director = {{ hostvars[dir].inventory_hostname_short }}-dir = all +} +{% endfor %} + +# +# Devices supported by this Storage daemon +# To connect, the Director's bacula-dir.conf must have the +# same Name and MediaType. +# + +Device { + Name = FileStorage + Media Type = File + Archive Device = /mnt/backup/bacula + LabelMedia = yes; # lets Bacula label unlabeled media + Random Access = Yes; + AutomaticMount = yes; # when device opened, read it + RemovableMedia = no; + AlwaysOpen = no; +} diff --git a/roles/bacula-sd/templates/etc/stunnel/bacula-sd.conf.j2 b/roles/bacula-sd/templates/etc/stunnel/bacula-sd.conf.j2 new file mode 100644 index 0000000..b193826 --- /dev/null +++ b/roles/bacula-sd/templates/etc/stunnel/bacula-sd.conf.j2 @@ -0,0 +1,53 @@ +; ************************************************************************** +; * 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-sd.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 }}-sd.pem +key = /etc/stunnel/certs/{{ inventory_hostname_short }}-sd.key + +; 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) * +; ************************************************************************** + +[{{ inventory_hostname_short }}-sd] +client = no +accept = 9103 +connect = 127.0.0.1:9113 +CAfile = /etc/stunnel/certs/bacula-dir+fds.pem + +; vim:ft=dosini diff --git a/roles/common-LDAP/files/usr/local/sbin/slapcat-all.sh b/roles/common-LDAP/files/usr/local/sbin/slapcat-all.sh new file mode 100755 index 0000000..4e5b5e4 --- /dev/null +++ b/roles/common-LDAP/files/usr/local/sbin/slapcat-all.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +# Usage: slapcat-all.sh DIR +# Save all LDAP databases in DIR: DIR/0.ldif, DIR/1.ldif, ... + +set -ue +PATH=/usr/sbin:/sbin:/usr/bin:/bin + +target="$1" +umask 0077 + +slapcat -n0 -l"$target/0.ldif" +n=$(grep -Ec '^dn:\s+olcDatabase={[1-9][0-9]*}' "$target/0.ldif") + +while [ $n -gt 0 ]; do + slapcat -n$n -l"$target/$n.ldif" + n=$(( $n - 1 )) +done diff --git a/roles/common-LDAP/tasks/main.yml b/roles/common-LDAP/tasks/main.yml index aa2f721..2eb0dfb 100644 --- a/roles/common-LDAP/tasks/main.yml +++ b/roles/common-LDAP/tasks/main.yml @@ -127,3 +127,9 @@ - name: Remove the rootDN under the 'config' database openldap: name="olcDatabase={0}config,cn=config" delete=olcRootDN,olcRootPW + +- name: Copy /usr/local/sbin/slapcat-all.sh + copy: src=usr/local/sbin/slapcat-all.sh + dest=/usr/local/sbin/slapcat-all.sh + owner=root group=root + mode=0755 diff --git a/roles/common/files/lib/systemd/system/bacula-fd.service b/roles/common/files/lib/systemd/system/bacula-fd.service new file mode 100644 index 0000000..6e2bbd4 --- /dev/null +++ b/roles/common/files/lib/systemd/system/bacula-fd.service @@ -0,0 +1,12 @@ +[Unit] +Description=Bacula File Daemon service +After=network.target + +[Service] +Type=forking +PIDFile=/var/run/bacula/bacula-fd.9112.pid +StandardOutput=syslog +ExecStart=/usr/sbin/bacula-fd -c /etc/bacula/bacula-fd.conf + +[Install] +WantedBy=multi-user.target diff --git a/roles/common/handlers/main.yml b/roles/common/handlers/main.yml index ddfe86b..b7ecaab 100644 --- a/roles/common/handlers/main.yml +++ b/roles/common/handlers/main.yml @@ -2,6 +2,9 @@ # corresponding state=restarted handler. (Register the task notifying # the handler, and add a conditional.) --- +- name: systemctl daemon-reload + command: /bin/systemctl daemon-reload + - name: Refresh hostname service: name=hostname.sh state=restarted @@ -35,5 +38,11 @@ - name: Reload Postfix service: name=postfix state=reloaded +- name: Restart stunnel + service: name=stunnel4 pattern=/usr/bin/stunnel4 state=restarted + +- name: Restart bacula-fd + service: name=bacula-fd state=restarted + - name: Update certificate command: update-ca-certificates diff --git a/roles/common/tasks/bacula.yml b/roles/common/tasks/bacula.yml new file mode 100644 index 0000000..248d47d --- /dev/null +++ b/roles/common/tasks/bacula.yml @@ -0,0 +1,150 @@ +- 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 FD + command: genkeypair.sh x509 + --pubkey=/etc/stunnel/certs/{{ inventory_hostname_short }}-fd.pem + --privkey=/etc/stunnel/certs/{{ inventory_hostname_short }}-fd.key + --ou=BaculaFD --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 FD X.509 certificate + # Ensure we don't fetch private data + sudo: False + fetch: src=/etc/stunnel/certs/{{ inventory_hostname_short }}-fd.pem + dest=certs/bacula/ + fail_on_missing=yes + flat=yes + tags: + - genkey + +- name: Copy Bacula Dir X.509 certificates + assemble: src=certs/bacula regexp="-dir\.pem$" remote_src=no + dest=/etc/stunnel/certs/bacula-dirs.pem + owner=root group=root + mode=0644 + register: r2 + when: "'bacula-dir' not in group_names" + notify: + - Restart stunnel + +- 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 + register: r3 + with_items: groups['bacula-sd'] | difference([inventory_hostname]) + notify: + - Restart stunnel + +- name: Configure stunnel + template: src=etc/stunnel/bacula-fd.conf.j2 + dest=/etc/stunnel/bacula-fd.conf + owner=root group=root + mode=0644 + register: r4 + when: "'bacula-dir' not in group_names or 'bacula-sd' not in group_names" + 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-fd + apt: pkg=bacula-fd + +- name: Create /var/lib/bacula/tmp + file: path=/var/lib/bacula/tmp + state=directory + owner=root group=root + mode=0700 + +- name: Delete /etc/bacula/common_default_passwords + file: path=/etc/bacula/common_default_passwords state=absent + +# Create with: +# echo $director-dir $(pwgen -sn 64 1) | sudo tee -a /etc/bacula/passwords-fd +- name: Ensure /etc/bacula/passwords-fd exists + file: path=/etc/bacula/passwords-fd + state=file + owner=root group=root + mode=0600 + +- name: Configure bacula + template: src=etc/bacula/bacula-fd.conf.j2 + dest=/etc/bacula/bacula-fd.conf + owner=root group=root + mode=0644 + notify: + - Restart bacula-fd + +- name: Create /etc/bacula/ssl + file: path=/etc/bacula/ssl + state=directory + owner=root group=root + mode=0755 + +- name: Generate a keypair for data encryption + command: genkeypair.sh x509 + --pubkey=/etc/bacula/ssl/{{ inventory_hostname_short }}.pem + --privkey=/etc/bacula/ssl/{{ inventory_hostname_short }}.pem + --ou=BaculaFD --cn={{ inventory_hostname }} --dns={{ inventory_hostname }} + -t rsa -b 4096 -h sha512 + register: r + changed_when: r.rc == 0 + failed_when: r.rc > 1 + notify: + - Restart bacula-fd + tags: + - genkey + +- name: Copy the master public key for data encryption + copy: src=certs/bacula/data-master.pem + dest=/etc/bacula/ssl/master.pem + owner=root group=root + mode=0644 + tags: + - genkey + +- name: Copy bacula-fd.service + copy: src=lib/systemd/system/bacula-fd.service + dest=/lib/systemd/system/bacula-fd.service + owner=root group=root + mode=0644 + notify: + - systemctl daemon-reload + - Restart bacula-fd + +- meta: flush_handlers + +- name: Enable bacula-fd + service: name=bacula-fd enabled=yes + +- name: Start bacula-fd + service: name=bacula-fd state=started diff --git a/roles/common/tasks/main.yml b/roles/common/tasks/main.yml index 8f28b93..477bd34 100644 --- a/roles/common/tasks/main.yml +++ b/roles/common/tasks/main.yml @@ -30,6 +30,7 @@ - include: logging.yml tags=logging - include: ntp.yml tags=ntp - include: mail.yml tags=mail,postfix +- include: bacula.yml tags=bacula-fd,bacula - name: Install common packages apt: pkg={{ item }} diff --git a/roles/common/templates/etc/bacula/bacula-fd.conf.j2 b/roles/common/templates/etc/bacula/bacula-fd.conf.j2 new file mode 100644 index 0000000..a47bb90 --- /dev/null +++ b/roles/common/templates/etc/bacula/bacula-fd.conf.j2 @@ -0,0 +1,41 @@ +# +# Default Bacula File Daemon Configuration file +# +# For Bacula release 5.2.6 (21 February 2012) -- debian jessie/sid + +# +# List Directors who are permitted to contact this File daemon +# +{% for dir in groups['bacula-dir'] | sort %} +Director { + Name = {{ hostvars[dir].inventory_hostname_short }}-dir + @|"sed -n '/^{{ hostvars[dir].inventory_hostname_short }}-dir\\s/ {s//Password = /p; q}' /etc/bacula/passwords-fd" +} + +# Send all messages except skipped files back to Director +Messages { + Name = Standard + director = {{ hostvars[dir].inventory_hostname_short }}-dir = all, !skipped, !restored +} +{% endfor %} + +# +# "Global" File daemon configuration specifications +# +FileDaemon { # define myself + Name = {{ inventory_hostname_short }}-fd + Working Directory = /var/lib/bacula + Pid Directory = /var/run/bacula + Maximum Concurrent Jobs = 20 + FDAddress = 127.0.0.1 + FDPort = 9112 + FDSourceAddress = 127.0.0.1 +{% if 'bacula-dir' not in group_names or 'bacula-sd' not in group_names %} + Heartbeat Interval = 60s +{% endif %} + + PKI Signatures = Yes # Enable Data Signing + PKI Encryption = Yes # Enable Data Encryption + PKI Keypair = /etc/bacula/ssl/{{ inventory_hostname_short }}.pem # Public and Private Keys + PKI Master Key = /etc/bacula/ssl/master.pem # ONLY the Public Key +} diff --git a/roles/common/templates/etc/iptables/services.j2 b/roles/common/templates/etc/iptables/services.j2 index 187e588..a0bb714 100644 --- a/roles/common/templates/etc/iptables/services.j2 +++ b/roles/common/templates/etc/iptables/services.j2 @@ -59,6 +59,16 @@ in tcp 80,443 # HTTP/HTTPS out tcp 993 # IMAP out tcp 4190 # MANAGESIEVE {% endif %} +{% if 'bacula-dir' in group_names and groups.all | difference(groups['bacula-dir']) %} +out tcp 9102 # BACULA-FD +{% elif groups['bacula-dir'] | difference([inventory_hostname]) %} +in tcp 9102 # BACULA-FD +{% endif %} +{% if 'bacula-sd' in group_names and groups.all | difference(groups['bacula-sd']) %} +in tcp 9103 # BACULA-SD +{% elif groups['bacula-sd'] | difference([inventory_hostname]) %} +out tcp 9103 # BACULA-SD +{% endif %} {% if 'LDAP-provider' in group_names %} out tcp 11371 # HKP diff --git a/roles/common/templates/etc/stunnel/bacula-fd.conf.j2 b/roles/common/templates/etc/stunnel/bacula-fd.conf.j2 new file mode 100644 index 0000000..74364c9 --- /dev/null +++ b/roles/common/templates/etc/stunnel/bacula-fd.conf.j2 @@ -0,0 +1,62 @@ +; ************************************************************************** +; * 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-fd.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 }}-fd.pem +key = /etc/stunnel/certs/{{ inventory_hostname_short }}-fd.key + +; 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) * +; ************************************************************************** + +[{{ inventory_hostname_short }}-fd] +client = no +accept = 9102 +connect = 9112 +CAfile = /etc/stunnel/certs/bacula-dirs.pem + +{% if 'bacula-sd' not in group_names %} +[{{ hostvars[ groups['bacula-sd'][0] ].inventory_hostname_short }}-sd] +client = yes +accept = 127.0.0.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 %} + +; vim:ft=dosini -- cgit v1.2.3