summaryrefslogtreecommitdiffstats
path: root/roles/common/tasks
diff options
context:
space:
mode:
Diffstat (limited to 'roles/common/tasks')
-rw-r--r--roles/common/tasks/apt.yml12
-rw-r--r--roles/common/tasks/bacula.yml92
-rw-r--r--roles/common/tasks/clamav.yml26
-rw-r--r--roles/common/tasks/fail2ban.yml49
-rw-r--r--roles/common/tasks/firewall.yml49
-rw-r--r--roles/common/tasks/haveged.yml5
-rw-r--r--roles/common/tasks/ipsec.yml93
-rw-r--r--roles/common/tasks/logging.yml13
-rw-r--r--roles/common/tasks/mail.yml107
-rw-r--r--roles/common/tasks/main.yml114
-rw-r--r--roles/common/tasks/munin-node.yml121
-rw-r--r--roles/common/tasks/ntp.yml32
-rw-r--r--roles/common/tasks/resolved.yml36
-rw-r--r--roles/common/tasks/rkhunter.yml5
-rw-r--r--roles/common/tasks/samhain.yml26
-rw-r--r--roles/common/tasks/smart.yml7
-rw-r--r--roles/common/tasks/stunnel.yml16
-rw-r--r--roles/common/tasks/sysctl.yml19
-rw-r--r--roles/common/tasks/unbound.yml21
19 files changed, 452 insertions, 391 deletions
diff --git a/roles/common/tasks/apt.yml b/roles/common/tasks/apt.yml
index f444315..8df3e8f 100644
--- a/roles/common/tasks/apt.yml
+++ b/roles/common/tasks/apt.yml
@@ -1,49 +1,43 @@
- name: Install various APT tools
- apt: pkg={{ item }}
- with_items:
+ apt: pkg={{ packages }}
+ vars:
+ packages:
- apt
- apt-listchanges
- apt-show-versions
- debian-archive-keyring
- debian-goodies
- needrestart
- unattended-upgrades
- debfoster
- deborphan
- - debsecan
- debsums
- name: Configure APT (1)
template: src=etc/apt/{{ item }}.j2
dest=/etc/apt/{{ item }}
owner=root group=root
mode=0644
with_items:
- sources.list
- preferences
notify:
- apt-get update
- name: Configure APT (2)
copy: src=etc/apt/{{ item }}
dest=/etc/apt/{{ item }}
owner=root group=root
mode=0644
with_items:
- listchanges.conf
- apt.conf.d/10periodic
- apt.conf.d/50unattended-upgrades
-- name: Configure the Debian Security Analyzer
- template: src=etc/default/debsecan.j2
- dest=/etc/default/debsecan
- owner=root group=root
- mode=0644
-
- name: Start cron
service: name=cron state=started
tags:
- cron
# We should run 'apt-get update' before proceeding to any other task.
- meta: flush_handlers
diff --git a/roles/common/tasks/bacula.yml b/roles/common/tasks/bacula.yml
index 248d47d..308e358 100644
--- a/roles/common/tasks/bacula.yml
+++ b/roles/common/tasks/bacula.yml
@@ -1,111 +1,33 @@
-- 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:
+# Populate 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
@@ -115,36 +37,42 @@
--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
+- name: Create /etc/systemd/system/bacula-fd.service.d
+ file: path=/etc/systemd/system/bacula-fd.service.d
+ state=directory
+ owner=root group=root
+ mode=0755
+
+- name: Copy bacula-fd.service override
+ copy: src=etc/systemd/system/bacula-fd.service.d/override.conf
+ dest=/etc/systemd/system/bacula-fd.service.d/override.conf
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/clamav.yml b/roles/common/tasks/clamav.yml
index e1ece0d..437387b 100644
--- a/roles/common/tasks/clamav.yml
+++ b/roles/common/tasks/clamav.yml
@@ -1,22 +1,32 @@
- name: Install ClamAV
- apt: pkg={{ item }}
- with_items:
+ apt: pkg={{ packages }}
+ vars:
+ packages:
- clamav
- clamav-daemon
- clamav-freshclam
- name: Configure FreshClam
- lineinfile: "dest=/etc/clamav/freshclam.conf
- line='DatabaseMirror {{ item }}'"
- with_items:
- - db.local.clamav.net
- - database.clamav.net
- - db.other.clamav.net
+ template: src=etc/clamav/freshclam.conf.j2
+ dest=/etc/clamav/freshclam.conf
+ owner=clamav group=adm
+ mode=0444
+ tags: freshclam
notify:
- Restart freshclam
- name: Start ClamAV
service: name={{ item }} state=started
with_items:
- clamav-daemon
- clamav-freshclam
+
+- name: Add a 'clamav' alias
+ lineinfile: dest=/etc/aliases create=yes
+ regexp="^clamav{{':'}} "
+ line="clamav{{':'}} root"
+
+- name: Compile the static local Postfix database
+ postmap: cmd=postalias src=/etc/aliases db=lmdb
+ owner=root group=root
+ mode=0644
diff --git a/roles/common/tasks/fail2ban.yml b/roles/common/tasks/fail2ban.yml
index be26c79..563075f 100644
--- a/roles/common/tasks/fail2ban.yml
+++ b/roles/common/tasks/fail2ban.yml
@@ -1,28 +1,63 @@
- name: Install fail2ban
apt: pkg=fail2ban
-- name: Add addititional filters
- copy: src=etc/fail2ban/filter.d/{{ item }}
- dest=/etc/fail2ban/filter.d/{{ item }}
+- name: Configure fail2ban (fail2ban.local)
+ copy: src=etc/fail2ban/fail2ban.local
+ dest=/etc/fail2ban/fail2ban.local
owner=root group=root
mode=0644
register: r1
- with_items:
- - roundcube.conf
notify:
- Restart fail2ban
-- name: Configure fail2ban
+- name: Configure fail2ban (jail.local)
template: src=etc/fail2ban/jail.local.j2
dest=/etc/fail2ban/jail.local
owner=root group=root
mode=0644
register: r2
notify:
- Restart fail2ban
+- name: Configure fail2ban (action.d/nftables-allports.local)
+ copy: src=etc/fail2ban/action.d/nftables-allports.local
+ dest=/etc/fail2ban/action.d/nftables-allports.local
+ owner=root group=root
+ mode=0644
+ register: r3
+ notify:
+ - Restart fail2ban
+
+- name: Copy filters
+ copy: src=etc/fail2ban/filter.d/
+ dest=/etc/fail2ban/filter.d/
+ owner=root group=root
+ mode=0644
+ register: r4
+ notify:
+ - Restart fail2ban
+
+- name: Create directory /etc/systemd/system/fail2ban.service.d
+ file: path=/etc/systemd/system/fail2ban.service.d
+ state=directory
+ owner=root group=root
+ mode=0755
+
+- name: Harden fail2ban.service
+ copy: src=etc/systemd/system/fail2ban.service.d/override.conf
+ dest=/etc/systemd/system/fail2ban.service.d/override.conf
+ owner=root group=root
+ mode=0644
+ register: r5
+ notify:
+ - systemctl daemon-reload
+ - Restart fail2ban
+
- name: Start fail2ban
service: name=fail2ban state=started
- when: not (r1.changed or r2.changed)
+ when: not (r1.changed or r2.changed or r3.changed or r4.changed or r5.changed)
- meta: flush_handlers
+
+- name: Delete /var/lib/fail2ban/fail2ban.sqlite3
+ file: path=/var/lib/fail2ban/fail2ban.sqlite3 state=absent
diff --git a/roles/common/tasks/firewall.yml b/roles/common/tasks/firewall.yml
index 29c0e2b..30f4fa9 100644
--- a/roles/common/tasks/firewall.yml
+++ b/roles/common/tasks/firewall.yml
@@ -1,40 +1,27 @@
-- name: Install some packages required for the firewall
- apt: pkg={{ item }}
- with_items:
- - iptables
- - netmask
- - bsdutils
+- name: Install nftables
+ apt: pkg=nftables
-- name: Create directory /etc/iptables
- file: path=/etc/iptables
- state=directory
- owner=root group=root
+- name: Copy /usr/local/sbin/update-firewall
+ copy: src=usr/local/sbin/update-firewall
+ dest=/usr/local/sbin/update-firewall
+ owner=root group=staff
mode=0755
-- name: Generate /etc/iptables/services
- template: src=etc/iptables/services.j2
- dest=/etc/iptables/services
+- name: Copy /etc/nftables.conf
+ template: src=etc/nftables.conf.j2
+ dest=/etc/nftables.conf
owner=root group=root
- mode=0600
-
-- name: Copy /usr/local/sbin/update-firewall.sh
- copy: src=usr/local/sbin/update-firewall.sh
- dest=/usr/local/sbin/update-firewall.sh
- owner=root group=root
- mode=0755
-
-- name: Make the rulesets persistent
- copy: src=etc/network/{{ item }}
- dest=/etc/network/{{ item }}
- owner=root group=root
- mode=0755
- with_items:
- - if-pre-up.d/iptables
- - if-post-down.d/iptables
+ mode=0644
- name: Ensure the firewall is up to date
- command: /usr/local/sbin/update-firewall.sh -c
+ command: /usr/local/sbin/update-firewall -c
register: rv
# A non-zero return value will make ansible stop and show stderr. This
# is what we want.
- changed_when: rv.rc
+ changed_when: rv.rc != 0
+
+- name: Enable nftables.service
+ service: name=nftables enabled=yes
+
+- name: Start nftables.service
+ service: name=nftables state=started
diff --git a/roles/common/tasks/haveged.yml b/roles/common/tasks/haveged.yml
deleted file mode 100644
index 3f03a28..0000000
--- a/roles/common/tasks/haveged.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-- name: Install haveged
- apt: pkg=haveged
-
-- name: Start haveged
- service: name=haveged state=started
diff --git a/roles/common/tasks/ipsec.yml b/roles/common/tasks/ipsec.yml
new file mode 100644
index 0000000..917c687
--- /dev/null
+++ b/roles/common/tasks/ipsec.yml
@@ -0,0 +1,93 @@
+- name: Install strongSwan
+ apt: pkg={{ packages }}
+ vars:
+ packages:
+ - strongswan-charon
+ - strongswan-starter
+ # for the GCM and openssl plugins
+ - libstrongswan-standard-plugins
+ notify:
+ - Update firewall
+ - Restart IPsec
+
+- name: Auto-create a dedicated virtual subnet for IPsec
+ template: src=etc/network/if-up.d/ipsec.j2
+ dest=/etc/network/if-up.d/ipsec
+ owner=root group=root
+ mode=0755
+
+- name: Auto-deactivate the dedicated virtual subnet for IPsec
+ file: src=../if-up.d/ipsec
+ dest=/etc/network/if-down.d/ipsec
+ owner=root group=root state=link force=yes
+
+
+- name: Configure IPsec
+ template: src=etc/ipsec.conf.j2
+ dest=/etc/ipsec.conf
+ owner=root group=root
+ mode=0644
+ register: r1
+ notify:
+ - Restart IPsec
+
+- name: Configure IPsec's secrets
+ template: src=etc/ipsec.secrets.j2
+ dest=/etc/ipsec.secrets
+ owner=root group=root
+ mode=0600
+ register: r2
+ notify:
+ - Restart IPsec
+
+- name: Configure Charon
+ copy: src=etc/strongswan.d/{{ item }}
+ dest=/etc/strongswan.d/{{ item }}
+ owner=root group=root
+ mode=0644
+ with_items:
+ - charon.conf
+ - charon/socket-default.conf
+ register: r3
+ notify:
+ - Restart IPsec
+
+- name: Generate a key pair for IPsec public key authentication
+ command: genkeypair.sh keypair
+ --pubkey=/etc/ipsec.d/certs/{{ inventory_hostname_short }}.pem
+ --privkey=/etc/ipsec.d/private/{{ inventory_hostname_short }}.key
+ -t rsa -b 4096
+ register: r4
+ changed_when: r4.rc == 0
+ failed_when: r4.rc > 1
+ notify:
+ - Restart IPsec
+ tags:
+ - genkey
+
+- name: Fetch the public part of IPsec host key
+ # Ensure we don't fetch private data
+ become: False
+ fetch: src=/etc/ipsec.d/certs/{{ inventory_hostname_short }}.pem
+ dest=certs/ipsec/{{ inventory_hostname_short }}.pem
+ fail_on_missing=yes flat=yes
+ tags:
+ - genkey
+
+# Don't copy our pubkey due to a possible race condition. Only the
+# remote machine has authority regarding its key.
+- name: Copy the public part of IPsec peers' key
+ copy: src=certs/ipsec/{{ hostvars[item].inventory_hostname_short }}.pem
+ dest=/etc/ipsec.d/certs/{{ hostvars[item].inventory_hostname_short }}.pem
+ owner=root group=root
+ mode=0644
+ with_items: "{{ groups.all | difference([inventory_hostname]) }}"
+ register: r5
+ tags:
+ - genkey
+ notify:
+ - Restart IPsec
+
+- name: Start IPsec
+ service: name=ipsec state=started
+ when: not (r1.changed or r2.changed or r3.changed or r4.changed or r5.changed)
diff --git a/roles/common/tasks/logging.yml b/roles/common/tasks/logging.yml
index 3b86294..699c6e3 100644
--- a/roles/common/tasks/logging.yml
+++ b/roles/common/tasks/logging.yml
@@ -1,82 +1,83 @@
- name: Install logging server & utilities
- apt: pkg={{ item }}
- with_items:
+ apt: pkg={{ packages }}
+ vars:
+ packages:
- rsyslog
- - syslog-summary
- logcheck
- logcheck-database
- logrotate
- name: Configure rsyslog
copy: src=etc/rsyslog.conf
dest=/etc/rsyslog.conf
owner=root group=root
mode=0644
register: r1
notify:
- Restart rsyslog
tags:
- syslog
- name: Configure postfix's custom rsyslog rules
template: src=etc/rsyslog.d/postfix.conf.j2
dest=/etc/rsyslog.d/postfix.conf
owner=root group=root
mode=0644
register: r2
notify:
- Restart rsyslog
tags:
- syslog
- name: Start rsyslog
service: name=rsyslog state=started
when: not (r1.changed or r2.changed)
tags:
- syslog
- meta: flush_handlers
- name: Configure logcheck (1)
copy: src=etc/logcheck/{{ item }}
dest=/etc/logcheck/{{ item }}
- owner=root group=logcheck
+ owner=root group=root
mode=0644
with_items:
- logcheck.conf
- ignore.d.server/common-local
- ignore.d.server/dovecot-local
- ignore.d.server/postfix-local
+ - ignore.d.server/strongswan-local
# logcheck-sudo already exists, but changing the filename for our
# local modifications would defeat the ruleset
- violations.ignore.d/logcheck-sudo
tags:
- logcheck
- name: Configure logcheck (2)
lineinfile: dest=/etc/logcheck/logcheck.logfiles
line={{ item }}
state=present
create=yes
- owner=root group=logcheck
- mode=0640
+ owner=root group=root
+ mode=0644
with_items:
- /var/log/syslog
- /var/log/auth.log
- /var/log/mail.log
tags:
- logcheck
- name: Minimal logging policy (1)
lineinfile: dest=/etc/logrotate.d/rsyslog
regexp="^/var/log/mail\\.(log|info|sasl)$"
state=absent
owner=root group=root
mode=0644
- name: Minimal logging policy (2)
copy: src=etc/logrotate.d/fripost-mail
dest=/etc/logrotate.d/fripost-mail
owner=root group=root
mode=0644
tags:
diff --git a/roles/common/tasks/mail.yml b/roles/common/tasks/mail.yml
index 1873928..139386f 100644
--- a/roles/common/tasks/mail.yml
+++ b/roles/common/tasks/mail.yml
@@ -1,114 +1,63 @@
- name: Install Postfix
- apt: pkg={{ item }}
- with_items:
+ apt: pkg={{ packages }}
+ vars:
+ packages:
# That one is nicer than GNU mailutils' mailx(1)
- - heirloom-mailx
+ - s-nail
- postfix
- - postfix-cdb
+ - postfix-lmdb
- name: Create Postfix instances
postmulti: instance={{ postfix_instance[item].name }}
group={{ postfix_instance[item].group | default('') }}
register: r1
- with_items: postfix_instance.keys() | intersect(group_names) | list
+ with_items: "{{ postfix_instance.keys() | intersect(group_names) | list }}"
notify:
- Restart Postfix
-- name: Link the dynamic maps & master.cf of each children to the master's
- # main.cf is specialized to each dedicated role, though
- file: src=../postfix/{{ item.1 }}
- dest=/etc/postfix-{{ postfix_instance[item.0].name }}/{{ item.1 }}
+- name: Link the dynamic maps of each children to the master's
+ # main.cf and master.cf are specialized to each dedicated role, though
+ file: src=../postfix/dynamicmaps.cf
+ dest=/etc/postfix-{{ postfix_instance[item].name }}/dynamicmaps.cf
owner=root group=root
state=link force=yes
register: r2
- with_nested:
- - postfix_instance.keys() | intersect(group_names) | list
- - [ 'dynamicmaps.cf', 'master.cf' ]
- notify:
- - Restart Postfix
-
-- name: Configure Postfix (1)
- copy: src=etc/postfix/master.cf
- dest=/etc/postfix/master.cf
- owner=root group=root
- mode=0644
- register: r3
+ with_items: "{{ postfix_instance.keys() | intersect(group_names) | list }}"
notify:
- Restart Postfix
-- name: Configure Postfix (2)
- template: src=etc/postfix/main.cf.j2
- dest=/etc/postfix/main.cf
+- name: Configure Postfix
+ template: src=etc/postfix/{{ item }}.j2
+ dest=/etc/postfix/{{ item }}
owner=root group=root
mode=0644
+ with_items:
+ - main.cf
+ - master.cf
notify:
- Reload Postfix
-- name: Create directory /etc/postfix/ssl
- file: path=/etc/postfix/ssl
- state=directory
- owner=root group=root
- mode=0755
- tags:
- - genkey
-
-- name: Generate a private key and a X.509 certificate for Postfix
- command: genkeypair.sh x509
- --pubkey=/etc/postfix/ssl/{{ ansible_fqdn }}.pem
- --privkey=/etc/postfix/ssl/{{ ansible_fqdn }}.key
- --ou=Postfix --cn={{ ansible_fqdn }}
- -t ecdsa -b secp384r1 -h sha512
- register: r4
- changed_when: r4.rc == 0
- failed_when: r4.rc > 1
- notify:
- - Restart Postfix
- tags:
- - genkey
-
-- name: Fetch Postfix's X.509 certificate
- # Ensure we don't fetch private data
- sudo: False
- fetch: src=/etc/postfix/ssl/{{ ansible_fqdn }}.pem
- dest=certs/postfix/
- fail_on_missing=yes
- flat=yes
- tags:
- - genkey
-
-- name: Add a 'root' alias
+- name: Add some common aliases
lineinfile: dest=/etc/aliases create=yes
- regexp="^root:"" "
- line="root:"" root@fripost.org"
+ regexp='^{{ item.src }}{{':'}} '
+ line='{{ item.src }}{{':'}} {{ item.dst }}'
+ with_items:
+ - { src: mailer-daemon, dst: 'postmaster' }
+ - { src: postmaster, dst: 'root' }
+ - { src: nobody, dst: 'root' }
+ - { src: root, dst: 'root@fripost.org' }
- name: Compile the static local Postfix database
- postmap: cmd=postalias src=/etc/aliases db=cdb
+ postmap: cmd=postalias src=/etc/aliases db=lmdb
owner=root group=root
mode=0644
-# We're using CDB
+# We're using LMDB
- name: Delete /etc/aliases.db
file: path=/etc/aliases.db state=absent
-- name: Copy the Postfix TLS policy map
- template: src=etc/postfix/tls_policy.j2
- dest=/etc/postfix/tls_policy
- owner=root group=root
- mode=0644
- when: "'out' not in group_names or 'MX' in group_names"
- tags:
- - tls_policy
-
-- name: Compile the Postfix TLS policy map
- postmap: cmd=postmap src=/etc/postfix/tls_policy db=cdb
- owner=root group=root
- mode=0644
- when: "'out' not in group_names or 'MX' in group_names"
- tags:
- - tls_policy
-
- name: Start Postfix
service: name=postfix state=started
- when: not (r1.changed or r2.changed or r3.changed or r4.changed)
+ when: not (r1.changed or r2.changed)
- meta: flush_handlers
diff --git a/roles/common/tasks/main.yml b/roles/common/tasks/main.yml
index 470a6b2..293d22b 100644
--- a/roles/common/tasks/main.yml
+++ b/roles/common/tasks/main.yml
@@ -1,70 +1,102 @@
---
-- include: sysctl.yml tags=sysctl
-- include: hosts.yml
-- include: apt.yml tags=apt
+- import_tasks: sysctl.yml
+ tags: sysctl
+- import_tasks: hosts.yml
+- import_tasks: apt.yml
+ tags: apt
- name: Install intel-microcode
apt: pkg=intel-microcode
- when: "ansible_processor[0] | search('^(Genuine)?Intel.*') and not (ansible_virtualization_role == 'guest' and ansible_virtualization_type == 'xen')"
+ when: "ansible_processor[1] is search('^(Genuine)?Intel.*') and not ansible_virtualization_role == 'guest'"
tags: intel
-- include: firewall.yml tags=firewall,iptables
-- include: samhain.yml tags=samhain
-- include: auditd.yml tags=auditd
-- include: rkhunter.yml tags=rkhunter
-- include: clamav.yml tags=clamav
-- include: fail2ban.yml tags=fail2ban
-- include: smart.yml tags=smartmontools,smart
- when: "not ((ansible_virtualization_role == 'guest' and ansible_virtualization_type == 'xen') or ansible_system_vendor == 'QEMU')"
-- include: haveged.yml tags=haveged,entropy
+- import_tasks: firewall.yml
+ tags:
+ - firewall
+ - iptables
+ - nftables
+
+- import_tasks: stunnel.yml
+ tags: stunnel
+ when: "'webmail' in group_names and 'LDAP_provider' not in group_names"
+#- import_tasks: auditd.yml
+# tags: auditd
+- import_tasks: resolved.yml
+ tags:
+ - resolv
+ - resolved
+ - dns
+- import_tasks: unbound.yml
+ tags:
+ - unbound
+ - dns
+ when: "ansible_processor[1] is search('^(Genuine)?Intel.*') and not ansible_virtualization_role == 'guest'"
+- import_tasks: rkhunter.yml
+ tags: rkhunter
+- import_tasks: clamav.yml
+ tags: clamav
+- import_tasks: fail2ban.yml
+ tags: fail2ban
+- import_tasks: smart.yml
+ tags:
+ - smartmontools
+ - smart
+ when: "not ansible_virtualization_role == 'guest'"
- name: Copy genkeypair.sh and gendhparam.sh
copy: src=usr/local/bin/{{ item }}
dest=/usr/local/bin/{{ item }}
- owner=root group=root
+ owner=root group=staff
mode=0755
tags: genkey
with_items:
- genkeypair.sh
- gendhparam.sh
- name: Generate DH parameters
- command: gendhparam.sh /etc/ssl/private/dhparams.pem creates=/etc/ssl/private/dhparams.pem
+ command: gendhparam.sh /etc/ssl/dhparams.pem 2048
+ creates=/etc/ssl/dhparams.pem
tags: genkey
-- include: logging.yml tags=logging
-- include: ntp.yml tags=ntp
-- include: mail.yml tags=mail,postfix
-- include: bacula.yml tags=bacula-fd,bacula
-- include: munin-node.yml tags=munin-node,munin
+- import_tasks: ipsec.yml
+ tags:
+ - strongswan
+ - ipsec
+ when: "groups.all | length > 1"
+- import_tasks: logging.yml
+ tags: logging
+- import_tasks: ntp.yml
+ tags: ntp
+- import_tasks: mail.yml
+ tags:
+ - mail
+ - postfix
+- import_tasks: bacula.yml
+ tags:
+ - bacula-fd
+ - bacula
+- import_tasks: munin-node.yml
+ tags:
+ - munin-node
+ - munin
- name: Install common packages
- apt: pkg={{ item }}
- with_items:
+ apt: pkg={{ packages }}
+ vars:
+ packages:
- ca-certificates
- etckeeper
- ethtool
- git
- htop
- molly-guard
- rsync
- screen
- - telnet-ssl
-
-# XXX: this is a workaround the CAcert root CAs not being present in
-# Jessie. In stretch, we would merely install the 'ca-cacert' package.
-- name: Create directory /usr/local/share/ca-certificates/CAcert
- file: path=/usr/local/share/ca-certificates/CAcert
- state=directory
- owner=root group=root
- mode=0755
- tags:
- - certs
+ - bind9-dnsutils
-- name: Copy CAcert root CAs
- copy: src=certs/CAcert/{{ item }}
- dest=/usr/local/share/ca-certificates/CAcert/{{ item }}
+- name: Disable resume device
+ # Cf. initramfs-tools(7) and initramfs.conf(5).
+ copy: src=etc/initramfs-tools/conf.d/resume
+ dest=/etc/initramfs-tools/conf.d/resume
owner=root group=root
mode=0644
- with_items:
- - root.crt
- - class3.crt
tags:
- - certs
+ - initramfs
+ - resume
notify:
- - Update certificate
+ - Update initramfs
diff --git a/roles/common/tasks/munin-node.yml b/roles/common/tasks/munin-node.yml
index 9e5d8f4..2411b59 100644
--- a/roles/common/tasks/munin-node.yml
+++ b/roles/common/tasks/munin-node.yml
@@ -1,23 +1,24 @@
- name: Install munin-node
- apt: pkg={{ item }}
- with_items:
+ apt: pkg={{ packages }}
+ vars:
+ packages:
- munin-node
- munin-plugins-extra
###
- acpi
- lm-sensors
- ethtool
- hdparm
- libwww-perl
- libxml-simple-perl
- logtail
- name: Create directory /usr/local/share/munin/plugins
file: path=/usr/local/share/munin/plugins
state=directory
owner=root group=root
mode=0755
- name: Copy our own Munin plugins
copy: src={{ item }}
dest=/usr/local/share/munin/plugins/
@@ -44,68 +45,90 @@
owner=root group=root
state=link force=yes
register: r2
with_items:
- cpu
- df
- df_inode
- diskstats
- entropy
- fail2ban
- forks
- fw_conntrack
- fw_forwarded_local
- fw_packets
- hddtemp_smartctl
- interrupts
- irqstats
- load
- memory
- netstat
- - ntp_kernel_err
- - ntp_kernel_pll_freq
- - ntp_kernel_pll_off
- - ntp_offset
- open_files
- open_inodes
- processes
- proc_pri
- swap
- threads
- uptime
- users
- vmstat
notify:
- Restart munin-node
-- name: Delete Munin plugins
+- name: Install Munin plugins
+ file: src=/usr/share/munin/plugins/{{ item }}
+ dest=/etc/munin/plugins/{{ item }}
+ owner=root group=root
+ state=link force=yes
+ with_items:
+ - ntp_kernel_err
+ - ntp_kernel_pll_freq
+ - ntp_kernel_pll_off
+ - ntp_offset
+ when: "'NTP_master' in group_names"
+ notify:
+ - Restart munin-node
+
+- name: Delete unnecessary Munin plugins
file: path=/etc/munin/plugins/{{ item }}
state=absent
register: r3
with_items:
- http_loadtime
- ip_255.255.255.255
- postfix_mailqueue
- postfix_mailvolume
notify:
- Restart munin-node
+- name: Delete unnecessary Munin plugins
+ file: path=/etc/munin/plugins/{{ item }}
+ state=absent
+ with_items:
+ - ntp_kernel_err
+ - ntp_kernel_pll_freq
+ - ntp_kernel_pll_off
+ - ntp_offset
+ when: "'NTP_master' not in group_names"
+ notify:
+ - Restart munin-node
+
- name: Install 'if_' Munin wildcard plugin
file: src=/usr/share/munin/plugins/{{ item.0 }}_
dest=/etc/munin/plugins/{{ item.0 }}_{{ item.1 }}
owner=root group=root
state=link force=yes
register: r4
with_nested:
- [ if, if_err ]
- [ lo, "{{ ansible_default_ipv4.interface }}" ]
notify:
- Restart munin-node
- name: Install 'postfix_mailvolume2' Munin plugin
file: src=/usr/local/share/munin/plugins/postfix_mailvolume2
dest=/etc/munin/plugins/postfix_mailvolume2
owner=root group=root
state=link force=yes
register: r5
notify:
- Restart munin-node
@@ -115,93 +138,49 @@
dest=/etc/munin/plugins/postfix_mailqueue_postfix
owner=root group=root
state=link force=yes
register: r6
notify:
- Restart munin-node
- name: Install 'postfix_stats_' Munin wildcard plugin
file: src=/usr/local/share/munin/plugins/postfix_stats_
dest=/etc/munin/plugins/postfix_stats_{{ item }}_postfix
owner=root group=root
state=link force=yes
register: r7
with_items:
- smtpd
- qmgr
- smtp
notify:
- Restart munin-node
-- name: Start munin-node
- service: name=munin-node state=started
- when: not (r1.changed or r2.changed or r3.changed or r4.changed or r5.changed or r6.changed or r7.changed)
-
-- meta: flush_handlers
-
-
-
-- 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
+- name: Create directory /etc/systemd/system/munin-node.service.d
+ file: path=/etc/systemd/system/munin-node.service.d
state=directory
owner=root group=root
mode=0755
-- name: Generate a private key and a X.509 certificate for munin-node
- command: genkeypair.sh x509
- --pubkey=/etc/stunnel/certs/munin-{{ inventory_hostname_short }}.pem
- --privkey=/etc/stunnel/certs/munin-{{ inventory_hostname_short }}.key
- --ou=Munin --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 Munin X.509 certificate
- # Ensure we don't fetch private data
- sudo: False
- fetch: src=/etc/stunnel/certs/munin-{{ inventory_hostname_short }}.pem
- dest=certs/munin/{{ inventory_hostname }}.pem
- fail_on_missing=yes
- flat=yes
- tags:
- - genkey
-
-- name: Copy munin-master X.509 certificates
- assemble: src=certs/munin regexp="{{ groups['munin-master'] | join('|') }}\.pem$" remote_src=no
- dest=/etc/stunnel/certs/munin-master.pem
- owner=root group=root
- mode=0644
- register: r2
- when: "'munin-master' not in group_names"
+- name: Copy munin-node.service override
+ copy: src=etc/systemd/system/munin-node.service.d/override.conf
+ dest=/etc/systemd/system/munin-node.service.d/override.conf
+ owner=root group=root
+ mode=0644
+ register: r8
notify:
- - Restart stunnel
+ - systemctl daemon-reload
+ - Restart munin-node
-- name: Configure stunnel
- template: src=etc/stunnel/munin-node.conf.j2
- dest=/etc/stunnel/munin-node.conf
- owner=root group=root
- mode=0644
- register: r3
- when: "'munin-master' not in group_names"
- notify:
- - Restart stunnel
+# We use RuntimeDirectory in our overrride unit to avoid permission
+# issues caused by the restrictive Capability Bounding Set
+- name: Mask /usr/lib/tmpfiles.d/munin-common.conf
+ file: src=/dev/null
+ dest=/etc/tmpfiles.d/munin-common.conf
+ owner=root group=root
+ state=link
-- name: Start stunnel
- service: name=stunnel4 pattern=/usr/bin/stunnel4 state=started
- when: not (r1.changed or r2.changed or r3.changed)
+- name: Start munin-node
+ service: name=munin-node state=started
+ when: not (r1.changed or r2.changed or r3.changed or r4.changed or r5.changed or r6.changed or r7.changed or r8.changed)
- meta: flush_handlers
diff --git a/roles/common/tasks/ntp.yml b/roles/common/tasks/ntp.yml
index f9a01c8..2ff9e49 100644
--- a/roles/common/tasks/ntp.yml
+++ b/roles/common/tasks/ntp.yml
@@ -1,15 +1,33 @@
-- name: Install ntp
- apt: pkg=ntp
+- name: Remove ntp package
+ apt: pkg=ntp state={{ state }} purge=yes
+ vars:
+ state: "{{ ('NTP_master' in group_names) | ternary('present', 'absent') }}"
+
+- name: Install systemd-timesyncd package
+ apt: pkg=systemd-timesyncd state=present purge=yes
+ when: "'NTP_master' not in group_names"
+
+- name: Create /etc/systemd/timesyncd.conf.d
+ file: path=/etc/systemd/timesyncd.conf.d
+ state=directory
+ owner=root group=root
+ mode=0755
+ when: "'NTP_master' not in group_names"
- name: Configure ntp
- template: src=etc/ntp.conf.j2
- dest=/etc/ntp.conf
+ template: src=etc/{{ conf }}.j2
+ dest=/etc/{{ conf }}
owner=root group=root
mode=0644
+ vars:
+ conf: "{{ ('NTP_master' in group_names) | ternary('ntp.conf', 'systemd/timesyncd.conf.d/fripost.conf') }}"
+ service: "{{ ('NTP_master' in group_names) | ternary('ntp', 'systemd-timesyncd') }}"
notify:
- - Restart ntp
+ - Restart {{ service }}
- meta: flush_handlers
-- name: Start ntp
- service: name=ntp state=started
+- name: Start and enable ntp
+ service: name={{ service }}.service state=started enabled=true
+ vars:
+ service: "{{ ('NTP_master' in group_names) | ternary('ntp', 'systemd-timesyncd') }}"
diff --git a/roles/common/tasks/resolved.yml b/roles/common/tasks/resolved.yml
new file mode 100644
index 0000000..2834eaa
--- /dev/null
+++ b/roles/common/tasks/resolved.yml
@@ -0,0 +1,36 @@
+- name: Install systemd-resolved
+ apt: pkg={{ packages }}
+ vars:
+ packages:
+ - systemd-resolved
+ - libnss-resolve
+ - libnss-myhostname
+
+- name: Create directory /etc/systemd/resolved.conf.d
+ file: path=/etc/systemd/resolved.conf.d
+ state=directory
+ owner=root group=root
+ mode=0755
+
+- name: Configure systemd-resolved
+ template: src=etc/systemd/resolved.conf.d/local.conf.j2
+ dest=/etc/systemd/resolved.conf.d/local.conf
+ owner=root group=root
+ mode=0644
+ notify:
+ - Restart systemd-resolved
+
+- name: Start systemd-resolved
+ service: name=systemd-resolved.service enabled=true state=started
+
+- meta: flush_handlers
+
+- name: Remove resolvconf
+ apt: pkg=resolvconf state=absent purge=yes
+
+- name: Configure /etc/nsswitch.conf
+ lineinfile: "dest=/etc/nsswitch.conf create=no
+ regexp='^(hosts:\\s+).*'
+ line='\\1resolve [!UNAVAIL=return] files myhostname dns'
+ backrefs=true"
+ tags: nsswitch
diff --git a/roles/common/tasks/rkhunter.yml b/roles/common/tasks/rkhunter.yml
index c9d26fa..64f2aac 100644
--- a/roles/common/tasks/rkhunter.yml
+++ b/roles/common/tasks/rkhunter.yml
@@ -1,23 +1,24 @@
- name: Install rkhunter
- apt: pkg={{ item }}
- with_items:
+ apt: pkg={{ packages }}
+ vars:
+ packages:
- rkhunter
- curl
- iproute2
- lsof
- unhide
# To test the configuration:
# ansible all -m command -a '/usr/bin/rkhunter -c --nomow --rwo'
- name: Configure rkhunter
copy: src=etc/{{ item }}
dest=/etc/{{ item }}
owner=root group=root
mode=0644
with_items:
- rkhunter.conf
- default/rkhunter
notify:
# This might not always be necessary, but it's not like we would
# change the config every day...
- Update rkhunter's data file
diff --git a/roles/common/tasks/samhain.yml b/roles/common/tasks/samhain.yml
deleted file mode 100644
index dd5c09b..0000000
--- a/roles/common/tasks/samhain.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-- name: Install samhain
- apt: pkg=samhain
- # XXX: Doesn't work out of the box, see #660197.
- # Every once in a while, or after a major upgrade, you may want to
- # update Samhain's database:
- #
- # sudo samhain -t update --foreground -l none
- #
- # To update the database interactively, without sending mails:
- #
- # sudo samhain -t update --interactive -l none -m none
-
-- name: Configure samhain
- copy: src=etc/samhain/samhainrc
- dest=/etc/samhain/samhainrc
- owner=root group=root
- mode=0644
- notify:
- - Reload samhain
-
-- name: Start samhain
- # This task is inconditional because samhain is reloaded not
- # restarted.
- service: name=samhain state=started
-
-- meta: flush_handlers
diff --git a/roles/common/tasks/smart.yml b/roles/common/tasks/smart.yml
index 8d35d9f..68e507f 100644
--- a/roles/common/tasks/smart.yml
+++ b/roles/common/tasks/smart.yml
@@ -1,12 +1,5 @@
- name: Install smartmontools
apt: pkg=smartmontools
-- name: Auto-enable smartmontools
- lineinfile: dest=/etc/default/smartmontools
- regexp='^(\s*#)?\s*start_smartd='
- line='start_smartd=yes'
- owner=root group=root
- mode=0644
-
- name: Start smartd
service: name=smartmontools state=started
diff --git a/roles/common/tasks/stunnel.yml b/roles/common/tasks/stunnel.yml
new file mode 100644
index 0000000..1522f1f
--- /dev/null
+++ b/roles/common/tasks/stunnel.yml
@@ -0,0 +1,16 @@
+- name: Install stunnel4
+ apt: pkg=stunnel4
+
+- name: Copy stunnel4 service files
+ copy: src=etc/systemd/system/{{ item }}
+ dest=/etc/systemd/system/{{ item }}
+ owner=root group=root
+ mode=0644
+ notify:
+ - systemctl daemon-reload
+ with_items:
+ - stunnel4.service
+ - stunnel4@.service
+
+- name: Disable stunnel4 service
+ service: name=stunnel4.service enabled=false
diff --git a/roles/common/tasks/sysctl.yml b/roles/common/tasks/sysctl.yml
index 6ac7feb..08a1b13 100644
--- a/roles/common/tasks/sysctl.yml
+++ b/roles/common/tasks/sysctl.yml
@@ -1,49 +1,48 @@
-- sysctl: name={{ item.name }} "value={{ item.value }}" sysctl_set=yes
+- sysctl: name={{ item.name }} value={{ item.value }} sysctl_set=yes
with_items:
- { name: 'kernel.domainname', value: '{{ ansible_domain }}' }
# Networking. See
# https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt
# Enable Spoof protection (reverse-path filter). Turn on Source
# Address Verification in all interfaces to prevent some spoofing
# attacks.
- { name: 'net.ipv4.conf.default.rp_filter', value: 1 }
- { name: 'net.ipv4.conf.all.rp_filter', value: 1 }
- # Enable TCP/IP SYN cookies to avoid TCP SYN flood attacks. We
- # rate-limit not only the default ICMP types 3, 4, 11 and 12
+ # Disable SYN cookies and improve SYN backlog handling, see tcp(7) and
+ # https://levelup.gitconnected.com/linux-kernel-tuning-for-high-performance-networking-high-volume-incoming-connections-196e863d458a
+ - { name: 'net.ipv4.tcp_syncookies', value: 0 }
+ - { name: 'net.ipv4.tcp_synack_retries', value: 1 }
+ - { name: 'net.ipv4.tcp_max_syn_backlog', value: 32768 }
+
+ # We rate-limit not only the default ICMP types 3, 4, 11 and 12
# (0x1818), but also types 0 and 8. See icmp(7).
- - { name: 'net.ipv4.tcp_syncookies', value: 1 }
- { name: 'net.ipv4.icmp_ratemask', value: 6425 }
- { name: 'net.ipv4.icmp_ratelimit', value: 1000 }
- # Disable paquet forwarding between interfaces (we are not a router).
+ # Disable packet forwarding between interfaces (we are not a router).
- { name: 'net.ipv4.ip_forward', value: 0 }
- { name: 'net.ipv6.conf.all.forwarding', value: 0 }
- # Enable IPv6 Privacy Extensions.
- - { name: 'net.ipv6.conf.default.use_tempaddr', value: 2 }
- - { name: 'net.ipv6.conf.all.use_tempaddr', value: 2 }
- - { name: 'net.ipv6.conf.all.autoconf', value: 0 }
-
# Do not accept ICMP redirects (prevent MITM attacks).
- { name: 'net.ipv4.conf.all.accept_redirects', value: 0 }
- { name: 'net.ipv6.conf.all.accept_redirects', value: 0 }
# Do not send ICMP redirects (we are not a router).
- { name: 'net.ipv4.conf.default.send_redirects', value: 0 }
- { name: 'net.ipv4.conf.all.send_redirects', value: 0 }
# Do not accept IP source route packets (we are not a router).
- { name: 'net.ipv4.conf.all.accept_source_route', value: 0 }
- { name: 'net.ipv6.conf.all.accept_source_route', value: 0 }
# Log Martian Packets.
- { name: 'net.ipv4.conf.all.log_martians', value: 1 }
# Ignore ICMP broadcasts.
- { name: 'net.ipv4.icmp_echo_ignore_broadcasts', value: 1 }
# Ignore bogus ICMP errors.
- { name: 'net.ipv4.icmp_ignore_bogus_error_responses', value: 1 }
diff --git a/roles/common/tasks/unbound.yml b/roles/common/tasks/unbound.yml
new file mode 100644
index 0000000..dda6769
--- /dev/null
+++ b/roles/common/tasks/unbound.yml
@@ -0,0 +1,21 @@
+- name: Install unbound
+ apt: pkg={{ packages }}
+ vars:
+ packages:
+ - unbound
+ - dns-root-data
+
+- name: Copy unbound configuration
+ template: src=templates/etc/unbound/unbound.conf.j2
+ dest=/etc/unbound/unbound.conf
+ owner=root group=root
+ mode=0644
+ register: r
+ notify:
+ - Restart unbound
+
+- name: Start unbound
+ service: name=unbound state=started
+ when: not r.changed
+
+#- meta: flush_handlers