summaryrefslogtreecommitdiffstats
path: root/roles/common
diff options
context:
space:
mode:
Diffstat (limited to 'roles/common')
-rw-r--r--roles/common/files/etc/apt/apt.conf.d/50unattended-upgrades26
-rw-r--r--roles/common/files/etc/fail2ban/action.d/nftables-allports.local6
-rw-r--r--roles/common/files/etc/fail2ban/fail2ban.local11
-rw-r--r--roles/common/files/etc/logcheck/ignore.d.server/common-local120
-rw-r--r--roles/common/files/etc/logcheck/ignore.d.server/dovecot-local30
-rw-r--r--roles/common/files/etc/logcheck/ignore.d.server/postfix-local72
-rw-r--r--roles/common/files/etc/logcheck/ignore.d.server/strongswan-local15
-rw-r--r--roles/common/files/etc/logcheck/violations.ignore.d/logcheck-sudo10
-rw-r--r--roles/common/files/etc/rkhunter.conf10
-rw-r--r--roles/common/files/etc/rsyslog.conf4
-rw-r--r--roles/common/files/etc/strongswan.d/charon.conf36
-rw-r--r--roles/common/files/etc/systemd/system/bacula-fd.service.d/override.conf (renamed from roles/common/files/etc/systemd/system/bacula-fd.service)12
-rw-r--r--roles/common/files/etc/systemd/system/fail2ban.service.d/override.conf5
-rw-r--r--roles/common/files/etc/systemd/system/munin-node.service.d/override.conf1
-rwxr-xr-xroles/common/files/usr/local/sbin/update-firewall6
-rw-r--r--roles/common/handlers/main.yml5
-rw-r--r--roles/common/tasks/bacula.yml22
-rw-r--r--roles/common/tasks/fail2ban.yml16
-rw-r--r--roles/common/tasks/ipsec.yml1
-rw-r--r--roles/common/tasks/logging.yml1
-rw-r--r--roles/common/tasks/main.yml1
-rw-r--r--roles/common/tasks/munin-node.yml30
-rw-r--r--roles/common/tasks/ntp.yml32
-rw-r--r--roles/common/tasks/smart.yml7
-rw-r--r--roles/common/tasks/sysctl.yml10
-rw-r--r--roles/common/templates/etc/apt/sources.list.j22
-rw-r--r--roles/common/templates/etc/bacula/bacula-fd.conf.j29
-rw-r--r--roles/common/templates/etc/clamav/freshclam.conf.j21
-rw-r--r--roles/common/templates/etc/fail2ban/jail.local.j24
-rw-r--r--roles/common/templates/etc/ipsec.conf.j24
-rw-r--r--roles/common/templates/etc/munin/munin-node.conf.j22
-rwxr-xr-xroles/common/templates/etc/nftables.conf.j2184
-rw-r--r--roles/common/templates/etc/ntp.conf.j212
-rw-r--r--roles/common/templates/etc/postfix/main.cf.j22
-rw-r--r--roles/common/templates/etc/postfix/master.cf.j22
-rw-r--r--roles/common/templates/etc/systemd/timesyncd.conf.d/fripost.conf.j29
-rw-r--r--roles/common/templates/etc/unbound/unbound.conf.j22
37 files changed, 456 insertions, 266 deletions
diff --git a/roles/common/files/etc/apt/apt.conf.d/50unattended-upgrades b/roles/common/files/etc/apt/apt.conf.d/50unattended-upgrades
index 02ec1e1..fd7cf1d 100644
--- a/roles/common/files/etc/apt/apt.conf.d/50unattended-upgrades
+++ b/roles/common/files/etc/apt/apt.conf.d/50unattended-upgrades
@@ -1,7 +1,7 @@
// Unattended-Upgrade::Origins-Pattern controls which packages are
// upgraded.
//
-// Lines below have the format format is "keyword=value,...". A
+// Lines below have the format "keyword=value,...". A
// package will be upgraded only if the values in its metadata match
// all the supplied keywords in a line. (In other words, omitted
// keywords are wild cards.) The keywords originate from the Release
@@ -30,6 +30,7 @@ Unattended-Upgrade::Origins-Pattern {
// "origin=Debian,codename=${distro_codename}-proposed-updates";
"origin=Debian,codename=${distro_codename},label=Debian";
"origin=Debian,codename=${distro_codename},label=Debian-Security";
+ "origin=Debian,codename=${distro_codename}-security,label=Debian-Security";
// Archive or Suite based matching:
// Note that this will silently match a different release after
@@ -92,9 +93,11 @@ Unattended-Upgrade::Package-Blacklist {
// 'mailx' must be installed. E.g. "user@example.com"
Unattended-Upgrade::Mail "admin@fripost.org";
-// Set this value to "true" to get emails only on errors. Default
-// is to always send a mail if Unattended-Upgrade::Mail is set
-//Unattended-Upgrade::MailOnlyOnError "false";
+// Set this value to one of:
+// "always", "only-on-error" or "on-change"
+// If this is not set, then any legacy MailOnlyOnError (boolean) value
+// is used to chose between "only-on-error" and "on-change"
+//Unattended-Upgrade::MailReport "on-change";
// Remove unused automatically installed kernel-related packages
// (kernel images, kernel headers and kernel version locked tools).
@@ -144,3 +147,18 @@ Acquire::http::Dl-Limit "256";
// Print debugging information both in unattended-upgrades and
// in unattended-upgrade-shutdown
// Unattended-Upgrade::Debug "false";
+
+// Allow package downgrade if Pin-Priority exceeds 1000
+// Unattended-Upgrade::Allow-downgrade "false";
+
+// When APT fails to mark a package to be upgraded or installed try adjusting
+// candidates of related packages to help APT's resolver in finding a solution
+// where the package can be upgraded or installed.
+// This is a workaround until APT's resolver is fixed to always find a
+// solution if it exists. (See Debian bug #711128.)
+// The fallback is enabled by default, except on Debian's sid release because
+// uninstallable packages are frequent there.
+// Disabling the fallback speeds up unattended-upgrades when there are
+// uninstallable packages at the expense of rarely keeping back packages which
+// could be upgraded or installed.
+// Unattended-Upgrade::Allow-APT-Mark-Fallback "true";
diff --git a/roles/common/files/etc/fail2ban/action.d/nftables-allports.local b/roles/common/files/etc/fail2ban/action.d/nftables-allports.local
index 3c8c030..3b9ebc8 100644
--- a/roles/common/files/etc/fail2ban/action.d/nftables-allports.local
+++ b/roles/common/files/etc/fail2ban/action.d/nftables-allports.local
@@ -9,8 +9,8 @@ actionunban =
[Init]
# With banaction = *-allports there is no need for separate rule names
-set_name = fail2ban
-blocktype = drop
+table = filter
+addr_set = fail2ban
[Init?family=inet6]
-set_name = fail2ban6
+addr_set = fail2ban6
diff --git a/roles/common/files/etc/fail2ban/fail2ban.local b/roles/common/files/etc/fail2ban/fail2ban.local
index 53cba35..23a92e9 100644
--- a/roles/common/files/etc/fail2ban/fail2ban.local
+++ b/roles/common/files/etc/fail2ban/fail2ban.local
@@ -1,16 +1,5 @@
[Definition]
-# Option: logtarget
-# Notes.: Set the log target. This could be a file, SYSLOG, STDERR or STDOUT.
-# Only one log target can be specified.
-# If you change logtarget from the default value and you are
-# using logrotate -- also adjust or disable rotation in the
-# corresponding configuration file
-# (e.g. /etc/logrotate.d/fail2ban on Debian systems)
-# Values: [ STDOUT | STDERR | SYSLOG | SYSOUT | FILE ] Default: STDERR
-#
-logtarget = /var/log/fail2ban/fail2ban.log
-
# Options: dbfile
# Notes.: Set the file for the fail2ban persistent data to be stored.
# A value of ":memory:" means database is only stored in memory
diff --git a/roles/common/files/etc/logcheck/ignore.d.server/common-local b/roles/common/files/etc/logcheck/ignore.d.server/common-local
index e64ec44..9b0d0fe 100644
--- a/roles/common/files/etc/logcheck/ignore.d.server/common-local
+++ b/roles/common/files/etc/logcheck/ignore.d.server/common-local
@@ -1,43 +1,60 @@
# Ansible Managed
# Do NOT edit this file directly!
#
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: subsystem request for sftp by user [-_.[:alnum:]]+$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: User [-_.[:alnum:]]+ not allowed because account is locked$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: fatal: Read from socket failed: (Connection reset by peer|Connection timed out) \[preauth\]$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: (error: )?Received disconnect from [:.[:xdigit:]]+: (3|11|14): .* \[preauth\]$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Disconnecting: Change of username or service not allowed: \(\S+\) -> (\(\S+\) )?\[preauth\]$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Disconnecting: Too many authentication failures for invalid user [-_.[:alnum:]]+ from [:.[:xdigit:]]+ port [[:digit:]]+ ssh2? \[preauth\]$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: (error: )?Received disconnect from [:.[:xdigit:]]+ port [0-9]+:(3|11|14): .* \[preauth\]$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: (Disconnected from|Connection (closed|reset) by) [[:xdigit:].:]{3,39} port [0-9]+ \[preauth\]$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: error: maximum authentication attempts exceeded for invalid user .* from [:.[:xdigit:]]+ port [0-9]+ ssh2 \[preauth\]$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: (Disconnected from|Connection (closed|reset) by)( invalid user .*)? [[:xdigit:].:]{3,39} port [0-9]+( \[preauth\])?$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: (Did not receive identification string|Invalid user .*) from [[:xdigit:].:]{3,39} port [0-9]+$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Invalid user .* from [:.[:xdigit:]]+$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: input_userauth_request: invalid user .* \[preauth\]$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: userauth_pubkey: unsupported public key algorithm: [[:alnum:]-]+ \[preauth\]$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: fatal: Write failed: (Connection (timed out|reset by peer)|Broken pipe) \[preauth\]$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: fatal: (no hostkey alg|Unable to negotiate a key exchange method) \[preauth\]$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: (Disconnected from|Connection closed by) (invalid|authenticating) user .* \[preauth\]$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Disconnecting (authenticating|invalid) user .* [[:xdigit:].:]{3,39} port [0-9]+: (Change of username or service not allowed: .* -> .*|Too many authentication failures) \[preauth\]$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: ssh_dispatch_run_fatal: Connection from (invalid user .* )?[[:xdigit:].:]{3,39} port [0-9]+: (message authentication code incorrect|Connection corrupted|Broken pipe) \[preauth\]$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Disconnected from user [a-z0-9]+ [[:xdigit:].:]{3,39} port [0-9]+$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Unable to negotiate with [:.[:xdigit:]]+ port [[:digit:]]+: no matching (host key type|key exchange method|cipher) found\. Their offer: [@.[:alnum:],-]+ \[preauth\]$
no matching cipher found: client [.@[:alnum:]-]+(,[.@[:alnum:]-]+)* server [.@[:alnum:]-]+(,[.@[:alnum:]-]+)* \[preauth\]$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Bad packet length [0-9]+\. \[preauth\]$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Bad protocol version identification '.*' from [:.[:xdigit:]]+ port [[:digit:]]+$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Accepted publickey for [^[:space:]]+ from [^[:space:]]+ port [[:digit:]]+( (ssh|ssh2))?(: (DSA|RSA|ECDSA|ED25519) ([[:xdigit:]]{2}:){15}[[:xdigit:]]{2})?$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: WARNING: no suitable primes in /etc/ssh/primes$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: dispatch_protocol_error: type [0-9]+ seq [0-9]+ \[preauth\]$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: error: Bad remote protocol version identification: '.*'$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Corrupted MAC on input\. \[preauth\]$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Protocol major versions differ for [[:xdigit:].:]{3,39} port [0-9]+: .+ vs\. .+$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: userauth_pubkey: key type [-[:alnum:]]+ not in PubkeyAcceptedKeyTypes \[preauth\]$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: error: kex_exchange_identification: Connection closed by remote host$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: error: kex_exchange_identification: read: Connection reset by peer$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: error: kex_exchange_identification: client sent invalid protocol identifier "
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: error: kex_exchange_identification: banner line contains invalid characters$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: error: send_error: write: Connection reset by peer$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: banner exchange: Connection from [[:xdigit:].:]{3,39} port [0-9]+: invalid format$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: error: beginning MaxStartups throttling$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: exited MaxStartups throttling after [0-9]{2}:[0-9]{2}:[0-9]{2}, [0-9]+ connections dropped$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: drop connection #[0-9]+ from \[[[:xdigit:].:]{3,39}\]:[0-9]+ on \[[[:xdigit:].:]{3,39}\]:[0-9]+ past MaxStartups$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: Start(ing|ed) Cleanup of Temporary Directories\.(\.\.)?$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ slapd\[[[:digit:]]+\]: connection_input: conn=[[:digit:]]+ deferring operation: binding$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (slapd\[[[:digit:]]+\]|slap(acl|add|auth|cat|dn|index)|ldap(add|compare|delete|exop|modify|modrdn|passwd|search|url|whoami)): DIGEST-MD5 common mech free$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: (Created|Removed) slice User Slice of [-[:alnum:]]+\.$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: (Created|Removed) slice User Slice of UID [-[:alnum:]]+\.$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[[0-9]+\]: (Listening on|Closed) .*\.$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: Start(ing|ed) Cleanup of Temporary Directories\.(\.\.)?$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: Starting (Cleanup of Temporary Directories|Daily man-db regeneration)\.\.\.$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: Started (Cleanup of Temporary Directories|Daily man-db regeneration)\.$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: Start(ing|ed) Session [0-9]+ of user [-[:alnum:]]+\.$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[[0-9]+\]: Startup finished in \S+\.$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd: pam_unix\(systemd-user:session\): session (opened|closed) for user [-[:alnum:]]+( by \(uid=0\))?$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[[0-9]+\]: [-[:alnum:]\\_@]+\.(mount|scope|service|socket): Succeeded\.$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd(-[a-z]+)?\[[0-9]+\]: \[/[^]]+:[0-9]+\] Line references path below legacy directory /var/run/, updating /var/run/
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: /lib/systemd/system/[-[:alnum:]\\_@]+\.service:[0-9]+: PIDFile= references path below legacy directory /var/run/, updating /var/run/
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ runuser: pam_unix\(runuser:session\): session (opened|closed) for user [-[:alnum:]]+( by \(uid=0\))?$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ CRON\[[0-9]+\]: pam_unix\(cron:session\): session (opened|closed) for user _?[-[:alnum:]]+(\(uid=[0-9]+\))?( by \(uid=0\))?$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: Start(ing|ed) Session [0-9]+ of user [-[:alnum:]]+\.$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[[0-9]+\]: Received SIGRTMIN\+24 from PID [0-9]+ \(kill\)\.$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd-logind\[[0-9]+\]: New session c?[0-9]+ of user [-[:alnum:]]+\.$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd-logind\[[0-9]+\]: Removed session c?[0-9]+\.$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd-logind\[[0-9]+\]: Session [0-9]+ logged out\. Waiting for processes to exit\.$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: apt-daily(-upgrade)?\.timer: Adding .* random time\.$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sudo:[[:space:]]+[_[:alnum:].-]+ : TTY=(unknown|(pts/|tty|vc/)[[:digit:]]+) ; PWD=[^;]+ ; USER=[._[:alnum:]-]+ (; ENV=([_a-zA-Z]+=\S* )+)?; COMMAND=(/(usr|etc|bin|sbin)/|sudoedit )
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> (bytecode|main|daily)\.(cld|cvd) (is up to date|updated) \(version: [[:digit:]]+, sigs: [[:digit:]]+, f-level: [[:digit:]]+, builder: [._[:alnum:]-]+\)$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: Starting Daily apt-listbugs preferences cleanup\.\.\.$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: Finished (Daily apt-listbugs preferences cleanup|Cleanup of Temporary Directories|Autocommit of changes in /etc directory|Clean php session files|Launch apticron to notify of packages pending an update|Online ext4 Metadata Check for All Filesystems|Autocommit of changes in /etc directory)\.$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: [[:alnum:]@-]+\.(service|scope): Consumed ([0-9]+min )?[0-9.]+s CPU time\.$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: rsyslog\.service: Sent signal SIGHUP to main process [0-9]+ \(rsyslogd\) on client request\.$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sudo:[[:space:]]+[_[:alnum:].-]+ : (TTY=(unknown|(pts/|tty|vc/)[[:digit:]]+) ; )?PWD=[^;]+ ; USER=[._[:alnum:]-]+ (; ENV=([_a-zA-Z]+=\S* )+)?; COMMAND=(/(usr|etc|bin|sbin)/|sudoedit )
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> daily database available for update \(local version: [[:digit:]]+, remote version: [[:digit:]]+\)$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> (bytecode|main|daily)\.(cld|cvd) (database )?(is up to date|is up-to-date|updated) \(version: [[:digit:]]+, sigs: [[:digit:]]+, f-level: [[:digit:]]+, builder: [._[:alnum:]-]+\)$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Testing database: '/var/lib/clamav/tmp[^/]*/clamav-.*' \.\.\.$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Database test passed\.$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Received signal: wake up$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> ClamAV update process started at \w{3} \w{3} [ :[:digit:]]{16}$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: (\w{3} \w{3} [ :[:digit:]]{16} -> \^|WARNING: )Your ClamAV installation is OUTDATED!$
@@ -45,26 +62,69 @@ no matching cipher found: client [.@[:alnum:]-]+(,[.@[:alnum:]-]+)* server [.@[:
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: WARNING: getfile: [._[:alnum:]-]+ not found on remote server \(IP: [.[:digit:]]+\)$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: WARNING: Incremental update failed, trying to download daily\.cvd$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: (WARNING|ERROR): (getpatch: )?Can't download [._[:alnum:]-]+ from [.[:alnum:]-]+$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> \*Can't query [._[:alnum:]-]+$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Downloading [._[:alnum:]-]+ \[[[:digit:]]+%\]$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> DON'T PANIC! Read https?://www\.clamav\.net/(support/faq|documents/upgrading-clamav)$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> DON'T PANIC! Read https://docs\.clamav\.net/manual/Installing\.html$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[0-9]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Database updated \([0-9]+ signatures\) from .* \(IP: [[:xdigit:].:]{3,39}\)$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[0-9]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Clamd successfully notified about the update\.$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Received signal: re-opening log file$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ clamd\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Reading databases from /var/lib/clamav$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ clamd\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> SelfCheck: Database status OK\.$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ clamd\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> SelfCheck: (Database status OK|Database modification detected\. Forcing reload)\.$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ clamd\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Database correctly reloaded \([0-9]+ signatures\)$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ clamd\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> SIGHUP caught: re-opening log file\.$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ clamd\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Activating the newly loaded database\.\.\.$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ kernel: \[ *[[:digit:]]+\.[[:digit:]]+ *\] Peer [.[:digit:]]+:[[:digit:]]+/[[:digit:]]+ unexpectedly shrunk window [[:digit:]]+:[[:digit:]]+ \(repaired\)$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ liblogging-stdlog: \[origin software="rsyslogd" swVersion="[0-9.]+" x-pid="[0-9]+" x-info="http://www\.rsyslog\.com"\] rsyslogd was HUPed$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ ansible-([_a-z0-9]+|<stdin>): Invoked with
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ rsyslogd: \[origin software="rsyslogd" swVersion="[0-9.]+" x-pid="[0-9]+" x-info="https://www\.rsyslog\.com"\] rsyslogd was HUPed$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ smartd\[[0-9]+\]: Device: /dev/sd[a-z] \[SAT\], CHECK POWER STATUS spins up disk \(0x[0-9a-f]{2} -> 0xff\)$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ ansible-([_a-z0-9.]+|<stdin>): Invoked with
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ python3\[[0-9]+\]: ansible-[_a-z0-9.]+ Invoked with
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ fail2ban-server\[[0-9]+\]: fail2ban\.filter\s*\[[0-9]+\]: INFO\s+\[[._[:alnum:]-]+\] Found [[:xdigit:].:]{3,39} -
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ fail2ban-server\[[0-9]+\]: fail2ban\.actions\s*\[[0-9]+\]: NOTICE\s+\[sshd\] (Ban|Unban) [[:xdigit:].:]{3,39}
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: notice Sympa::Request::Message::
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: info Sympa::Request::Handler::
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: notice Sympa::Bulk::store\(\)
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: notice Sympa::(Bulk|Spool)::store\(\)
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: info Sympa::Spool::_create\(\) Creating directory /var/spool/sympa/auth
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: (info|notice) Sympa::Spindle::Process(Incoming|Message|Template|Digest)::
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: info Sympa::Spindle::Do(Command|Message)::
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: info Sympa::Request::Handler::(subscribe|confirm|reject|signoff|distribute)::_twist\(\)
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: (info|notice) Sympa::Spindle::To(List|Moderation|Auth|Held)::
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: notice Sympa::Spindle::AuthorizeMessage::_twist\(\) Message Sympa::Message .* rejected\(\) because sender not allowed$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: err main::#[0-9]+ > Sympa::Spindle::spin#[0-9]+ >
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ task_manager\[[0-9]+\]: (info|notice) main::
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: info main::do_
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[[:digit:]]+\]: notice main:: \([.[:alnum:]-]+\) \[robot [.[:alnum:]-]+\] \[client [[:xdigit:].:]{3,39}\] Does NOT match HTTP_HOST; setting cookie_domain to [.[:alnum:]-]+$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[[:digit:]]+\]: notice Sympa::(Spindle::ProcessTemplate::_twist|Bulk::store)\(\)
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ bulk\[[[:digit:]]+\]: notice Sympa::(Spindle::ProcessOutgoing::_twist|Mailer::store)\(\)
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ task_manager\[[0-9]+\]: (info|notice) Sympa::(Spindle::ProcessTask|Spool)::
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: info main::
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: info Sympa::Ticket::load\(\) Ticket:
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: notice main:: Redirecting to\s
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: notice main::do_login\(\) Authentication failed$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: err main::#[0-9]+ > main::do_login#[0-9]+ > Sympa::WWW::Auth::check_auth#[0-9]+ > Sympa::WWW::Auth::authentication#[0-9]+ Incorrect password for user\s
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: notice Sympa::WWW::Tools::_get_css_url\(\) Template file /usr/share/sympa/default/web_tt2/css\.tt2 or configuration has changed; updating CSS file /var/lib/sympa/css/[.[:alnum:]-]+/style\.css$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: info Sympa::WWW::Session::new\(\) Ignoring unknown session cookie
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: err main::#[0-9]+ > main::get_parameters#[0-9]+ \[robot [.[:alnum:]-]+\] \[client [[:xdigit:].:]{3,39}\] Syntax error for parameter action value "(lists|search_list_request)#[^"]+" not conform to regexp:
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: err main::#[0-9]+ > main::check_action_parameters#[0-9]+ \[robot [.[:alnum:]-]+\] \[session [[:xdigit:]]+\] \[client [[:xdigit:].:]{3,39}\] \[list [.[:alnum:]-]+\] User not logged in$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: err main::#[0-9]+ > main::do_arc#[0-9]+ \[robot [.[:alnum:]-]+\] \[session [[:xdigit:]]+\] \[client [[:xdigit:].:]{3,39}\] \[list [.[:alnum:]-]+\] Empty archive Sympa::Archive <
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: notice Sympa::Spindle::Process(Request|Template)::_twist\(\) Processing Sympa::
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: info Sympa::Spindle::ToAuth::
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: notice Sympa::Bulk::store\(\) Message Sympa::Message::Template <
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (wwsympa|sympa_msg)\[[0-9]+\]: notice Sympa::Spool::Outgoing::store\(\) Message Sympa::Message::Template <
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: notice Sympa::Spool::store\(\) Sympa::Request <
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: info Sympa::Request::Handler::(add|signoff|subscribe)::_twist\(\)
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: info Sympa::Scenario::authz\(\) Sympa::Scenario <create_list\.[.[:alnum:]-]+;ERROR>: No rule match, reject$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: err main::#[0-9]+ > main::check_param_in#[0-9]+ > Sympa::Scenario::new#[0-9]+ Unable to find scenario file "
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: notice Sympa::Spool::Outgoing::store\(\) Message Sympa::Message <[^>]+> is stored into bulk spool as <[^>]+>$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ mysqld\[[0-9]+\]: [0-9: -]{19} [0-9]+ \[Warning\] Aborted connection [0-9]+ to db: '[^']+' user: '[^']+' host: 'localhost' \(Got (timeout|an error) reading communication packets\)$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ bulk\[[0-9]+\]: notice main:: Bulk exited normally due to signal$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ bulk\[[0-9]+\]: notice Sympa::Mailer::store\(\)
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ bulk\[[0-9]+\]: (info|notice) Sympa::Spindle::ProcessOutgoing::
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ bounced\[[0-9]+\]: notice Sympa::Tracking::store\(\) Sympa::Message <
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ bounced\[[0-9]+\]: notice Sympa::Spindle::ProcessBounce::_twist\(\)
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ bounced\[[0-9]+\]: info Sympa::Spindle::ProcessBounce::_twist\(\) No address found in message Sympa::Message <
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ archived\[[0-9]+\]: notice Sympa::Spindle::ProcessArchive::
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ archived\[[0-9]+\]: (info|notice) Sympa::Archive::
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ ikiwiki\[[[:digit:]]+\]:
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ ikiwiki: \[Fripost wiki\] (invalid page|unknown do) parameter$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ unbound: \[[0-9]+:[0-9]+\] info: generate keytag query _ta-[[:xdigit:]]+\. NULL IN$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ rrdcached\[[[:digit:]]+\]: (flushing old values|rotating journals|started new journal /\S+$|removing old journal /\S+$)
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ rrdcached\[[[:digit:]]+\]: queue_thread_main: rrd_update_r \(([^)]+)\) failed with status -1. \(opening '\1': No such file or directory\)
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ auditd\[[[:digit:]]+\]: Audit daemon rotating log files$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ stunnel(:|4\[[[:digit:]]+\]: [0-9]{4}\.[0-9]{2}\.[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}) LOG3\[[[:digit:]]+\]: SSL_accept: (Peer suddenly disconnected|[[:xdigit:]]+: error:[[:xdigit:]]+:SSL routines:SSL2?3_GET_CLIENT_HELLO:(unknown protocol|http request|no shared cipher))$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dhclient\[[[:digit:]]+\]: DHCPREQUEST for [[:digit:].]{3,15} on [[:alnum:]]+ to [[:digit:].]{3,15} port 67$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ bacula-sd\[[[:digit:]]+\]: [._[:alnum:]-]+: askdir\.c:[0-9]+-[0-9]+ Discard: JobMedia Vol=[._[:alnum:]-]+ wrote=[0-9]+ MediaId=[0-9]+ FI=[0-9]+ LI=[0-9]+ StartAddr=[0-9]+ EndAddr=[0-9]+$
diff --git a/roles/common/files/etc/logcheck/ignore.d.server/dovecot-local b/roles/common/files/etc/logcheck/ignore.d.server/dovecot-local
index 66c8101..89c4b9a 100644
--- a/roles/common/files/etc/logcheck/ignore.d.server/dovecot-local
+++ b/roles/common/files/etc/logcheck/ignore.d.server/dovecot-local
@@ -1,17 +1,23 @@
# Ansible Managed
# Do NOT edit this file directly!
#
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: imap\([-_.@[:alnum:]]+\): (Logged out|Disconnected for inactivity) in=[[:digit:]]+ out=[[:digit:]]+$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: imap\([-_.@[:alnum:]]+\): Connection closed( \(IDLE running for .*\))? in=[[:digit:]]+ out=[[:digit:]]+$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: imap-hibernate\([-_.@[:alnum:]]+\): Connection closed in=[[:digit:]]+ out=[[:digit:]]+$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (pop3|imap|managesieve)-login: Login: user=<[^>]*>, method=[[:alnum:]-]+, rip=[.:[:xdigit:]]+, lip=[.:[:xdigit:]]+, mpid=[0-9]+, (TLS|secured), session=<[^>]+>$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (pop3|imap)-login: (Aborted login|Disconnected) \(auth failed, [[:digit:]]+ attempts in [[:digit:]]+ secs\): user=<[^>]*>, method=[[:alnum:]-]+, rip=[.:[:xdigit:]]+, lip=[.:[:xdigit:]]+, (TLS(: Disconnected)?|secured), session=<[^>]+>$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (pop3|imap)-login: (Aborted login|Disconnected(: Inactivity)?) \(no auth attempts in [[:digit:]]+ secs\): user=<>, rip=[.:[:xdigit:]]+, lip=[.:[:xdigit:]]+, TLS( handshaking|: Disconnected)?(: SSL_(accept|read)\(\) syscall failed: (Connection reset by peer|Success))?, session=<[^>]+>$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (pop3|imap)-login: Disconnected(: Inactivity during authentication)? \(client didn't finish SASL auth, waited [[:digit:]]+ secs\): user=<>, method=[[:alnum:]-]+, rip=[.:[:xdigit:]]+, lip=[.:[:xdigit:]]+, TLS(: SSL_read\(\) syscall failed: Connection reset by peer)?, session=<[^>]+>$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: lmtp\([-_.@[:alnum:]]+\): [+/[:alnum:]]{22}: msgid=((\? )?<[^>]*>|unspecified): saved mail to\s
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: lmtp\([-_.@[:alnum:]]+\): [+/[:alnum:]]{22}(:[0-9]+)?: sieve: msgid=((\? )?<[^>]*>|unspecified): (stored mail into mailbox '|(forwarded|discarded duplicate forward) to <[^[:space:]]+>$|marked message to be discarded if not explicitly delivered \(discard action\)$)
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: lmtp\([^@]+@[^@]+\): [+/[:alnum:]]{22}:[0-9]+: sieve: Execution of script \S+ failed, but implicit keep was successful \(user logfile \S+ may reveal additional details\)$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (pop3|imap|managesieve)-login: Maximum number of connections from user\+IP exceeded \(mail_max_userip_connections=[[:digit:]]+\): user=<[^>]*>, method=[[:alnum:]-]+, rip=[.:[:xdigit:]]+, lip=[.:[:xdigit:]]+(, TLS, session=<[^>]+>)?$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: lmtp\([-_.@[:alnum:]]+\): Connect from local$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: lmtp\([0-9]+\): Disconnect from local: Successful quit$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: imap\([-_.@[:alnum:]]+\)<[0-9]+><[+/[:alnum:]]+>: Connection closed(: read\(size=[0-9]+\) failed: Connection reset by peer)? \((((UID )?[[:alpha:]\-]* finished [0-9.]+ secs ago|IDLE running for [^\)]+, state=wait-input|No commands sent)\))?( in=[0-9]+ out=[0-9]+ deleted=[0-9]+ expunged=[0-9]+ trashed=[0-9]+ hdr_count=[0-9]+ hdr_bytes=[0-9]+ body_count=[0-9]+ body_bytes=[0-9]+)?$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: imap\(.+\)<[0-9]+><[+/[:alnum:]]+>(: Disconnected)?(: Logged out| for inactivity( in reading our output)?|: Disconnected in [[:upper:]]+ \([0-9]+ msgs, [0-9]+ secs, [0-9]+/[0-9]+ bytes\)|: Too many invalid IMAP commands\.)?( in=[0-9]+ out=[0-9]+ deleted=[0-9]+ expunged=[0-9]+ trashed=[0-9]+ hdr_count=[0-9]+ hdr_bytes=[0-9]+ body_count=[0-9]+ body_bytes=[0-9]+)?$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: imap: Logged out in=[0-9]+ out=[0-9]+ deleted=0 expunged=0 trashed=0 hdr_count=0 hdr_bytes=0 body_count=0 body_bytes=0$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: imap\([-_.@[:alnum:]]+\)<[0-9]+><[+/[:alnum:]]+>: Connection closed(: (read\(size=[0-9]+\) failed: )?Connection reset by peer)?( \((LOGOUT,)?(UID )?[[:alpha:]\-]+ (running for|finished) [^\)]+\))? in=[0-9]+ out=[0-9]+ deleted=[0-9]+ expunged=[0-9]+ trashed=[0-9]+ hdr_count=[0-9]+ hdr_bytes=[0-9]+ body_count=[0-9]+ body_bytes=[0-9]+$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: imap-hibernate\([-_.@[:alnum:]]+\)<[0-9]+><[+/[:alnum:]]+>: Connection closed in=[0-9]+ out=[0-9]+ deleted=[0-9]+ expunged=[0-9]+ trashed=[0-9]+ hdr_count=[0-9]+ hdr_bytes=[0-9]+ body_count=[0-9]+ body_bytes=[0-9]+$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (pop3|imap|managesieve)-login: Login: user=<[^>]*>, method=[[:alnum:]-]+, rip=[[:xdigit:].:]{3,39}, lip=[[:xdigit:].:]{3,39}, mpid=[0-9]+, (TLS|secured)(: (read\(size=[0-9]+\) failed: )?Connection (closed|reset by peer))?, session=<[^>]+>$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: managesieve\([-_.@[:alnum:]]+\)<[0-9]+><[+/[:alnum:]]+>: Disconnected: Logged out bytes=[[:digit:]]+/[[:digit:]]+$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (imap|managesieve)-login: (Disconnected(: Inactivity)?|Aborted login) \(auth failed, [[:digit:]]+ attempts in [[:digit:]]+ secs\): user=<[^>]*>, method=[A-Z\-]+, rip=[[:xdigit:].:]{3,39}, lip=[[:xdigit:].:]{3,39}, (TLS|SSL|secured)(: (Disconnected|Connection closed))?, session=<[^>]*>$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (imap|managesieve)-login: Disconnected \((no auth attempts in|disconnected before auth was ready, waited) [[:digit:]]+ secs\):( user=<>,)? rip=[[:xdigit:].:]{3,39}, lip=[[:xdigit:].:]{3,39}, (TLS|SSL)( handshaking)?: (SSL_accept\(\)( syscall)? failed:|(read\(size=[0-9]+\) failed: )?Connection (closed|reset by peer), session=<[+/[:alnum:]]+>$|SSL_read failed: error:[[:xdigit:]]+:SSL routines:(ssl3_get_record:decryption failed or bad record mac|ssl3_read_bytes:unexpected record), session=<[+/[:alnum:]]+>$)
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (imap|managesieve)-login: (Disconnected(: (Inactivity|Too many invalid commands\.?))?|Aborted login) \(no auth attempts in [[:digit:]]+ secs\):( user=<>,)? rip=[[:xdigit:].:]{3,39}, lip=[[:xdigit:].:]{3,39}(, (TLS|SSL)( handshaking)?)?, session=<[+/[:alnum:]]+>$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (pop3|imap)-login: Disconnected(: Inactivity during authentication)? \(client didn't finish SASL auth, waited [[:digit:]]+ secs\): user=<>, method=[[:alnum:]-]+, rip=[[:xdigit:].:]{3,39}, lip=[[:xdigit:].:]{3,39}, TLS(: (read\(size=[0-9]+\) failed: Connection reset by peer|Disconnected|Connection closed))?, session=<[^>]+>$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: lmtp\([-_.@[:alnum:]]+\)<[0-9]+><[+/[:alnum:]]{22}(:[0-9]+)?>: msgid=(\? )?(<[^>]*>|[^[:blank:]]*|[^,()]+@[.[:alnum:]-]+)( \(added by \S+@[.[:alnum:]-]+\))?: saved mail to\s
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: lmtp\([-_.@[:alnum:]]+\)<[0-9]+><[+/[:alnum:]]{22}(:[0-9]+)?>: sieve: msgid=(\? )?(<[^>]*>\s*|[^[:blank:]]*|[^,()]+@[.[:alnum:]-]+)( \(added by \S+@[.[:alnum:]-]+\))?: (stored mail into mailbox '|(forwarded|discarded duplicate forward) to <[^[:space:]]+>$|marked message to be discarded if not explicitly delivered \(discard action\)$)
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: lmtp\([^@]+@[^@]+\)<[0-9]+><[+/[:alnum:]]{22}(:[0-9]+)?>: sieve: Execution of script \S+ failed, but implicit keep was successful \(user logfile \S+ may reveal additional details\)$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (pop3|imap|managesieve)-login: Maximum number of connections from user\+IP exceeded \(mail_max_userip_connections=[[:digit:]]+\): user=<[^>]*>, method=[[:alnum:]-]+, rip=[[:xdigit:].:]{3,39}, lip=[[:xdigit:].:]{3,39}(, TLS, session=<[^>]+>)?$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: lmtp\([0-9]+\): Disconnect from local: (Client has quit the connection|Remote closed connection) \(state=[[:upper:]]+\)$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: auth: Warning: auth client [0-9]+ disconnected with [0-9]+ pending requests: (Connection reset by peer|EOF)$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: stats: Warning: UPDATE-CMD: Already expired$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: Start(ing|ed) Dovecot authentication proxy\.(\.\.)?$
diff --git a/roles/common/files/etc/logcheck/ignore.d.server/postfix-local b/roles/common/files/etc/logcheck/ignore.d.server/postfix-local
index f539c3a..cffb438 100644
--- a/roles/common/files/etc/logcheck/ignore.d.server/postfix-local
+++ b/roles/common/files/etc/logcheck/ignore.d.server/postfix-local
@@ -13,37 +13,43 @@
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/scache\[[[:digit:]]+\]: statistics: (domain|address) lookup hits=[[:digit:]]+ miss=[[:digit:]]+ success=[[:digit:]]+%$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/scache\[[[:digit:]]+\]: statistics: max simultaneous domains=[[:digit:]]+ addresses=[[:digit:]]+ connection=[[:digit:]]+$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/smtpd\[[[:digit:]]+\]: [[:xdigit:]]+: client=[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/cleanup\[[[:digit:]]+\]: [[:xdigit:]]+: (resent-)?message-id=([^[:blank:]]*|(mid:)?[[:alnum:]_/+.$@-]+)( \(added by [^[:space:]]+\))?$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/cleanup\[[[:digit:]]+\]: [[:xdigit:]]+: (resent-)?message-id=([^[:blank:]]*|(mid:)?[[:alnum:]_/+.$@-]+|[^,()]+@[.[:alnum:]-]+)( \(added by [^[:space:]]+\))?$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/cleanup\[[[:digit:]]+\]: warning: unix_trigger_event: read timeout for service public/qmgr$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/cleanup\[[[:digit:]]+\]: warning: milter unix:public/opendmarc: can't read SMFIC_BODYEOB reply packet header: Success$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/qmgr\[[[:digit:]]+\]: [[:xdigit:]]+: from=<[^>]*>, size=[[:digit:]]+, nrcpt=[[:digit:]]+ \(queue active\)$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/n?qmgr\[[[:digit:]]+\]: [[:xdigit:]]+: from=<[^>]*>, status=expired, returned to sender$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/n?qmgr\[[[:digit:]]+\]: [[:xdigit:]]+: message-id=(<[^>]*>|[[:alnum:]_/+.$@-]+)( \(added by [^[:space:]]+\))?
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/n?qmgr\[[[:digit:]]+\]: [[:xdigit:]]+: removed$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/n?qmgr\[[[:digit:]]+\]: [[:xdigit:]]+: skipped, still being delivered$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/verify\[[[:digit:]]+\]: cache [a-z]+:\S+ (partial|full) cleanup: retained=[[:digit:]]+ dropped=[[:digit:]]+ entries$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/smtpd\[[[:digit:]]+\]: disconnect from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]( (ehlo|helo|xforward|starttls|auth|mail|rcpt|data|noop|rset|quit|commands|unknown)=[0-9]+(/[0-9]+)?)+$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/smtpd\[[[:digit:]]+\]: disconnect from [._[:alnum:]-]+\[([[:xdigit:].:]{3,39}|unknown)\]( (ehlo|helo|xforward|starttls|auth|mail|rcpt|data|bdat|noop|rset|quit|commands|unknown)=[0-9]+(/[0-9]+)?)+$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: warning: non-SMTP command from [-._[:alnum:]]+\[[[:xdigit:].:]{3,39}\]:\s
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/pickup\[[[:digit:]]+\]: [[:xdigit:]]+: uid=[[:digit:]]+ from=<[^>]*>$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/cleanup\[[[:digit:]]+\]: [[:xdigit:]]+: replace: header\s
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: [[:xdigit:]]+: client=[^[:space:]]+, sasl_method=[-[:alnum:]]+, sasl_username=[-_.@[:alnum:]]+(, sasl_sender=[-_.@[:alnum:]]+)?$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: warning: [-._[:alnum:]]+\[[[:xdigit:].:]{3,39}\]: SASL (PLAIN|LOGIN) authentication (failed|aborted)(:[ [:alnum:]]*)?$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: improper command pipelining after (EHLO|HELO|MAIL|QUIT) from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]:
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: warning: [-._[:alnum:]]+\[[[:xdigit:].:]{3,39}\]: SASL [[:alpha:]]+ authentication (failed|aborted)(:[ [:alnum:]]*)?$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: improper command pipelining after (EHLO|HELO|AUTH|MAIL|QUIT) from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]:
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: warning: hostname [._[:alnum:]-]+ does not resolve to address [[:xdigit:].:]{3,39}(: Name or service not known)?$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: warning: Connection concurrency limit exceeded: [0-9]+ from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\] for service (submissions?|smtpd)$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 5[[:digit:]]{2} 5(\.[[:digit:]]){2} <[^>]+>: Helo command rejected: need fully-qualified hostname;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^>]+>)?$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 4[[:digit:]]{2} 4(\.[[:digit:]]){2} <[^>]+>: Sender address rejected: Domain not found;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^>]+>)?$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 5[[:digit:]]{2} 5(\.[[:digit:]]){2} Service unavailable; (Unverified Client host|Sender address) \[\S+\] blocked using [._[:alnum:]-]+; https?://[^[:blank:];]+; from=<[^>]*> to=<[^>]+> proto=E?SMTP( helo=<[^>]+>)?$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 5[[:digit:]]{2} 5(\.[[:digit:]]+){2} <[^>]+>: Helo command rejected: need fully-qualified hostname;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^>]+>)?$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 4[[:digit:]]{2} 4(\.[[:digit:]]+){2} <[^>]+>: Sender address rejected: (Domain not found|Malformed DNS server reply);( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^>]+>)?$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 5[[:digit:]]{2} 5(\.[[:digit:]]+){2} <[^>]+>: Sender address rejected: Domain [.[:alnum:]-]+ does not accept mail \(nullMX\);( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^>]+>)?$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 5[[:digit:]]{2} 5(\.[[:digit:]]+){2} Service unavailable; (Unverified Client host|Sender address) \[\S+\] blocked using [._[:alnum:]-]+(; https?://[^[:blank:];]+)?; from=<[^>]*> to=<[^>]+> proto=E?SMTP( helo=<[^>]+>)?$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[([[:xdigit:].:]{3,39})\]: 4[[:digit:]]{2} 4(\.[[:digit:]]+){2} Client host rejected: cannot find your hostname, \[\1\]; from=<[^>]*> to=<[^>]+> proto=E?SMTP( helo=<[^>]+>)?$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: timeout after [-[:upper:]]+( \([[:digit:]]+ bytes\))? from [^[:space:]]+$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-((msa|mx)/smtpd|out/smtp)\[[[:digit:]]+\]: warning: (tls_text_name: [-._[:alnum:]]+\[[[:xdigit:].:]{3,39}\]: )?peer certificate has no (subject CN|issuer Organization)$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: [[:upper:]]+ from [^[:space:]]+: 450( 4\.1\.2)? <[^>]*>: Recipient address rejected: Domain not found;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: [[:upper:]]+ from [^[:space:]]+: 450( 4\.1\.8)? <[^>]*>: Sender address rejected: Domain not found;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: [[:upper:]]+ from [^[:space:]]+: 554( 5\.7\.1)? <>: Sender address rejected: Null sender not allowed; from=<> to=<[^>]+> proto=E?SMTP( helo=<[^[:space:]]+>)?$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: [[:upper:]]+ from [^[:space:]]+: 5[[:digit:]]{2} 5(\.[[:digit:]]){2} <[^>]*>: (Recipient|Sender) address rejected: need fully-qualified address;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: [[:upper:]]+ from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 550( 5\.7\.23)? <[^>]+>: Sender address rejected: Message rejected due to: (domain owner discourages use of this host|SPF fail - not authorized)\. Please see https?://www\.openspf\.net/Why\?\S+; from=<[^>]+> to=<[^>]+> proto=E?SMTP( helo=<[^[:space:]]+>)?$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ policyd-spf\[[[:digit:]]+\]: 550( 5\.7\.23)? Message rejected due to: (domain owner discourages use of this host|SPF fail - not authorized)\. Please see https?://www\.openspf\.net/Why\?\S+$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: [[:upper:]]+ from [^[:space:]]+: 5[[:digit:]]{2} 5(\.[[:digit:]]+){2} <[^>]*>: (Recipient|Sender) address rejected: need fully-qualified address;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 554 5\.7\.1 <[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]>: Client host rejected: Access denied;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mda/lmtp\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^>]+>,( orig_to=<[^>]+>,)? relay=[._[:alnum:]-]+\[private/dovecot-lmtpd\],( conn_use=[[:digit:]]+,)? delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=2(\.[[:digit:]]+){2})?, status=sent \(2[[:digit:]][[:digit:]] .+\)$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-\w+/(error|n?qmgr|smtp)\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^>]+>,( orig_to=<[^>]+>,)? relay=(none|[^[:space:]]+\[[[:xdigit:].:]{3,39}\]:[[:digit:]]+),( conn_use=[[:digit:]]+,)? delay=[[:digit:].]+,( delays=[[:digit:]./]+,)?( dsn=[45]\.[[:digit:]]\.[[:digit:]],)? status=(deferred|undeliverable|bounced) \((delivery temporarily suspended: )?((lost connection with [^[:space:]]+|conversation with [^[:space:]]+ timed out) while (sending [[:alnum:]]+( [[:alnum:]]+)?|performing the (HELO|EHLO) handshake|receiving the initial server greeting|sending [[:alnum:]]+( [/[:alnum:]]+)?|sending end of data -- message may be sent more than once)|connect to [^[:space:]]+: (Connection timed out|read timeout|Connection refused|Network is unreachable|No route to host)|host [^[:space:]]+ refused to talk to me: [45][[:digit:]][[:digit:]].*|Host or domain name not found. Name service error for name=[^[:space:]]+ type=(MX|A|AAAA): Host (not found, try again|found but no data record of requested type)|User unknown in virtual alias table|host [^[:space:]]+\[[[:xdigit:].:]{3,39}\] said: [45][[:digit:]][[:digit:]] [45](\.[[:digit:]]+){2} <[^>]+>: (Temporarily rejected\. Try again later\.|Recipient address rejected: ((undeliverable|unverified) address:|Domain not found)) .*)\)$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^>]+>,( orig_to=<[^>]+>,)? relay=[^[:space:]]+\[[[:xdigit:].:]{3,39}\]:[[:digit:]]+,( conn_use=[[:digit:]]+,)? delay=[[:digit:].]+,( delays=[[:digit:]./]+,)?( dsn=[45]\.[[:digit:]]\.[[:digit:]],)? status=undeliverable \(host
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: host [^[:space:]]+\[[[:xdigit:].:]{3,39}\]( said: 45[01] .* \(in reply to RCPT TO command\)| refused to talk to me: 421 )
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: lost connection with [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\] while (receiving the initial server greeting|sending [[:upper:] ]+|performing the HELO handshake|sending end of data -- message may be sent more than once)$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: host [^[:space:]]+\[[[:xdigit:].:]{3,39}\]( said: 45[01][ -].* \(in reply to (MAIL FROM|RCPT TO) command\)| refused to talk to me: (421|450) )
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(out|msa)/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: lost connection with [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\] while (receiving the initial server greeting|sending [[:upper:] ]+|performing the HELO handshake|sending end of data -- message may be sent more than once)$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: conversation with [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\] timed out while (sending message body|receiving the initial server greeting)$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^>]+>(, orig_to=<[^>]+>)?, relay=[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\](:[[:digit:]]{1,5})?,( conn_use=[[:digit:]]+,)? delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=[45](\.[[:digit:]]+){2})?, status=(deferred|bounced|undeliverable|SOFTBOUNCE) \(host [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\] said: [45][[:digit:]][[:digit:]][- ]+.* \(in reply to (HELO|EHLO|MAIL FROM|RCPT TO|DATA|end of DATA) command\)\)$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: connect to [^[:space:]]+: (read timeout|Connection (refused|timed out)|Network is unreachable|No route to host)( \(port [[:digit:]]+\))?$
@@ -52,10 +58,11 @@
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mda|out|lists)/smtpd\[[[:digit:]]+\]: [[:xdigit:]]+: client=[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\], orig_queue_id=[[:xdigit:]]+, orig_client=[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [A-Z[:digit:]]+: to=<[^>]+>,( orig_to=<[^>]+>,) relay=[^[:space:]]+, delay=[[:digit:]]+, status=deferred \(host [^[:space:]]+ said: [45][[:digit:]]{2} <[^[:space:]]*>: Recipient address rejected: Greylisted for [[:digit:]]+ (seconds|minutes)(\(see http://isg.ee.ethz.ch/tools/postgrey/help/[.[:alnum:]-]+.html\))? \(in reply to (HELO|EHLO|MAIL FROM|RCPT TO|DATA|end of DATA) command\)\)$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: to=<.*>,( orig_to=<[^>]+>,)? relay=[^[:space:]]+\](:[[:digit:]]+)?,( conn_use=[[:digit:]]+,)? delay=[[:digit:].]+,( delays=[[:digit:]./]+,)?( dsn=4\.[[:digit:]]\.[[:digit:]],)? status=deferred \(host [^[:space:]]+\] said: .*$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mda|out)/smtpd?\[[[:digit:]]+\]: warning: numeric domain name in resource data of MX record for [._[:alnum:]-]+: [[:xdigit:].:]{3,39}$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mda|out|mx)/smtpd?\[[[:digit:]]+\]: warning: valid_hostname: numeric hostname: [0-9]+$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mda|out|mx)/smtpd?\[[[:digit:]]+\]: warning: (malformed|numeric) domain name in resource data of MX record for [._[:alnum:]-]+:\s
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: warning: no MX host for [._[:alnum:]-]+ has a valid address record$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/smtpd\[[[:digit:]]+\]: SSL_accept error from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: (lost connection|Connection reset by peer|-?[[:digit:]]+|Connection timed out)$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:SSL3_READ_BYTES:(sslv3|tlsv1) alert (unknown ca|certificate unknown):s3_pkt.c:[0-9]+:SSL alert number [[:digit:]]+:$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/smtpd\[[[:digit:]]+\]: SSL_accept error from [._[:alnum:]-]+\[([[:xdigit:].:]{3,39}|unknown)\]: (lost connection|Connection reset by peer|-?[[:digit:]]+|Connection timed out|Broken pipe)$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:SSL3_READ_BYTES:(sslv3|tlsv1) alert (unknown ca|certificate unknown):s3_pkt\.c:[0-9]+:SSL alert number [[:digit:]]+:$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(out|mx)/bounce\[[[:digit:]]+\]: [[:xdigit:]]+: sender (delay|non-delivery|delivery status) notification: [[:xdigit:]]+$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: host [^[:space:]]+ refused to talk to me: [45][[:digit:]][[:digit:]].*$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: enabling PIX <CRLF>\.<CRLF> workaround for [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\](:[[:digit:]]{1,5})?$
@@ -64,20 +71,23 @@
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: SSL_connect error to [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]:[[:digit:]]+: -?[[:digit:]]+$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:SSL2?3_CHECK_CERT_AND_ALGORITHM:dh key too small:s2?3_clnt\.c:[0-9]+:$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: Cannot start TLS: handshake failure$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/tlsproxy\[[[:digit:]]+\]: TLS handshake failed for service=smtpd peer=\[[[:xdigit:].:]{3,39}\]:[0-9]+$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: Host offered STARTTLS: \[[._[:alnum:]-]+\]$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: [[:xdigit:]]+: reject: RCPT from [^[:space:]]+: 4[[:digit:]][[:digit:]]( 4(\.[[:digit:]]){2}) <[^[:space:]]*>: Recipient address rejected: Greylisted( for [[:digit:]]+ (second|minute)s)?, see https?://[-_.:/[:alnum:]]+\.html?; from=<[^>]*> to=<[^>]+> proto=E?SMTP helo=<[^[:space:]]+>$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: [[:xdigit:]]+: reject: RCPT from [^[:space:]]+: 4[[:digit:]][[:digit:]]( 4(\.[[:digit:]]+){2}) <[^[:space:]]*>: Recipient address rejected: Greylisted( for [[:digit:]]+ (second|minute)s)?, see https?://[-_.:/[:alnum:]]+\.html?; from=<[^>]*> to=<[^>]+> proto=E?SMTP helo=<[^[:space:]]+>$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-\w+/smtpd\[[[:digit:]]+\]: lost connection after [[:upper:]]+( \([[:digit:]]+ bytes\))? from [._[:alnum:]-]+\[(unknown|[[:xdigit:].:]{3,39})\]$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: [[:xdigit:]]+: reject: (CONNECT|RCPT) from [^[:space:]]+: [45][[:digit:]][[:digit:]]( [45](\.[[:digit:]]){2})? Service unavailable; Client host \[([[:xdigit:].:]{3,39}|[-._[:alnum:]]+)\] blocked using [._[:alnum:]-]+;( .+;)? (from=<[^>]*> to=<[^>]+> )?proto=E?SMTP( helo=<[^[:space:]]+>)?$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: RCPT from [^[:space:]]+: [[:digit:]]{3}( [45](\.[[:digit:]]){2})? <[^[:space:]]*>: Relay access denied; from=<[^>]*> to=<[^>]+> proto=E?SMTP helo=<[^[:space:]]+>$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: [[:xdigit:]]+: reject: (CONNECT|RCPT) from [^[:space:]]+: [45][[:digit:]][[:digit:]]( [45](\.[[:digit:]]+){2})? Service unavailable; Client host \[([[:xdigit:].:]{3,39}|[-._[:alnum:]]+)\] blocked using [._[:alnum:]-]+;( .+;)? (from=<[^>]*> to=<[^>]+> )?proto=E?SMTP( helo=<[^[:space:]]+>)?$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: RCPT from [^[:space:]]+: [[:digit:]]{3}( [45](\.[[:digit:]]+){2})? <[^[:space:]]*>: Relay access denied; from=<[^>]*> to=<[^>]+> proto=E?SMTP helo=<[^[:space:]]+>$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: warning: ([-._[:alnum:]]+): RBL lookup error: Host or domain name not found\. Name service error for name=\1 type=A(AAA)?: Host not found, try again$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mx|msa)/(smtpd|tlsproxy)\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:SSL2?3_(GET_RECORD:(decryption failed or bad record mac|wrong version number):s3_pkt\.c:[0-9]+:|READ_BYTES:(reason\([[:digit:]]+\)|sslv3 alert (unexpected message|bad certificate)):s3_pkt\.c:[[:digit:]]+:SSL alert number (0|10|42):|GET_CLIENT_HELLO:(unsupported protocol|no shared cipher|unknown protocol|wrong version number):s2?3_srvr\.c:[0-9]+:)$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/tlsproxy\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:tls_post_process_client_hello:no shared cipher:\.\./ssl/statem/statem_srvr\.c:[0-9]+:$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:tls_process_client_hello:(no shared cipher|unknown protocol|version too low):\.\./ssl/statem/statem_srvr\.c:[0-9]+:$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: [[:upper:]]+ from [^[:space:]]+: 554( 5\.1\.[01])? <[^[:space:]]*>: Recipient address rejected: User unknown in virtual alias table;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: [[:xdigit:]]+: reject: RCPT from [^[:space:]]+: [45][[:digit:]][[:digit:]]( [45](\.[[:digit:]]){2})? <[^[:space:]]*>: Helo command rejected: .+; from=<[^>]*> to=<[^>]+> proto=E?SMTP helo=<[^[:space:]]+>$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mx|msa)/(smtpd|tlsproxy)\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:(ssl3_get_record:(wrong version number|http request|packet length too long|bad record type)|tls_post_process_client_hello:no shared cipher):
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mx|msa)/(smtpd|tlsproxy)\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:ssl3_read_bytes:(sslv3 alert bad certificate|unexpected record|tlsv1 alert user cancelled):
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mx|msa)/(smtpd|tlsproxy)\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:tls_parse_ctos_key_share:bad key share:
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/(smtpd|tlsproxy)\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:tls_((early_)?post_)?process_client_hello:(no shared cipher|unknown protocol|unsupported protocol|version too low):\.\./ssl/statem/statem_srvr\.c:[0-9]+:$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: [[:upper:]]+ from [^[:space:]]+: 55[0-9]( 5\.1\.[01])? <[^[:space:]]*>: Recipient address rejected: User unknown in virtual alias table;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: [[:xdigit:]]+: reject: RCPT from [^[:space:]]+: [45][[:digit:]][[:digit:]]( [45](\.[[:digit:]]+){2})? <[^[:space:]]*>: Helo command rejected: .+; from=<[^>]*> to=<[^>]+> proto=E?SMTP helo=<[^[:space:]]+>$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: too many errors after ([[:upper:]]{4}|END-OF-MESSAGE|UNKNOWN|DATA \(0 bytes\)) from [._[:alnum:]-]+\[[.[:digit:]]+\]$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mx|msa)/smtpd\[[[:digit:]]+\]: warning: hostname [^[:space:]]+ does not resolve to address [[:xdigit:].:]{3,39}: (No address associated with hostname|Temporary failure in name resolution)$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: warning: (numeric hostname: [[:xdigit:].:]{3,39}|valid_hostname: misplaced delimiter: \S)$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mx|msa)/smtpd\[[[:digit:]]+\]: warning: (numeric hostname: [[:xdigit:].:]{3,39}|valid_hostname: misplaced delimiter: \S)$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mx|lists)/pipe\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^>]+>,( orig_to=<[^>]+>,)* relay=([-_.[:alnum:]]+), delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=2(\.[[:digit:]]+){2})?, status=sent \(delivered via \3 service\)$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/discard\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^>]+>,( orig_to=<[^>]+>,)* relay=none, delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=2(\.[[:digit:]]+){2})?, status=sent \(discard\.fripost\.org\)$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mx|msa)/smtpd\[[[:digit:]]+\]: warning: Illegal address syntax from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\] in (MAIL|RCPT) command:\s
@@ -90,10 +100,11 @@
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: NON-SMTP COMMAND from \[[[:xdigit:].:]{3,39}\]:[[:digit:]]+\s
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: COMMAND PIPELINING from \[[[:xdigit:].:]{3,39}\]:[[:digit:]]+ after\s
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: DNSBL rank [[:digit:]]+ for \[[[:xdigit:].:]{3,39}\]:[[:digit:]]+$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from (\[[[:xdigit:].:]{3,39}\]):[[:digit:]]+: [45][[:digit:]][[:digit:]]( [45](\.[[:digit:]]){2})? (Service unavailable; client \1 blocked using [._[:alnum:]-]+|Protocol error|Service currently unavailable);( .+;)? (from=<[^>]*>, to=<[^>]+>, )?proto=E?SMTP(, helo=<[^[:space:]]+>)?$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: [[:upper:]]+ without valid RCPT from \[[[:xdigit:].:]{3,39}\]:[[:digit:]]+$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from (\[[[:xdigit:].:]{3,39}\]):[[:digit:]]+: [45][[:digit:]][[:digit:]]( [45](\.[[:digit:]]+){2})? (Service unavailable; client \1 blocked using [._[:alnum:]-]+|Protocol error|Service currently unavailable);( .+;)? (from=<[^>]*>, to=<[^>]+>, )?proto=E?SMTP(, helo=<[^[:space:]]+>)?$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: NOQUEUE: reject: CONNECT from \[[[:xdigit:].:]{3,39}\]:[[:digit:]]+: too many connections$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: COMMAND (COUNT|TIME) LIMIT from \[[[:xdigit:].:]{3,39}\]:[[:digit:]]+( after [[:upper:]]+)?$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: cache [a-z]+:\S+ full cleanup: retained=[[:digit:]]+ dropped=[[:digit:]]+ entries$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: cache [a-z]+:\S+ (partial|full) cleanup: retained=[[:digit:]]+ dropped=[[:digit:]]+ entries$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: warning: getpeername: Transport endpoint is not connected -- dropping this connection$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: warning: psc_cache_update: lmdb:/var/lib/postfix-mx/postscreen_cache update average delay is [[:digit:]]+ ms$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: warning: dnsblog reply timeout [[:digit:]]+s for [._[:alnum:]-]+$
@@ -104,8 +115,19 @@
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: Start(ing|ed) Postfix sender login socketmap\.(\.\.)?$
#
# Amavis
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ amavis\[[[:digit:]]+\]: \([-[:digit:]]+\) Passed (CLEAN|SPAM|UNCHECKED(-[A-Z]+)?|BAD-HEADER-[28]) {Relayed(Tagged)?(Internal|Inbound|Outbound)}, (INCOMING|OUTGOING)( LOCAL)? \[(IPv6:)?[[:xdigit:].:]{3,39}\](:[[:digit:]]+)?( \[[[:xdigit:].:]{3,39}\])? <[^>]*> -> (<[^>]*>,)+( Queue-ID: [[:xdigit:]]+,)?( Message-ID: <[^>]+>,)?( Resent-Message-ID: <[^>]+>,)? mail_id: [_-+[:alnum:]]+, Hits: -?[[:digit:].]*, size: [[:digit:]]+, queued_as: [[:xdigit:]]+(, dkim_(new|sd)?=[-_.,:[:alnum:]]+)?, [[:digit:]]+ ms$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ amavis\[[[:digit:]]+\]: \([-[:digit:]]+\) Passed (CLEAN|SPAM|UNCHECKED(-[A-Z]+)?|BAD-HEADER-[28]) {Relayed(Tagged)?(Internal|Inbound|Outbound)}, (INCOMING|OUTGOING)( LOCAL)? \[(IPv6:)?[[:xdigit:].:]{3,39}\](:[[:digit:]]+)?( \[[[:xdigit:].:]{3,39}\])? <[^>]*> -> (<[^>]*>,)+( Queue-ID: [[:xdigit:]]+,)?( Message-ID: <[^>]+>,)?( Resent-Message-ID: <[^>]+>,)? mail_id: [-_+[:alnum:]]+, Hits: -?[[:digit:].]*, size: [[:digit:]]+, queued_as: [[:xdigit:]]+(, dkim_(new|sd)?=[-_.,:[:alnum:]]+)?, [[:digit:]]+ ms$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ amavis\[[[:digit:]]+\]: \([-[:digit:]]+\) Passed (CLEAN|SPAM|UNCHECKED(-[A-Z]+)?|BAD-HEADER-[28]) {Relayed(Tagged)?(Internal|Inbound|Outbound)}, (INCOMING|OUTGOING)( LOCAL)? \[(IPv6:)?[[:xdigit:].:]{3,39}\](:[[:digit:]]+)?( \[[[:xdigit:].:]{3,39}\])? <[^>]*> -> (<[^>]*>,)*(<[^>]*)?\.\.\.$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ amavis\[[[:digit:]]+\]: \([-[:digit:]]+\) \.\.\.([^>]*>)?(,<[^>]*>)*,( Queue-ID: [[:xdigit:]]+,)?( Message-ID: <[^>]+>,)?( Resent-Message-ID: <[^>]+>,)? mail_id: [_-+[:alnum:]]+, Hits: -?[[:digit:].]*, size: [[:digit:]]+, queued_as: [[:xdigit:]]+(, dkim_(new|sd)?=[-_.,:[:alnum:]]+)?, [[:digit:]]+ ms$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ amavis\[[[:digit:]]+\]: \([-[:digit:]]+\) \.\.\.([^>]*>)?(,<[^>]*>)*,( Queue-ID: [[:xdigit:]]+,)?( Message-ID: <[^>]+>,)?( Resent-Message-ID: <[^>]+>,)? mail_id: [-_+[:alnum:]]+, Hits: -?[[:digit:].]*, size: [[:digit:]]+, queued_as: [[:xdigit:]]+(, dkim_(new|sd)?=[-_.,:[:alnum:]]+)?, [[:digit:]]+ ms$
# SMTP client connection caching was introduced in 2.6.0; the SMTP session is held for the next task, and is terminated by Postfix if the next mail comes soon enough
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtpd\[[[:digit:]]+\]: timeout after END-OF-MESSAGE from [._[:alnum:]-]+\[(127.0.0.1|::1)\]$
+#
+# OpenDMARC
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ opendmarc\[[0-9]+\]: implicit authentication service: [-_.[:alnum:]]+\.fripost\.org$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ opendmarc\[[0-9]+\]: [[:xdigit:]]+: RFC5322 requirement error: (not exactly one Date field|multiple Message-Id fields)$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ opendmarc\[[0-9]+\]: [[:xdigit:]]+: unable to parse From header field$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ opendmarc\[[0-9]+\]: [[:xdigit:]]+:? ignoring Authentication-Results at\s
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ opendmarc\[[0-9]+\]: [[:xdigit:]]+: ignoring invalid ARC-Authentication-Results header ".*"
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ opendmarc\[[0-9]+\]: [[:xdigit:]]+: SPF\((mailfrom|helo)\): \S+ (none|tempfail|fail|pass)$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ opendmarc\[[0-9]+\]: [[:xdigit:]]+: [-_.[:alnum:]]+ (none|fail|pass)$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ opendmarc\[[0-9]+\]: [[:xdigit:]]+: opendmarc_policy_query_dmarc\([._[:alnum:]-]+\) returned status 4$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ opendmarc\[[0-9]+\]: opendmarc: opendmarc-arcares\.c:[0-9]+: opendmarc_arcares_strip_whitespace: Assertion `.*' failed\.$
diff --git a/roles/common/files/etc/logcheck/ignore.d.server/strongswan-local b/roles/common/files/etc/logcheck/ignore.d.server/strongswan-local
index cebfaba..e78e9f0 100644
--- a/roles/common/files/etc/logcheck/ignore.d.server/strongswan-local
+++ b/roles/common/files/etc/logcheck/ignore.d.server/strongswan-local
@@ -3,17 +3,22 @@
#
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[KNL\] creating acquire job for policy [[:xdigit:].:]{3,39}/[[:digit:]]+(\[\w+(/[[:alnum:]-]+)?\])? === [[:xdigit:].:]{3,39}/[[:digit:]]+(\[\w+(/[[:alnum:]-]+)?\])? with reqid \{[[:digit:]]+\}$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[KNL\] creating rekey job for CHILD_SA ESP/0x[[:xdigit:]]{8}/[[:xdigit:].:]{3,39}$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[KNL\] creating delete job for CHILD_SA ESP/0x[[:xdigit:]]{8}/[[:xdigit:].:]{3,39}$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[JOB\] CHILD_SA ESP/0x[[:xdigit:]]{8}/[[:xdigit:].:]{3,39} not found for delete$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[KNL\] creating delete job for CHILD_SA ESP/0x[[:xdigit:]]{8}/([[:xdigit:].:]{3,39}|%any)$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[JOB\] CHILD_SA ESP/0x[[:xdigit:]]{8}/([[:xdigit:].:]{3,39}|%any) not found for delete$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ ipsec\[[[:digit:]]+\]: [[:digit:]]+\[JOB\] spawning [0-9]+ worker threads$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] initiating IKE_SA [[:alnum:]._-]+\[[[:digit:]]+\] to [[:xdigit:].:]{3,39}$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] [[:xdigit:].:]{3,39} is initiating an IKE_SA$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] establishing CHILD_SA [[:alnum:]._-]+(\{[[:digit:]]+\})?$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] establishing CHILD_SA [[:alnum:]._-]+(\{[[:digit:]]+\}( reqid [0-9]+)?)?$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] IKE_SA [[:alnum:]._-]+\[[[:digit:]]+\] established between [[:xdigit:].:]{3,39}\[[^]\"]+\]\.\.\.[[:xdigit:].:]{3,39}\[[^]]+\]$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] CHILD_SA [[:alnum:]._-]+\{[[:digit:]]+\} established with SPIs [[:xdigit:]]{8}_i [[:xdigit:]]{8}_o and TS [[:xdigit:].:]{3,39}/[[:digit:]]+ === [[:xdigit:].:]{3,39}/[[:digit:]]+$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] ((in|out)bound )?CHILD_SA [[:alnum:]._-]+\{[[:digit:]]+\} established with SPIs [[:xdigit:]]{8}_i [[:xdigit:]]{8}_o and TS [[:xdigit:].:]{3,39}/[[:digit:]]+ === [[:xdigit:].:]{3,39}/[[:digit:]]+$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] closing CHILD_SA [[:alnum:]._-]+\{[[:digit:]]+\} with SPIs [[:xdigit:]]{8}_i \([[:digit:]]+ bytes\) [[:xdigit:]]{8}_o \([[:digit:]]+ bytes\) and TS [[:xdigit:].:]{3,39}/[[:digit:]]+ === [[:xdigit:].:]{3,39}/[[:digit:]]+$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] reauthenticating IKE_SA [[:alnum:]._-]+\[[[:digit:]]+\]$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[JOB\] deleting IKE_SA after [[:digit:]]+ seconds of CHILD_SA inactivity$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] deleting IKE_SA [[:alnum:]._-]+\[[[:digit:]]+\] between [[:xdigit:].:]{3,39}\[[^]\"]+\]\.\.\.[[:xdigit:].:]{3,39}\[[^]]+\]$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[JOB\] deleting CHILD_SA after [[:digit:]]+ seconds of inactivity$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[JOB\] CHILD_SA \{[[:digit:]]+\} not found for delete$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[JOB\] deleting half open IKE_SA with [[:xdigit:].:]{3,39} after timeout$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] IKE_SA deleted$
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ vpn: [+-] .* [[:xdigit:].:]{3,39}/[[:digit:]]+ == [[:xdigit:].:]{3,39} -- [[:xdigit:].:]{3,39} == [[:xdigit:].:]{3,39}/[[:digit:]]+$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[MGR\] ignoring request with ID [[:digit:]]+, already processing$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[KNL\] flags changed for [[:xdigit:].:]{3,39} on e[nt][[:alnum:]]+
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[KNL\] [[:xdigit:].:]{3,39} appeared on e[nt][[:alnum:]]+$
diff --git a/roles/common/files/etc/logcheck/violations.ignore.d/logcheck-sudo b/roles/common/files/etc/logcheck/violations.ignore.d/logcheck-sudo
index e474019..70673ae 100644
--- a/roles/common/files/etc/logcheck/violations.ignore.d/logcheck-sudo
+++ b/roles/common/files/etc/logcheck/violations.ignore.d/logcheck-sudo
@@ -1,7 +1,5 @@
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sudo: pam_krb5\(sudo:auth\): user [[:alnum:]-]+ authenticated as [[:alnum:]-]+@[.A-Z]+$
-# ignore sudo with custom ENV
-#^\w{3} [ :0-9]{11} [._[:alnum:]-]+ sudo:[[:space:]]+[_[:alnum:].-]+ : TTY=(unknown|console|(pts/|tty|vc/)[[:digit:]]+) ; PWD=[^;]+ ; USER=[._[:alnum:]-]+ ; COMMAND=((/(usr|etc|bin|sbin)/|sudoedit ).*|list)$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ sudo:[[:space:]]+[_[:alnum:].-]+ : TTY=(unknown|console|(pts/|tty|vc/)[[:digit:]]+) ; PWD=[^;]+ ; USER=[._[:alnum:]-]+ (; ENV=([_a-zA-Z]+=\S* )+)?; COMMAND=((/(usr|etc|bin|sbin)/|sudoedit ).*|list)$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sudo: pam_krb5\(sudo:auth\): user [._[:alnum:]-]+ authenticated as [._[:alnum:]-]+@[.A-Z]+$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ sudo:[[:space:]]+[_[:alnum:].-]+ : (TTY=(unknown|console|(pts/|tty|vc/)[[:digit:]]+) ; )?PWD=[^;]+ ; USER=[._[:alnum:]-]+( ; GROUP=[._[:alnum:]-]+)? ; COMMAND=((/(usr|etc|bin|sbin)/|sudoedit ).*|list)$
^\w{3} [ :0-9]{11} [._[:alnum:]-]+ sudo:[[:space:]]+[_[:alnum:].-]+ : \(command continued\).*$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ sudo: pam_[[:alnum:]]+\(sudo:session\): session opened for user [[:alnum:]-]+ by ([[:alnum:]-]+)?\(uid=[0-9]+\)$
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ sudo: pam_[[:alnum:]]+\(sudo:session\): session closed for user [[:alnum:]-]+$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ sudo: pam_[[:alnum:]]+\(sudo:session\): session opened for user [._[:alnum:]-]+\(uid=[0-9]+\) by ([[:alnum:]-]+)?\(uid=[0-9]+\)$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ sudo: pam_[[:alnum:]]+\(sudo:session\): session closed for user [._[:alnum:]-]+$
diff --git a/roles/common/files/etc/rkhunter.conf b/roles/common/files/etc/rkhunter.conf
index ce3b2d6..c7358d0 100644
--- a/roles/common/files/etc/rkhunter.conf
+++ b/roles/common/files/etc/rkhunter.conf
@@ -353,7 +353,7 @@ ALLOW_SSH_PROT_V1=2
# program defaults.
#
ENABLE_TESTS=ALL
-DISABLE_TESTS=suspscan hidden_procs deleted_files packet_cap_apps apps
+DISABLE_TESTS=suspscan hidden_ports hidden_procs deleted_files packet_cap_apps apps
#
# The HASH_CMD option can be used to specify the command to use for the file
@@ -562,6 +562,10 @@ HASH_CMD=SHA512
#
#EXISTWHITELIST=""
+# work around for usr-merge, cf. https://bugs.debian.org/932594
+EXISTWHITELIST=/usr/bin/egrep
+EXISTWHITELIST=/usr/bin/fgrep
+
#
# Whitelist various attributes of the specified file. The attributes are those
# of the 'attributes' test. Specifying a file name here does not include it
@@ -592,7 +596,9 @@ HASH_CMD=SHA512
#
SCRIPTWHITELIST=/bin/egrep
SCRIPTWHITELIST=/bin/fgrep
-SCRIPTWHITELIST=/bin/which
+SCRIPTWHITELIST=/usr/bin/egrep
+SCRIPTWHITELIST=/usr/bin/fgrep
+SCRIPTWHITELIST=/usr/bin/which
SCRIPTWHITELIST=/usr/bin/ldd
SCRIPTWHITELIST=/usr/bin/lwp-request
SCRIPTWHITELIST=/usr/sbin/adduser
diff --git a/roles/common/files/etc/rsyslog.conf b/roles/common/files/etc/rsyslog.conf
index 6340537..42b01c5 100644
--- a/roles/common/files/etc/rsyslog.conf
+++ b/roles/common/files/etc/rsyslog.conf
@@ -90,11 +90,11 @@ user.* -/var/log/user.log
#
*.=debug;\
auth,authpriv.none;\
- news.none;mail.none -/var/log/debug
+ mail.none -/var/log/debug
*.=info;*.=notice;*.=warn;\
auth,authpriv.none;\
cron,daemon.none;\
- mail,news.none -/var/log/messages
+ mail.none -/var/log/messages
#
# Emergencies are sent to everybody logged in.
diff --git a/roles/common/files/etc/strongswan.d/charon.conf b/roles/common/files/etc/strongswan.d/charon.conf
index 22479cf..7cbe7db 100644
--- a/roles/common/files/etc/strongswan.d/charon.conf
+++ b/roles/common/files/etc/strongswan.d/charon.conf
@@ -1,6 +1,10 @@
# Options for the charon IKE daemon.
charon {
+ # Deliberately violate the IKE standard's requirement and allow the use of
+ # private algorithm identifiers, even if the peer implementation is unknown.
+ # accept_private_algs = no
+
# Accept unencrypted ID and HASH payloads in IKEv1 Main Mode.
# accept_unencrypted_mainmode_messages = no
@@ -17,6 +21,13 @@ charon {
# memory.
# cert_cache = yes
+ # Whether to use DPD to check if the current path still works after any
+ # changes to interfaces/addresses.
+ # check_current_path = no
+
+ # Send the Cisco FlexVPN vendor ID payload (IKEv2 only).
+ # cisco_flexvpn = no
+
# Send Cisco Unity vendor ID payload (IKEv1 only).
# cisco_unity = no
@@ -60,6 +71,10 @@ charon {
# Whether to follow IKEv2 redirects (RFC 5685).
# follow_redirects = yes
+ # Violate RFC 5998 and use EAP-only authentication even if the peer did not
+ # send an EAP_ONLY_AUTHENTICATION notify during IKE_AUTH.
+ # force_eap_only_authentication = no
+
# Maximum size (complete IP datagram size in bytes) of a sent IKE fragment
# when using proprietary IKEv1 or standardized IKEv2 fragmentation, defaults
# to 1280 (use 0 for address family specific default values, which uses a
@@ -135,6 +150,11 @@ charon {
# NAT keep alive interval.
# keep_alive = 20s
+ # Number of seconds the keep alive interval may be exceeded before a DPD is
+ # sent instead of a NAT keep alive (0 to disable). This is only useful if a
+ # clock is used that includes time spent suspended (e.g. CLOCK_BOOTTIME).
+ # keep_alive_dpd_margin = 0s
+
# Plugins to load in the IKE daemon charon.
# load =
@@ -176,14 +196,17 @@ charon {
# INVALID_KE_PAYLOAD notifies).
# prefer_configured_proposals = yes
- # By default public IPv6 addresses are preferred over temporary ones (RFC
- # 4941), to make connections more stable. Enable this option to reverse
- # this.
+ # Controls whether permanent or temporary IPv6 addresses are used as source,
+ # or announced as additional addresses if MOBIKE is used.
# prefer_temporary_addrs = no
# Process RTM_NEWROUTE and RTM_DELROUTE events.
# process_route = yes
+ # How RDNs in subject DNs of certificates are matched against configured
+ # identities (strict, reordered, or relaxed).
+ # rdn_matching = strict
+
# Delay in ms for receiving packets, to simulate larger RTT.
# receive_delay = 0
@@ -254,6 +277,13 @@ charon {
# Whether to enable constraints against IKEv2 signature schemes.
# signature_authentication_constraints = yes
+ # Value mixed into the local IKE SPIs after applying spi_mask.
+ # spi_label = 0x0000000000000000
+
+ # Mask applied to local IKE SPIs before mixing in spi_label (bits set will
+ # be replaced with spi_label).
+ # spi_mask = 0x0000000000000000
+
# The upper limit for SPIs requested from the kernel for IPsec SAs.
# spi_max = 0xcfffffff
diff --git a/roles/common/files/etc/systemd/system/bacula-fd.service b/roles/common/files/etc/systemd/system/bacula-fd.service.d/override.conf
index 119b3a2..537bf1e 100644
--- a/roles/common/files/etc/systemd/system/bacula-fd.service
+++ b/roles/common/files/etc/systemd/system/bacula-fd.service.d/override.conf
@@ -1,18 +1,9 @@
-[Unit]
-Description=Bacula File Daemon service
-After=network.target
-
[Service]
-Type=simple
-StandardOutput=syslog
-ExecStart=/usr/sbin/bacula-fd -f -c /etc/bacula/bacula-fd.conf
-
# Hardening
NoNewPrivileges=yes
ProtectHome=read-only
ProtectSystem=strict
ReadWriteDirectories=/var/lib/bacula
-RuntimeDirectory=bacula
PrivateTmp=yes
PrivateDevices=yes
ProtectControlGroups=yes
@@ -20,6 +11,3 @@ ProtectKernelModules=yes
ProtectKernelTunables=yes
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
CapabilityBoundingSet=CAP_DAC_READ_SEARCH
-
-[Install]
-WantedBy=multi-user.target
diff --git a/roles/common/files/etc/systemd/system/fail2ban.service.d/override.conf b/roles/common/files/etc/systemd/system/fail2ban.service.d/override.conf
index e3e651f..b34d130 100644
--- a/roles/common/files/etc/systemd/system/fail2ban.service.d/override.conf
+++ b/roles/common/files/etc/systemd/system/fail2ban.service.d/override.conf
@@ -2,13 +2,16 @@
After=nftables.service
[Service]
+ExecStartPre=
+ExecStart=
+ExecStart=/usr/bin/fail2ban-server -xf --logtarget=sysout start
+
# Need explicit rights to read logs as we don't grant CAP_DAC_READ_SEARCH
SupplementaryGroups=adm
# Hardening
NoNewPrivileges=yes
ProtectSystem=strict
-ReadWriteDirectories=/var/log/fail2ban
RuntimeDirectory=fail2ban
PrivateDevices=yes
ProtectControlGroups=yes
diff --git a/roles/common/files/etc/systemd/system/munin-node.service.d/override.conf b/roles/common/files/etc/systemd/system/munin-node.service.d/override.conf
index 53747f6..fee16b3 100644
--- a/roles/common/files/etc/systemd/system/munin-node.service.d/override.conf
+++ b/roles/common/files/etc/systemd/system/munin-node.service.d/override.conf
@@ -1,4 +1,5 @@
[Service]
+ExecStartPre=
# Hardening
NoNewPrivileges=yes
diff --git a/roles/common/files/usr/local/sbin/update-firewall b/roles/common/files/usr/local/sbin/update-firewall
index 4b3e5cf..e11e8a9 100755
--- a/roles/common/files/usr/local/sbin/update-firewall
+++ b/roles/common/files/usr/local/sbin/update-firewall
@@ -36,14 +36,14 @@ for idx in "${!INTERFACES[@]}"; do
done
# clear sets in the old rules before diff'ing with the new ones
-nft list ruleset -sn >"$oldrules"
+nft -sn list ruleset >"$oldrules"
ip netns exec "$netns" nft -f - <"$oldrules"
ip netns exec "$netns" nft flush set inet filter fail2ban || true
ip netns exec "$netns" nft flush set inet filter fail2ban6 || true
-ip netns exec "$netns" nft list ruleset -sn >"$oldrules"
+ip netns exec "$netns" nft -sn list ruleset >"$oldrules"
ip netns exec "$netns" nft -f - <"$script"
-ip netns exec "$netns" nft list ruleset -sn >"$newrules"
+ip netns exec "$netns" nft -sn list ruleset >"$newrules"
ip netns del "$netns"
netns=
diff --git a/roles/common/handlers/main.yml b/roles/common/handlers/main.yml
index 2437653..bbaaef5 100644
--- a/roles/common/handlers/main.yml
+++ b/roles/common/handlers/main.yml
@@ -18,7 +18,7 @@
command: /usr/bin/rkhunter --propupd
- name: Update firewall
- command: /usr/local/sbin/update-firewall.sh -c
+ command: /usr/local/sbin/update-firewall -c
- name: Restart fail2ban
service: name=fail2ban state=restarted
@@ -29,6 +29,9 @@
- name: Restart rsyslog
service: name=rsyslog state=restarted
+- name: Restart systemd-timesyncd
+ service: name=systemd-timesyncd state=restarted
+
- name: Restart ntp
service: name=ntp state=restarted
diff --git a/roles/common/tasks/bacula.yml b/roles/common/tasks/bacula.yml
index fb37b5b..308e358 100644
--- a/roles/common/tasks/bacula.yml
+++ b/roles/common/tasks/bacula.yml
@@ -10,7 +10,7 @@
- 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
@@ -54,23 +54,21 @@
tags:
- genkey
-- name: Copy bacula-fd.service
- copy: src=etc/systemd/system/bacula-fd.service
- dest=/etc/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
-# We use RuntimeDirectory in our service unit to avoid permission issues
-# caused by the restrictive Capability Bounding Set
-- name: Mask /usr/lib/tmpfiles.d/bacula.conf
- file: src=/dev/null
- dest=/etc/tmpfiles.d/bacula.conf
- owner=root group=root
- state=link
-
- meta: flush_handlers
- name: Enable bacula-fd
diff --git a/roles/common/tasks/fail2ban.yml b/roles/common/tasks/fail2ban.yml
index e56deaf..563075f 100644
--- a/roles/common/tasks/fail2ban.yml
+++ b/roles/common/tasks/fail2ban.yml
@@ -1,22 +1,6 @@
- name: Install fail2ban
apt: pkg=fail2ban
-# Log into a dedicate directory so we can use ReadWriteDirectories in
-# the .service file
-- name: Create directory /var/log/fail2ban
- file: path=/var/log/fail2ban
- state=directory
- owner=root group=adm
- mode=0750
-
-- name: Fix fail2ban logrotate snippet
- lineinfile: dest=/etc/logrotate.d/fail2ban
- state=present
- line="/var/log/fail2ban/*.log"
- insertbefore="^[^#]*\\s{$"
- tags:
- - logrotate
-
- name: Configure fail2ban (fail2ban.local)
copy: src=etc/fail2ban/fail2ban.local
dest=/etc/fail2ban/fail2ban.local
diff --git a/roles/common/tasks/ipsec.yml b/roles/common/tasks/ipsec.yml
index 4fc2ef7..917c687 100644
--- a/roles/common/tasks/ipsec.yml
+++ b/roles/common/tasks/ipsec.yml
@@ -3,6 +3,7 @@
vars:
packages:
- strongswan-charon
+ - strongswan-starter
# for the GCM and openssl plugins
- libstrongswan-standard-plugins
notify:
diff --git a/roles/common/tasks/logging.yml b/roles/common/tasks/logging.yml
index b602a49..2b4a42a 100644
--- a/roles/common/tasks/logging.yml
+++ b/roles/common/tasks/logging.yml
@@ -3,7 +3,6 @@
vars:
packages:
- rsyslog
- - syslog-summary
- logcheck
- logcheck-database
- logrotate
diff --git a/roles/common/tasks/main.yml b/roles/common/tasks/main.yml
index fc692fa..a6795ba 100644
--- a/roles/common/tasks/main.yml
+++ b/roles/common/tasks/main.yml
@@ -82,6 +82,7 @@
- molly-guard
- rsync
- screen
+ - bind9-dnsutils
- name: Disable resume device
# Cf. initramfs-tools(7) and initramfs.conf(5).
diff --git a/roles/common/tasks/munin-node.yml b/roles/common/tasks/munin-node.yml
index a713f08..2411b59 100644
--- a/roles/common/tasks/munin-node.yml
+++ b/roles/common/tasks/munin-node.yml
@@ -62,10 +62,6 @@
- load
- memory
- netstat
- - ntp_kernel_err
- - ntp_kernel_pll_freq
- - ntp_kernel_pll_off
- - ntp_offset
- open_files
- open_inodes
- processes
@@ -78,6 +74,20 @@
notify:
- Restart munin-node
+- 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
@@ -90,6 +100,18 @@
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 }}
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/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/sysctl.yml b/roles/common/tasks/sysctl.yml
index 3bf3b4f..08a1b13 100644
--- a/roles/common/tasks/sysctl.yml
+++ b/roles/common/tasks/sysctl.yml
@@ -11,10 +11,14 @@
- { 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 }
diff --git a/roles/common/templates/etc/apt/sources.list.j2 b/roles/common/templates/etc/apt/sources.list.j2
index 47a7cda..c8f5dfc 100644
--- a/roles/common/templates/etc/apt/sources.list.j2
+++ b/roles/common/templates/etc/apt/sources.list.j2
@@ -4,7 +4,7 @@
deb https://deb.debian.org/debian {{ ansible_lsb.codename }} main{% if inventory_hostname_short in non_free_packages.keys() or (ansible_processor[1] is search("^(Genuine)?Intel.*") and not ansible_virtualization_role == 'guest') %} contrib non-free{% endif %}
-deb https://deb.debian.org/debian-security {{ ansible_lsb.codename }}/updates main{% if inventory_hostname_short in non_free_packages.keys() or (ansible_processor[1] is search("^(Genuine)?Intel.*") and not ansible_virtualization_role == 'guest') %} contrib non-free{% endif %}
+deb https://deb.debian.org/debian-security {{ ansible_lsb.codename }}{% if ansible_lsb.major_release | int < 11 %}/updates{% else %}-security{% endif %} main{% if inventory_hostname_short in non_free_packages.keys() or (ansible_processor[1] is search("^(Genuine)?Intel.*") and not ansible_virtualization_role == 'guest') %} contrib non-free{% endif %}
deb https://deb.debian.org/debian {{ ansible_lsb.codename }}-updates main
diff --git a/roles/common/templates/etc/bacula/bacula-fd.conf.j2 b/roles/common/templates/etc/bacula/bacula-fd.conf.j2
index db1960e..d0af395 100644
--- a/roles/common/templates/etc/bacula/bacula-fd.conf.j2
+++ b/roles/common/templates/etc/bacula/bacula-fd.conf.j2
@@ -1,7 +1,14 @@
#
# Default Bacula File Daemon Configuration file
#
-# For Bacula release 9.4.2 (04 February 2019) -- debian buster/sid
+# For Bacula release 9.6.7 (10 December 2020) -- debian bullseye/sid
+#
+# There is not much to change here except perhaps the
+# File daemon Name to
+#
+#
+# Copyright (C) 2000-2020 Kern Sibbald
+# License: BSD 2-Clause; see file LICENSE-FOSS
#
#
diff --git a/roles/common/templates/etc/clamav/freshclam.conf.j2 b/roles/common/templates/etc/clamav/freshclam.conf.j2
index 06cebd1..650a2b3 100644
--- a/roles/common/templates/etc/clamav/freshclam.conf.j2
+++ b/roles/common/templates/etc/clamav/freshclam.conf.j2
@@ -19,7 +19,6 @@ ReceiveTimeout 30
TestDatabases yes
ScriptedUpdates yes
CompressLocalDatabase no
-SafeBrowsing false
Bytecode true
NotifyClamd /etc/clamav/clamd.conf
# Check for new database 24 times a day
diff --git a/roles/common/templates/etc/fail2ban/jail.local.j2 b/roles/common/templates/etc/fail2ban/jail.local.j2
index b01709a..3cd19cc 100644
--- a/roles/common/templates/etc/fail2ban/jail.local.j2
+++ b/roles/common/templates/etc/fail2ban/jail.local.j2
@@ -13,7 +13,9 @@ destemail = admin@fripost.org
ignoreip = 127.0.0.0/8, ::1, {{ ipsec_subnet }}
banaction = nftables-allports
-logpath = /var/log/fail2ban/fail2ban.log
+
+# must match nftables.conf's blackholes timeouts
+bantime = 10m
#
# JAILS
diff --git a/roles/common/templates/etc/ipsec.conf.j2 b/roles/common/templates/etc/ipsec.conf.j2
index 6b3840f..e7505b4 100644
--- a/roles/common/templates/etc/ipsec.conf.j2
+++ b/roles/common/templates/etc/ipsec.conf.j2
@@ -17,7 +17,7 @@ conn %default
{% endif %}
leftauth = pubkey
left = %defaultroute
- leftsubnet = {{ ipsec[inventory_hostname_short] | ipv4 }}/32
+ leftsubnet = {{ ipsec[inventory_hostname_short] | ansible.utils.ipv4 }}/32
leftid = {{ inventory_hostname }}
leftsigkey = {{ inventory_hostname_short }}.pem
leftfirewall = no
@@ -36,7 +36,7 @@ conn {{ hostvars[host].inventory_hostname_short }}
rightallowany = yes
{% endif %}
rightsigkey = {{ hostvars[host].inventory_hostname_short }}.pem
- rightsubnet = {{ ipsec[ hostvars[host].inventory_hostname_short ] | ipv4 }}/32
+ rightsubnet = {{ ipsec[ hostvars[host].inventory_hostname_short ] | ansible.utils.ipv4 }}/32
{% if 'NATed' not in group_names and 'NATed' in hostvars[host].group_names %}
mobike = yes
{% endif %}
diff --git a/roles/common/templates/etc/munin/munin-node.conf.j2 b/roles/common/templates/etc/munin/munin-node.conf.j2
index a1391d9..1aba053 100644
--- a/roles/common/templates/etc/munin/munin-node.conf.j2
+++ b/roles/common/templates/etc/munin/munin-node.conf.j2
@@ -42,7 +42,7 @@ host_name {{ inventory_hostname_short }}
# may repeat the allow line as many times as you'd like
{% for host in groups['munin_master'] %}
-allow ^{{ ipsec[ hostvars[host].inventory_hostname_short ] | ipv4 | replace(".","\.") }}$
+allow ^{{ ipsec[ hostvars[host].inventory_hostname_short ] | ansible.utils.ipv4 | replace(".","\.") }}$
{% endfor %}
# Which address to bind to;
diff --git a/roles/common/templates/etc/nftables.conf.j2 b/roles/common/templates/etc/nftables.conf.j2
index fc7691a..805d1a8 100755
--- a/roles/common/templates/etc/nftables.conf.j2
+++ b/roles/common/templates/etc/nftables.conf.j2
@@ -45,8 +45,107 @@ define out-tcp-ports = {
flush ruleset
+table netdev filter {
+{% for if in ansible_interfaces %}
+{% if if != "lo" and ansible_facts[if].active %}
+{% set addr = (ansible_facts[if].ipv4 | default({'address': '0.0.0.0'})).address %}
+ chain INGRESS-{{ if }} {
+ type filter hook ingress device {{ if }} priority -499
+ policy accept
+
+ # IPsec traffic (refined later in the filter rule)
+ ip saddr {{ ipsec_subnet }} ip daddr {{ ipsec[inventory_hostname_short] }} meta secpath exists accept
+
+ # rate-limiting is done directly by the kernel (net.ipv4.icmp_{ratelimit,ratemask} runtime options)
+ icmp type { echo-reply, echo-request, destination-unreachable, time-exceeded } counter accept
+ icmpv6 type { echo-reply, echo-request, destination-unreachable,
+ packet-too-big, time-exceeded, parameter-problem } counter accept
+
+ # accept neighbour discovery for autoconfiguration, RFC 4890 sec. 4.4.1
+ ip6 hoplimit 255 icmpv6 type { 133,134,135,136,141,142 } counter accept
+
+ # accept link-local multicast receiver notification messages
+ ip6 saddr fe80::/10 ip6 daddr ff02::/16 ip6 hoplimit 1 icmpv6 type { 130,131,132,143 } counter accept
+
+ # drop all remaining ICMP/ICMPv6 traffic
+ meta l4proto { icmp, icmpv6 } counter drop
+
+ # bogon filter (cf. RFC 6890 for non-global ip addresses)
+ define bogon = {
+ 0.0.0.0/8 # this host, on this network (RFC 1122 sec. 3.2.1.3)
+{% if not addr | ansible.utils.ipaddr('10.0.0.0/8') %}
+ , 10.0.0.0/8 # private-use (RFC 1918)
+{% endif %}
+ , 100.64.0.0/10 # shared address space (RFC 6598)
+ , 127.0.0.0/8 # loopback (RFC 1122, sec. 3.2.1.3)
+ , 169.254.0.0/16 # link local (RFC 3927)
+ , 172.16.0.0/12 # private-use (RFC 1918)
+ , 192.0.0.0/24 # IETF protocol assignments (RFC 6890 sec. 2.1)
+ , 192.0.2.0/24 # documentation (RFC 5737)
+{% if not addr | ansible.utils.ipaddr('192.168.0.0/16') %}
+ , 192.168.0.0/16 # private-use (RFC 1918)
+{% endif %}
+ , 198.18.0.0/15 # benchmarking (RFC 2544)
+ , 198.51.100.0/24 # documentation (RFC 5737)
+ , 203.0.113.0/24 # documentation (RFC 5737)
+ , 224.0.0.0/3 # multicast - class D 224.0.0.0/4 + class E 240.0.0.0/4 (RFC 1112 sec. 4)
+ , 255.255.255.255/32 # limited broadcast (RFC 0919 sec. 7)
+ }
+
+ ip saddr $bogon counter drop
+ ip daddr $bogon counter drop
+
+ # See also https://www.team-cymru.org/Services/Bogons/fullbogons-ipv6.txt
+ define bogon6 = {
+ ::1/128 # loopback address (RFC 4291)
+ , ::/128 # unspecified (RFC 4291)
+ , ::ffff:0:0/96 # IPv4-mapped address (RFC 4291)
+ , 100::/64 # discard-only address block (RFC 6666)
+ , 2001::/23 # IETF protocol assignments (RFC 2928)
+ , 2001::/32 # TEREDO (RFC 4380)
+ , 2001:2::/48 # benchmarking (RFC 5180)
+ , 2001:db8::/32 # documentation (RFC 3849)
+ , 2001:10::/28 # ORCHID (RFC 4843)
+ , 2002::/16 # 6to4 (RFC 3056)
+ , fc00::/7 # unique-local (RFC 4193)
+ , fe80::/10 # linked-scoped unicast (RFC 4291)
+ }
+
+ ip6 saddr $bogon6 counter drop
+ ip6 saddr $bogon6 counter drop
+ }
+{% endif %}
+{% endfor %}
+}
+
+table inet raw {
+ chain PREROUTING-stateless {
+ # XXX can't add that to the ingress hook as that happens before IP defragmentation
+ # so we don't have the TCP header in later fragments (we don't want to drop IP
+ # fragments, see https://blog.cloudflare.com/ip-fragmentation-is-broken/ )
+ type filter hook prerouting priority -399 # > NF_IP_PRI_CONNTRACK_DEFRAG (-400)
+ policy accept
+
+ # stateless filter for bogus TCP packets
+ tcp flags & (fin|syn|rst|psh|ack|urg) == 0x0 counter drop # null packet
+ tcp flags & (fin|psh|urg) == fin|psh|urg counter drop # XMAS packet
+ tcp flags & (syn|rst) == syn|rst counter drop
+ tcp flags & (fin|rst) == fin|rst counter drop
+ tcp flags & (fin|syn) == fin|syn counter drop
+ tcp flags & (fin|psh|ack) == fin|psh counter drop
+ }
+
+ chain PREROUTING {
+ type filter hook prerouting priority -199 # > NF_IP_PRI_CONNTRACK (-200)
+ policy accept
+
+ # stateful filter
+ ct state invalid counter drop
+ }
+}
+
table inet filter {
- # blackholes
+ # blackholes (timeout must match /etc/fail2ban/jail.local)
set fail2ban { type ipv4_addr; timeout 10m; }
set fail2ban6 { type ipv6_addr; timeout 10m; }
@@ -67,18 +166,12 @@ table inet filter {
# ip saddr {{ ipsec_subnet }} ip daddr {{ ipsec[inventory_hostname_short] }} ipsec in reqid $i accept
ip saddr {{ ipsec_subnet }} ip daddr {{ ipsec[inventory_hostname_short] }} meta secpath exists accept
- # rate-limiting is done directly by the kernel (net.ipv4.icmp_{ratelimit,ratemask} runtime options)
- icmp type { echo-reply, echo-request, destination-unreachable } counter accept
- icmpv6 type { echo-reply, echo-request, destination-unreachable,
- packet-too-big, time-exceeded, parameter-problem } counter accept
-
- # accept neighbour discovery for autoconfiguration, RFC 4890 sec. 4.4.1
- icmpv6 type { 133,134,135,136,141,142 } ip6 hoplimit 255 counter accept
+ # incoming ICMP/ICMPv6 traffic was filtered in the ingress chain already
+ meta l4proto { icmp, icmpv6 } counter accept
- jump martian
- jump invalid
+ # NTP (ntpd uses sport 123 but systemd-timesyncd does not)
+ udp sport 123 ct state related,established accept
- udp sport 123 udp dport 123 ct state related,established accept
{% if groups.all | length > 1 %}
udp sport 500 udp dport 500 ct state new,related,established accept
{% if groups.NATed | length > 0 %}
@@ -93,8 +186,8 @@ table inet filter {
ip6 version 6 udp sport 547 udp dport 546 ct state related,established accept
{% endif %}
- meta l4proto tcp ip saddr @fail2ban counter drop
- meta l4proto tcp ip6 saddr @fail2ban6 counter drop
+ ip saddr @fail2ban counter drop
+ ip6 saddr @fail2ban6 counter drop
tcp dport $in-tcp-ports ct state related,established accept
tcp dport $in-tcp-ports ct state new counter accept
@@ -114,12 +207,11 @@ table inet filter {
# ip saddr {{ ipsec[inventory_hostname_short] }} ip daddr {{ ipsec_subnet }} ipsec out reqid $i accept
ip saddr {{ ipsec[inventory_hostname_short] }} ip daddr {{ ipsec_subnet }} accept
- meta l4proto { icmp, icmpv6 } accept
+ meta l4proto { icmp, icmpv6 } counter accept
- jump martian
- jump invalid
+ # NTP (ntpd uses sport 123 but systemd-timesyncd does not)
+ udp dport 123 ct state new,related,established accept
- udp sport 123 udp dport 123 ct state new,related,established accept
{% if groups.all | length > 1 %}
udp sport 500 udp dport 500 ct state new,related,established accept
{% if groups.NATed | length > 0 %}
@@ -142,62 +234,4 @@ table inet filter {
meta l4proto udp counter reject
counter reject
}
-
- chain martian {
- # bogon filter (cf. RFC 6890 for non-global ip addresses)
- define invalid-ip = {
- 0.0.0.0/8 # this host, on this network (RFC 1122 sec. 3.2.1.3)
-{% if not ansible_default_ipv4.address | ipaddr('10.0.0.0/8') %}
- , 10.0.0.0/8 # private-use (RFC 1918)
-{% endif %}
- , 100.64.0.0/10 # shared address space (RFC 6598)
- , 127.0.0.0/8 # loopback (RFC 1122, sec. 3.2.1.3)
- , 169.254.0.0/16 # link local (RFC 3927)
-{% if not ansible_default_ipv4.address | ipaddr('172.16.0.0/12') %}
- , 172.16.0.0/12 # private-use (RFC 1918)
-{% endif %}
- , 192.0.0.0/24 # IETF protocol assignments (RFC 6890 sec. 2.1)
- , 192.0.2.0/24 # documentation (RFC 5737)
-{% if not ansible_default_ipv4.address | ipaddr('192.168.0.0/16') %}
- , 192.168.0.0/16 # private-use (RFC 1918)
-{% endif %}
- , 198.18.0.0/15 # benchmarking (RFC 2544)
- , 198.51.100.0/24 # documentation (RFC 5737)
- , 203.0.113.0/24 # documentation (RFC 5737)
- , 240.0.0.0/4 # reserved (RFC 1112, sec. 4)
- , 255.255.255.255/32 # limited broadcast (RFC 0919, section 7)
- }
-
- define invalid-ip6 = {
- ::1/128 # loopback address (RFC 4291)
- , ::/128 # unspecified (RFC 4291)
- , ::ffff:0:0/96 # IPv4-mapped address (RFC 4291)
- , 100::/64 # discard-only address block (RFC 6666)
- , 2001::/23 # IETF protocol assignments (RFC 2928)
- , 2001::/32 # TEREDO (RFC 4380)
- , 2001:2::/48 # benchmarking (RFC 5180)
- , 2001:db8::/32 # documentation (RFC 3849)
- , 2001:10::/28 # ORCHID (RFC 4843)
- , 2002::/16 # 6to4 (RFC 3056)
- , fc00::/7 # unique-local (RFC 4193)
- , fe80::/10 # linked-scoped unicast (RFC 4291)
- }
-
- ip saddr $invalid-ip counter drop
- ip daddr $invalid-ip counter drop
-
- ip6 saddr $invalid-ip6 counter drop
- ip6 daddr $invalid-ip6 counter drop
- }
-
- chain invalid {
- ct state invalid counter reject
-
- # drop bogus TCP packets
- tcp flags & (fin|syn|rst|psh|ack|urg) == 0x0 counter drop # null packets
- tcp flags != syn ct state new counter drop # SYN-flood attacks
- tcp flags & (fin|syn|rst|psh|ack|urg) == fin|psh|urg counter drop # XMAS packets
- tcp flags & (fin|syn) == fin|syn counter drop # bogus
- tcp flags & (syn|rst) == syn|rst counter drop # bogus
- }
}
diff --git a/roles/common/templates/etc/ntp.conf.j2 b/roles/common/templates/etc/ntp.conf.j2
index 1016d55..b76f0dd 100644
--- a/roles/common/templates/etc/ntp.conf.j2
+++ b/roles/common/templates/etc/ntp.conf.j2
@@ -15,7 +15,6 @@ filegen clockstats file clockstats type day enable
# You do need to talk to an NTP server or two (or three).
-{% if 'NTP_master' in group_names %}
# Use Stratum One Time Servers:
# http://support.ntp.org/bin/view/Servers/StratumOneTimeServers
server sth1.ntp.se iburst
@@ -24,17 +23,6 @@ server gbg1.ntp.se iburst
server gbg2.ntp.se iburst
server ntp1.sp.se iburst
server ntp2.sp.se iburst
-{% else %}
-# Sychronize to our (stratum 2) NTP server, to ensure our network has a
-# consistent time.
-{% for host in groups['NTP_master'] | sort %}
-server {{ ipsec[ hostvars[host].inventory_hostname_short ] }} prefer iburst
-{% endfor %}
-pool 0.{{ geoip | default('debian') }}.pool.ntp.org iburst
-pool 1.{{ geoip | default('debian') }}.pool.ntp.org iburst
-pool 2.{{ geoip | default('debian') }}.pool.ntp.org iburst
-pool 3.{{ geoip | default('debian') }}.pool.ntp.org iburst
-{% endif %}
# Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for
diff --git a/roles/common/templates/etc/postfix/main.cf.j2 b/roles/common/templates/etc/postfix/main.cf.j2
index b369d43..5ac7920 100644
--- a/roles/common/templates/etc/postfix/main.cf.j2
+++ b/roles/common/templates/etc/postfix/main.cf.j2
@@ -31,7 +31,7 @@ virtual_alias_maps = lmdb:/etc/aliases
alias_database = $virtual_alias_maps
# Forward everything to our internal outgoing proxy
-relayhost = [{{ postfix_instance.out.addr | ipaddr }}]:{{ postfix_instance.out.port }}
+relayhost = [{{ postfix_instance.out.addr | ansible.utils.ipaddr }}]:{{ postfix_instance.out.port }}
relay_domains =
smtp_tls_security_level = none
diff --git a/roles/common/templates/etc/postfix/master.cf.j2 b/roles/common/templates/etc/postfix/master.cf.j2
index f199ed0..3954085 100644
--- a/roles/common/templates/etc/postfix/master.cf.j2
+++ b/roles/common/templates/etc/postfix/master.cf.j2
@@ -57,6 +57,8 @@ smtp_verify unix - - y - - smtp
-o smtp_tls_protocols=!SSLv2,!SSLv3
-o smtp_tls_note_starttls_offer=yes
-o smtp_tls_session_cache_database=lmdb:$data_directory/smtp_tls_session_cache
+ -o smtp_tls_fingerprint_digest=sha256
+ -o smtp_tls_policy_maps=lmdb:$config_directory/smtp_tls_policy
{% endif %}
relay unix - - y - - smtp
showq unix n - y - - showq
diff --git a/roles/common/templates/etc/systemd/timesyncd.conf.d/fripost.conf.j2 b/roles/common/templates/etc/systemd/timesyncd.conf.d/fripost.conf.j2
new file mode 100644
index 0000000..f578cd9
--- /dev/null
+++ b/roles/common/templates/etc/systemd/timesyncd.conf.d/fripost.conf.j2
@@ -0,0 +1,9 @@
+[Time]
+# Sychronize to our (stratum 2) NTP server, to ensure our network has a
+# consistent time.
+{%- set ntp = [] -%}
+{%- for host in groups['NTP_master'] -%}
+{%- set _ = ntp.append(ipsec[ hostvars[host].inventory_hostname_short ]) -%}
+{%- endfor %}
+
+NTP={{ ntp | join(' ') }}
diff --git a/roles/common/templates/etc/unbound/unbound.conf.j2 b/roles/common/templates/etc/unbound/unbound.conf.j2
index 64f32bf..e75e66f 100644
--- a/roles/common/templates/etc/unbound/unbound.conf.j2
+++ b/roles/common/templates/etc/unbound/unbound.conf.j2
@@ -29,4 +29,4 @@ server:
#
# The following line includes additional configuration files from the
# /etc/unbound/unbound.conf.d directory.
-include: "/etc/unbound/unbound.conf.d/*.conf"
+include-toplevel: "/etc/unbound/unbound.conf.d/*.conf"