summaryrefslogtreecommitdiffstats
path: root/roles/common
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem@fripost.org>2015-06-03 21:13:10 +0200
committerGuilhem Moulin <guilhem@fripost.org>2015-06-07 02:54:20 +0200
commit00d6d904dc26592553ba93710c205603757e3faf (patch)
tree09ce9d1f3257da4303362317b04a596f4e0df741 /roles/common
parentab03c7c75d91667dbc30f9ce1f66fe343fb9f93b (diff)
Configure Bacula File Daemon / Storage Daemon / Director.
Using client-side data signing/encryption and wrapping inter-host communication into stunnel.
Diffstat (limited to 'roles/common')
-rw-r--r--roles/common/files/lib/systemd/system/bacula-fd.service12
-rw-r--r--roles/common/handlers/main.yml9
-rw-r--r--roles/common/tasks/bacula.yml150
-rw-r--r--roles/common/tasks/main.yml1
-rw-r--r--roles/common/templates/etc/bacula/bacula-fd.conf.j241
-rw-r--r--roles/common/templates/etc/iptables/services.j210
-rw-r--r--roles/common/templates/etc/stunnel/bacula-fd.conf.j262
7 files changed, 285 insertions, 0 deletions
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