summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--certs/dkim/138abf7e73c88d8dc67ca2d26881bc81:guilhem.se.pub9
-rw-r--r--certs/dkim/564736f16aac6a05b50ea67fd6259e16:hemskaklubben.se.pub9
-rw-r--r--certs/dkim/79992d8659ce1c2d3f5a9ad20d167c15:r0x.se.pub9
-rw-r--r--certs/dkim/9552b222c0c258daf13bd410f6b5a159:ljhms.se.pub9
-rw-r--r--certs/dkim/aa813339234ce48d3b3bbfa334fbf48e:dubre.me.pub9
-rw-r--r--certs/dkim/caf0355abffeda8264045c3730362147:himmelkanten.se.pub9
-rw-r--r--certs/dkim/ccb92aa8f79aa6d76b2a9d6ecf6b30e6:vimmelkanten.se.pub9
-rw-r--r--certs/dkim/ce3283cc9129cb6692174bd2ec480b88:kodafritt.se.pub9
-rw-r--r--certs/ipsec/levante.pem24
-rw-r--r--certs/ldap/ldap.fripost.org.pem39
-rw-r--r--certs/ldap/mx.pem31
-rw-r--r--certs/ldap/syncrepl/mx@civett.pem12
-rw-r--r--certs/ldap/syncrepl/mx@elefant.pem12
-rw-r--r--certs/ssh_known_hosts3
-rw-r--r--group_vars/all.yml29
-rw-r--r--lib/action_plugins/fetch_cmd.py2
-rw-r--r--lib/modules/mysql_user2495
-rw-r--r--lib/modules/openldap60
-rw-r--r--lib/modules/postmulti4
-rw-r--r--production1
-rw-r--r--roles/IMAP/files/etc/dovecot/conf.d/10-auth.conf17
-rw-r--r--roles/IMAP/files/etc/dovecot/conf.d/10-mail.conf427
-rw-r--r--roles/IMAP/files/etc/dovecot/conf.d/10-ssl.conf73
-rw-r--r--roles/IMAP/files/etc/dovecot/conf.d/15-lda.conf48
-rw-r--r--roles/IMAP/files/etc/dovecot/conf.d/15-mailboxes.conf76
-rw-r--r--roles/IMAP/files/etc/dovecot/conf.d/20-imap.conf108
-rw-r--r--roles/IMAP/files/etc/dovecot/conf.d/20-lmtp.conf27
-rw-r--r--roles/IMAP/files/etc/dovecot/conf.d/90-plugin.conf28
-rw-r--r--roles/IMAP/files/etc/dovecot/conf.d/90-sieve.conf214
-rw-r--r--roles/IMAP/files/etc/dovecot/ssl/config2
-rw-r--r--roles/IMAP/tasks/imap.yml20
-rw-r--r--roles/IMAP/tasks/spam.yml4
-rw-r--r--roles/IMAP/templates/etc/dovecot/conf.d/10-master.conf.j22
-rw-r--r--roles/IMAP/templates/etc/dovecot/conf.d/99-local.conf.j2204
-rw-r--r--roles/IMAP/templates/etc/postfix/main.cf.j22
-rw-r--r--roles/MSA/files/etc/postfix/anonymize_sender.pcre2
-rw-r--r--roles/MSA/templates/etc/postfix/main.cf.j27
-rw-r--r--roles/MX/files/etc/opendmarc.conf4
-rw-r--r--roles/MX/templates/etc/postfix/main.cf.j22
-rw-r--r--roles/MX/templates/etc/postfix/virtual/transport.j24
-rw-r--r--roles/amavis/tasks/main.yml2
-rw-r--r--roles/bacula-dir/tasks/main.yml4
-rw-r--r--roles/common-LDAP/tasks/main.yml36
-rw-r--r--roles/common-LDAP/templates/etc/ldap/database.ldif.j22
-rw-r--r--roles/common-SQL/tasks/main.yml10
-rw-r--r--roles/common-web/files/etc/nginx/sites-available/default4
-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/fail2ban/filter.d/dovecot.conf49
-rw-r--r--roles/common/files/etc/logcheck/ignore.d.server/common-local45
-rw-r--r--roles/common/files/etc/logcheck/ignore.d.server/dovecot-local11
-rw-r--r--roles/common/files/etc/logcheck/ignore.d.server/postfix-local16
-rw-r--r--roles/common/files/etc/logcheck/ignore.d.server/strongswan-local2
-rw-r--r--roles/common/files/etc/logcheck/violations.ignore.d/logcheck-sudo10
-rw-r--r--roles/common/files/etc/rkhunter.conf3
-rw-r--r--roles/common/files/etc/rsyslog.conf4
-rw-r--r--roles/common/files/etc/strongswan.d/charon.conf77
-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/bin/genkeypair.sh10
-rwxr-xr-xroles/common/files/usr/local/sbin/update-firewall6
-rw-r--r--roles/common/handlers/main.yml3
-rw-r--r--roles/common/tasks/fail2ban.yml16
-rw-r--r--roles/common/tasks/ipsec.yml1
-rw-r--r--roles/common/tasks/logging.yml7
-rw-r--r--roles/common/tasks/main.yml6
-rw-r--r--roles/common/tasks/ntp.yml7
-rw-r--r--roles/common/tasks/resolved.yml36
-rw-r--r--roles/common/tasks/smart.yml7
-rw-r--r--roles/common/tasks/sysctl.yml2
-rw-r--r--roles/common/tasks/unbound.yml11
-rw-r--r--roles/common/templates/etc/apt/preferences.j210
-rw-r--r--roles/common/templates/etc/apt/sources.list.j26
-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.j25
-rw-r--r--roles/common/templates/etc/munin/munin-node.conf.j22
-rwxr-xr-xroles/common/templates/etc/nftables.conf.j239
-rw-r--r--roles/common/templates/etc/postfix/main.cf.j22
-rw-r--r--roles/common/templates/etc/systemd/resolved.conf.d/local.conf.j211
-rw-r--r--roles/common/templates/etc/unbound/unbound.conf.j22
-rw-r--r--roles/lacme/files/etc/lacme/lacme.conf80
-rw-r--r--roles/lacme/tasks/main.yml9
-rw-r--r--roles/lists/files/etc/nginx/sites-available/sympa4
-rw-r--r--roles/lists/files/etc/sympa/sympa/sympa.conf10
-rw-r--r--roles/lists/tasks/sympa.yml4
-rw-r--r--roles/lists/templates/etc/postfix/main.cf.j22
-rw-r--r--roles/lists/templates/etc/sympa/robot.conf.j23
-rw-r--r--roles/nextcloud/files/etc/ldap/ldap.conf4
-rw-r--r--roles/nextcloud/files/etc/nginx/sites-available/nextcloud49
-rw-r--r--roles/nextcloud/files/etc/php/fpm/pool.d/nextcloud.conf2
-rw-r--r--roles/nextcloud/handlers/main.yml4
-rw-r--r--roles/nextcloud/tasks/main.yml40
-rw-r--r--roles/webmail/files/etc/nginx/sites-available/roundcube2
-rw-r--r--roles/webmail/files/etc/php/fpm/pool.d/roundcube.conf2
-rw-r--r--roles/webmail/handlers/main.yml4
-rw-r--r--roles/webmail/tasks/roundcube.yml54
-rw-r--r--roles/webmail/templates/etc/roundcube/plugins/managesieve/config.inc.php.j24
100 files changed, 891 insertions, 1968 deletions
diff --git a/certs/dkim/138abf7e73c88d8dc67ca2d26881bc81:guilhem.se.pub b/certs/dkim/138abf7e73c88d8dc67ca2d26881bc81:guilhem.se.pub
new file mode 100644
index 0000000..7996cdb
--- /dev/null
+++ b/certs/dkim/138abf7e73c88d8dc67ca2d26881bc81:guilhem.se.pub
@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA27ioPU45Jca7x1J37gnI
+MOYTxxWE2H/EhL0SiMUROTphBPGYPyqJMmVCb3ff30Uf1tNv4g2UudWkMmoyHfgB
+hS7B07U+kK+q1gIDzcdQyGv1NN4efYtzo7iT6aNEArSP7vxa+OW1pltF1MQz5tnS
+UNFagc34cmQcN3QQXJW8XPMrQfDCm5QYgjXKamQ59GQuH+H6awNi0jGoEmlkwZad
+ZZ0O2Ly7eP/VPrmjDjP0QfC3pUjiFVa7ZPeL89aUuhQv40//7UxuGWuRKH/S7Rna
+tn3P059zXbK73Gg4ZdxLp9FPoORAyKxTq4F0ekSDc64zwNzTuNMusysBzAf3g2WS
+LwIDAQAB
+-----END PUBLIC KEY-----
diff --git a/certs/dkim/564736f16aac6a05b50ea67fd6259e16:hemskaklubben.se.pub b/certs/dkim/564736f16aac6a05b50ea67fd6259e16:hemskaklubben.se.pub
new file mode 100644
index 0000000..8f0a4bd
--- /dev/null
+++ b/certs/dkim/564736f16aac6a05b50ea67fd6259e16:hemskaklubben.se.pub
@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzdBZEho4wiYXL2RcxE3f
+ELcE7p2gjJD+gCIEIY6a7R6TM+GDxY/uLRXJuMpaw3Ar23R9Dj9I4Pu8k/MpskXU
+XQPwpOlnY18Dg/AYJR23RMBOZl8x6AGrO7GxP1R21l/9Y+ZHcuORPnIvRyLgX9aj
+k8iUwWaHfRo+rIyDTsPGQ6O8Zi1mCjlV+iuY1EO2AE88MNh6DiBlZlAH0dhLD9nw
+2AIz6oDQb9PNuUMfW6CBILWK45ETaBkAXqSJjcxzNbRov7AkHNDXx4Vw/s9AE2n+
+On7QHuojPtz4rJh83nInCFVuHXF9ZYR/MYBFLTBa9QzN6W/p7igulc4pn0Bn8STD
+RQIDAQAB
+-----END PUBLIC KEY-----
diff --git a/certs/dkim/79992d8659ce1c2d3f5a9ad20d167c15:r0x.se.pub b/certs/dkim/79992d8659ce1c2d3f5a9ad20d167c15:r0x.se.pub
new file mode 100644
index 0000000..0b5de26
--- /dev/null
+++ b/certs/dkim/79992d8659ce1c2d3f5a9ad20d167c15:r0x.se.pub
@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0fHwmvlTzoFX3AYvh6JZ
+t2P2vS1dDRaMB6sVXEoHjdesrvmkYCYkMvboAA1Sv34ZOqoc0E6WhSsiwEP4tRdl
+WkIQhOFr85KR3sdj3KtepngBexl4arx8FcE55mbDErzaHdmMZVbITJDNfl002DiD
+j2U35R81pTOT1M7j8eJPAF2yu2FzJG/hw98ZQWwbkgyZrIcdtTmi95uWnsjGbfcM
+Iq9YBPQItt0g/tGF379+r1D4md50UQz5SbqzsZ36O73UhY1CYo+ZFZH5dHtEl8am
+mnGy0QSdMHvwd+emPXo5bZHYSKqUqt/dDJ7NkYUnXiDpFbnCyt3s/UJ4T5VAyMQg
+CQIDAQAB
+-----END PUBLIC KEY-----
diff --git a/certs/dkim/9552b222c0c258daf13bd410f6b5a159:ljhms.se.pub b/certs/dkim/9552b222c0c258daf13bd410f6b5a159:ljhms.se.pub
new file mode 100644
index 0000000..cbf348c
--- /dev/null
+++ b/certs/dkim/9552b222c0c258daf13bd410f6b5a159:ljhms.se.pub
@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzzcLgdRi0hh0X1aXWA5R
+oa92nKQCAf26aClwuXCyl9mfJXhIWPrw/tobpl1RCrRXUT7d/3qQ/cboacjuPbIB
+E8U6a3D0S9usWg9qY31fNMQoqKQPk/lXbfAfeiJCccVUdaXqEtMErqj8+XTnd4jJ
+EfA/P/p956w3bdZAH+4jEtrXgf7NErn7YJcusK2HQp1clOzV+kBo9bABqjhXHL2L
+rhtWRUgO3ODaiPmUl1VAFjepjJYb6gXSQOuquJdlKYfOwyxcVgKA1caADeWS51em
+hc/MOob5DKL99S3IjecicaBffTArijW5PcJLfGGKHIkAxmTWo/YsTA3hxSmnpGna
+1wIDAQAB
+-----END PUBLIC KEY-----
diff --git a/certs/dkim/aa813339234ce48d3b3bbfa334fbf48e:dubre.me.pub b/certs/dkim/aa813339234ce48d3b3bbfa334fbf48e:dubre.me.pub
new file mode 100644
index 0000000..92f7479
--- /dev/null
+++ b/certs/dkim/aa813339234ce48d3b3bbfa334fbf48e:dubre.me.pub
@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArZQr93FM5Ob62mmMlE2r
+pPnRJCSnaKobSedlAjdvN3frKp7jI38ygRf+9tlj40k8XPES9CYcqmN3EGCZsOTF
+JxcZvFbSQIj+1YDKiefUm6ezGbOWdSOYHY0Ztycl9pJeUFWFFXrqhk6jBs8kt3gb
+siwLD2mgXUauV+PRumoxkzLz7oH+wnNlAEcyhzhor4sHN+2oYfr/KBHfS6X1UcVp
+Tn6mGv71OAzI0Ae3VgJ+uIfNA5rcm0iBpVMIZL2z4KYNbDUl3ah7H46/W0SI+53E
+1aUsq4mHccDZV5CtMjncM16O1iqVRbA0BBvt1lxgd42YInGd88eM9Bp6GuyBuSFr
+GwIDAQAB
+-----END PUBLIC KEY-----
diff --git a/certs/dkim/caf0355abffeda8264045c3730362147:himmelkanten.se.pub b/certs/dkim/caf0355abffeda8264045c3730362147:himmelkanten.se.pub
new file mode 100644
index 0000000..f0f4827
--- /dev/null
+++ b/certs/dkim/caf0355abffeda8264045c3730362147:himmelkanten.se.pub
@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoJ2pK0ZGuPMzXm9yUXjS
+A8CYffODp8qGl+C4Hg3F3EbBvv5VP92ALwVh3bsA63Zn4TXQ2yKztK/czoRvmTBw
+qfpZABMdkLbokffIALHrouz3e0oNxrfNcH/H/vB0AjjtHvENfOLlhBBB178HuHpa
+YVKAItiD5T0rQ3soTXRYt5Lc/TjXLMfiN8MXxVKNc5FtHi8KFZLDMXC4wfBbkkyD
+iJGryG2p3XFTCn03nEOdpLb291K/tnE6BOdDsIkgN0OHwWv/SefSgiyyJtTYvdlN
+7Cknr0uu6vjjEGhvkF3q7HzIqqlA8OwiTWuqegnOvsOR3ueIly5DIZ/cgAuhpOgY
+0QIDAQAB
+-----END PUBLIC KEY-----
diff --git a/certs/dkim/ccb92aa8f79aa6d76b2a9d6ecf6b30e6:vimmelkanten.se.pub b/certs/dkim/ccb92aa8f79aa6d76b2a9d6ecf6b30e6:vimmelkanten.se.pub
new file mode 100644
index 0000000..51ce588
--- /dev/null
+++ b/certs/dkim/ccb92aa8f79aa6d76b2a9d6ecf6b30e6:vimmelkanten.se.pub
@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1Raz+2M5r1t/bKiFYRZx
+e3HsciNmoMIHy1+UaXq7gnGHmSFxOwDquItmrsmXZBLPbul34NnOcXjmz2sOYDNR
+bAbKWGp/Gp1Tw0d8wWGScOI8QJLayVqmnnJW2INzYQ3XmXXlVJu0U8659W/jIBrE
+GHtVGus9X46tNI1fMQjRxTuJ9fKp4cjVuUCpZM4U8+YAyqPI+uGkRtacYRpoHcrR
+/OeN6/rx63XLgvjW8woihdoUo2S2FAqMvHRKSVwrkoMl9C3yNUUZTq/ddzUPd/jm
+skzgGqkgePSwMM04TE4fW395GFaZwhh0opecwZS2KV9MAPjVtnm/PnTLluAQLBeG
+4QIDAQAB
+-----END PUBLIC KEY-----
diff --git a/certs/dkim/ce3283cc9129cb6692174bd2ec480b88:kodafritt.se.pub b/certs/dkim/ce3283cc9129cb6692174bd2ec480b88:kodafritt.se.pub
new file mode 100644
index 0000000..f673d2e
--- /dev/null
+++ b/certs/dkim/ce3283cc9129cb6692174bd2ec480b88:kodafritt.se.pub
@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuTFd3JIWOX5P2dHwyyfX
+o9OS5KKZ7SYzOntHE6mKJV2jwkt81XX2BznximopptMCyRQWucSAxIrlbYb6zgIA
+QdHSK1OD9c2zMtq4iRGiLAv7Be/QaTtB2zq0+Q2YYTHM+GqFMlPa3PJ+4F4DeJZG
+Z8o1ylYjd8VI57P8HP217sHZQinYeht0iEX7kQgkwW1SdEH/FuMC/dptD9+Z29Cd
+3ml873GnY+Rx6p41EvFq7EhUsJamnY3gGADWmcmDudxVWgwjZdxr9zs11Z2tWI7D
+aU4Ze62vTY55t1opeYM0YfSiPHs3X91T2Wn0dtkLm9Xa+E4NKjTFQt0353c42ODR
+PwIDAQAB
+-----END PUBLIC KEY-----
diff --git a/certs/ipsec/levante.pem b/certs/ipsec/levante.pem
index 06af7c3..ace22c1 100644
--- a/certs/ipsec/levante.pem
+++ b/certs/ipsec/levante.pem
@@ -1,14 +1,14 @@
-----BEGIN PUBLIC KEY-----
-MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0wHLeQbEamVileAuqKmI
-lJDBtXFDqK90G/cRmNY+2G3Iy3qzbyPQ2oqZLWwXLOs4M2PGwgzeaNAVWxONVa7C
-Hxaj0R1fV06JsqNwWX5P6u5NAy/lz0Z3GtWr9WWttHVn3+d6EpZR2j00pzgOlk4O
-3LeZiVg4NnX0Tf9uWSk1EmFmQjZQX0AcVx9HOvNZS7/uoWU25pOhJu5TZ4b0FARe
-LU5kA1VzCdeRclMA2YfhPP93W6bHvqaaMMy9EdBefkbNiJZP+DxoLSCRsI2Cc3eI
-xVPnXj6un2Yjdhuku1rxfFkPuhEjU6yNfI/SPmX/VPmSzy4SDMUDjdn81+TC1RHO
-gjCD83a69AbMW6qv0/5sYpbZlbNi8q+UV/tZcp740tS4cRCZqEQOsL4CZWioXMfi
-hTAhX9E65u0GCDjcXw2ydV05omTNqndq/vV8tTE0Opj/AX5EGgfRPxvc92K1piLZ
-aq406XSpc009A9Y0OAFbF1gEFMM1qtp93+1osnSH3sNpIB1ufzHOsobEnd8Jtkdh
-4M38Ohreaw4xUSryT8oqvGVY/ObTVA+vnJIgv+GmCTRzvmkTIjaYgUn0/LvscreJ
-njaVcBZbL2v8zujJoSXCdRc7SCRJ9JlEIFxlaoEqAa6zexVMQW8+8bDtoIjr25xK
-XIm9iuIlo/vi9f6QxaMjitECAwEAAQ==
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA1YZv2Xs5c/fN92CXtOZp
+c4oAlV099Og3mLlsypu1xTyf0eeUhMuqH1dsGWCyLF2Wcha4GJCgWXZ5Fy1nwYBV
+JyF5Ji1Jj3Xssr9locno5dFm0WsdPF7C6SNxKYxk8QkTC6LT6ypv8O1uVqlO+G8t
+C7pRt+qALNJ5pqK7h+KsZqrMk89ztjXfTaK5aeupDYr77479WHVvOXMdQhiizgUF
+9yMA9muRfaNeegR86DPo+1HTX1cvzAl/WE0H90wAiLbo4VrYHS/U79maTQf3LCHZ
+CU0G4gC2+xDNbei+A4Dn7s/nGJckxkkBAaBRJ0lDY1gAdJvCrPeKT34aBUnhg05+
+kl4VHbupVJ7x5DOogxN6iV1veER06vikfpenlxffodT6oLhmhjaMFhhNlc918zkh
+7c4devC7oIzCPnpBgQmK/2tWc4jWbZ7nU64csi9VhkQPLukLruAxtP+0k6opAiVm
+a74T0OyExjfs7p80yNd62aeX7OgKXms0+0xbmxhmboAI2LYGAIaTLRZvf2ZYDSJn
+qNuvkXQmcosz32uS/ZED7i9FWNXdAQrhsxZ/epSf8lelyHcLEPohO6p1ab1dpfWe
++X36GreoiUEnBEiSE1h5n7OWGR4ClJCfssu6q5gQ+2MRFCxVrh5CFJ4ZgT9tkc44
+7Q5TodP5Fcvz/hLhvaX8dtUCAwEAAQ==
-----END PUBLIC KEY-----
diff --git a/certs/ldap/ldap.fripost.org.pem b/certs/ldap/ldap.fripost.org.pem
index f9d9e94..02b1237 100644
--- a/certs/ldap/ldap.fripost.org.pem
+++ b/certs/ldap/ldap.fripost.org.pem
@@ -1,31 +1,12 @@
-----BEGIN CERTIFICATE-----
-MIIFXzCCA0egAwIBAgIJALUdgbcP0QegMA0GCSqGSIb3DQEBCwUAME8xEDAOBgNV
-BAoTB0ZyaXBvc3QxETAPBgNVBAsTCFNTTGNlcnRzMQ0wCwYDVQQLEwRMREFQMRkw
-FwYDVQQDExBsZGFwLmZyaXBvc3Qub3JnMB4XDTE0MDkxMjE2NDM1NloXDTI0MDkw
-OTE2NDM1NlowTzEQMA4GA1UEChMHRnJpcG9zdDERMA8GA1UECxMIU1NMY2VydHMx
-DTALBgNVBAsTBExEQVAxGTAXBgNVBAMTEGxkYXAuZnJpcG9zdC5vcmcwggIiMA0G
-CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCqwdXg+Jst/vZ6NUPfT4DwXCwt7Xl4
-L2txiwGbpHqgC5B2ZcSePpoGCyT1CC7GsFCw+4qSDtB+7kDqDcomZsru1+n3onET
-YC7cSFzs6ks9PtpRMmnWC7184X0bUm6wkvpdJE8tlaqWzkt8S1RlGS/4g5bLKbmz
-ClYz/IrG68yPLWU9MHwlrV79Uf29mwLZGwK1PBV29QOiKDTp1KribRepjiO/bKVd
-+NIrHY8k7rdbZoe4z1Hp/SBdr7WyospSLwbJgNAFXPw/Nju9B/xEkQhDL+DkUR1X
-6JmIik1iAIxv3t1YgctL3Dyc8+RP0vjekrBWUYgRK9dBqia7Etmn7pGB19dqZe6g
-y30OsI9TcpW8Elqwg768QUCYZjwI2LN1SyR/et7hL3FQasjMjJOwqlT/PIQAJsLF
-CdqK+zZKBi/fNpdzJIb7TW7g4p8NJaICU0n9PMsoSdp4yi4n3OEYq6c8fKUuDF1i
-w8pCZE7SHW4qB1Vz5BgZjGmRk+MRzF48VigiZvL+WYoKEvNK7bhXQJ1DACc60j5h
-hrX5mleUANrhgwG72+m7gyZNCo2p15SausLup9ImyImZoQT88xRgz8txsDxe08Oa
-fO7z9dTuenY/tNVYHMkiJ/0RskOs7fDnSRpHzcwzWf1u4iEDS6lEbUWDdkyZ3XEP
-wLoBBaRhexm4mQIDAQABoz4wPDAcBgNVHREEFTATgRFhZG1pbkBmcmlwb3N0Lm9y
-ZzAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwICpDANBgkqhkiG9w0BAQsFAAOC
-AgEAglkIiXCYMajASIjJuVp8e3Eu+k3FKXvW7SPfga6SxcKUTmVPyzNAIVUWXxDq
-3nHArOEgrHW8ZAa9aFvLHKcUFOo9hmFZe+dxCXBK++XSyf2Au8PQ7B+8uznaC8/w
-JhSq+VarhItd3KMcW9ueG8YMCAxL7yahC0NQkMmwdecvdNB1gNRNnefvjhGIGFOJ
-Af5EPSckv+M6f4tFiX8EiabE4t4YW1yHHQ+6SStZL8vBJgT4OCeXaARirGAUiL7K
-xVR55ilO3dOdTEg7/+9ASNqygxtz53flnGltKfzt+QwzFK37WSBvGyp+tvmh6EE7
-XaqhBTYepWoiWJ2oRZsQet3QL4goCQGug0HFhYjW2sIl6TjlczuHXc3ynC6kkTD5
-8fhHNDt2bqXPfWmLqHXFP8RFapj+j/PzSXFH0JgllYGXtJufLXzGfN5Bg+6zpJSo
-COuZcoWw0e4BgNlc3gT8lKDqjK7zBoAVoxxvsOOaDB27T0sWwg3SERZXKD3xn7Jw
-vOIAWYkaQLonYuexW3KUX7OoG9d8HQAOyEkgoU0R6CfwGmK5VbGUQCFAwjF0VHqz
-9rKQrRB5+Oh4wK0dQhtU1m5IuxRrRyV7CX/n79vlBePdUIbDRWgJOvaSD125P+9l
-RHOSUOZ3tq6IltCLetUMM+qgDkVUFvRvXy2tev5ZBFUpJQs=
+MIIBvTCCAW+gAwIBAgIUHA3QvHLOo4JVBaYkVrDL9xv+sdMwBQYDK2VwME8xEDAO
+BgNVBAoMB0ZyaXBvc3QxETAPBgNVBAsMCFNTTGNlcnRzMQ0wCwYDVQQLDARMREFQ
+MRkwFwYDVQQDDBBsZGFwLmZyaXBvc3Qub3JnMB4XDTI0MDkwODE4MzMyM1oXDTM0
+MDkwNjE4MzMyM1owTzEQMA4GA1UECgwHRnJpcG9zdDERMA8GA1UECwwIU1NMY2Vy
+dHMxDTALBgNVBAsMBExEQVAxGTAXBgNVBAMMEGxkYXAuZnJpcG9zdC5vcmcwKjAF
+BgMrZXADIQAvg/MmR2tVDRb0MYcfQ8T9CMm6xNSWLt+2JDpXs7W0x6NdMFswHAYD
+VR0RBBUwE4ERYWRtaW5AZnJpcG9zdC5vcmcwDAYDVR0TAQH/BAIwADAOBgNVHQ8B
+Af8EBAMCBaAwHQYDVR0OBBYEFEJgdyZi8bgHZljJaUT/p8e8ZIWeMAUGAytlcANB
+APqO/lJ6WkT2rr8MG7kG+3IvBa7+KWKCmzV8ew9SoSF+enaCkNjOBtvW85W0lHBT
+i4DzFM0IxdgxgWIEP/NsrgQ=
-----END CERTIFICATE-----
diff --git a/certs/ldap/mx.pem b/certs/ldap/mx.pem
deleted file mode 100644
index 2e6275e..0000000
--- a/certs/ldap/mx.pem
+++ /dev/null
@@ -1,31 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIFaTCCA1GgAwIBAgIJAMFfcQJWxnoSMA0GCSqGSIb3DQEBCwUAMFQxEDAOBgNV
-BAoTB0ZyaXBvc3QxETAPBgNVBAsTCFNTTGNlcnRzMQ0wCwYDVQQLEwRMREFQMREw
-DwYDVQQLEwhTeW5jUmVwbDELMAkGA1UEAxMCbXgwHhcNMTQwOTEyMTY0MzM3WhcN
-MjQwOTA5MTY0MzM3WjBUMRAwDgYDVQQKEwdGcmlwb3N0MREwDwYDVQQLEwhTU0xj
-ZXJ0czENMAsGA1UECxMETERBUDERMA8GA1UECxMIU3luY1JlcGwxCzAJBgNVBAMT
-Am14MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEArdTG5Uh17j85iOs2
-8+92wHtIR/95ic3+E0Ao8KsWNXYduKLGGrLLAh7T9JPMK80M3gF32nZcbTD5pBuW
-NpuClezmCHtPN5ZtTMN6sRl3I/OGhu4vrOkfjOvRNTSByQo3ZC48rcgZbUPTzrCq
-+2eDc3R+TbllGhXB9JyZtM71nIix6c6vuERuj6uPQ64oonNWL5eVPH/Ww8wlTDzp
-Q69ATXQ92KoIILWllN7zqoU6ldVUyNswo0/wZsqDjxajh7s0qQwQLt7jMLV5JGNd
-kWvzyeMJMrmZj5C7Ch54usZh1gdOyf+ZnpnrhCERNOKpkxL59WOrglQPNiKMBZin
-MYVcpeCG3UdFaN59kuExUut8U3AVVflYuDfQIP9iHGdHKsBazqUTfqgLIZyWIMoe
-MdERazvRANPNHBMjIYYLlcWyjDch3k5iY1pyl8jskWi72F82XsiKMkr5H+tjFPve
-H3VaUCY2XNYNI8Ztvn6lifjvA+uVAI084pHZUDQkZFbT4LnLKY79d5IOwE1uXHtf
-6tUu8PHG9HeLZNiGex+kIPhg5gmQmipZwofbXX4xG0Km+3Dz2dWViOQri4n1s5xQ
-G1bWJtVmyDKEfDGF2ZiUZ+dAiih3qit1rTFZoiMqtNgEiahh/8R78Qx2xsCcu/76
-GLg/qh8r+lR1wMkWcoUbToIpARcCAwEAAaM+MDwwHAYDVR0RBBUwE4ERYWRtaW5A
-ZnJpcG9zdC5vcmcwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCAqQwDQYJKoZI
-hvcNAQELBQADggIBAGmCGK8Q32nc1Ltc3S2XCkbMzn4qfFKu1agEk2fBgU1qrVnx
-ioNWcct4trI8hwYwJ7QMQLx8ZdmuBbEyD60k9/qj+SCctrXnSA8p0SSCRUKgwyN0
-L14hvu+7P6G5VfPDNd+T1yqVMbMM2qgNYMHQDmf8e9IFa1DUSYks0v/3YdGwLSxj
-5IoIvc1JxBlGmgRGgG4z5a4v0ikuDc+XAEV0wWT2xF/7CuJnwglpedOgE+l7PLgU
-RQ4uPFQUnFUbcBBE+GLDxXxkOosD7GmAkvppaS8vwA+beqYX8LZMlCqqzXqk+3bp
-FCgQ6IARyYWchp/x4PFy1uGkU8PKsVO4xzQ15WuyaJCy3jqum9TfQUW/ZjRFT+3m
-sEgzarTxqP7CIlCHygVaDj2ALiaMjGbpHGA5JbwMFFaIuzVDj/DEJWKnxu5paJw1
-ERLBmZXhCqtveGmbI08RCMIZjlZ1xLAhFKGRQ4abDTfTlD4QU1EWh+NLHlSRTIg4
-Idbs9QDQH9Eb6p2+scEUL6ci2XGWRjet2wKdCPC3VMNwW/+pXG5YvrvHJBdx8V+F
-w0jWYOg4RQQuB/tAbucj1fvCnj2yMJPCsnlbeN4RPG/xF/89qlSey3kxUfma5eid
-m9kmjWPgXPgUQf+hmefL5HcN7M8zShTdSf81Xa0z3VqJENoQ4v4AqidEjVGY
------END CERTIFICATE-----
diff --git a/certs/ldap/syncrepl/mx@civett.pem b/certs/ldap/syncrepl/mx@civett.pem
new file mode 100644
index 0000000..430c3e6
--- /dev/null
+++ b/certs/ldap/syncrepl/mx@civett.pem
@@ -0,0 +1,12 @@
+-----BEGIN CERTIFICATE-----
+MIIBxzCCAXmgAwIBAgIUKkHGFnwdZ85QwHkb4cCfE8chdFEwBQYDK2VwMFQxEDAO
+BgNVBAoMB0ZyaXBvc3QxETAPBgNVBAsMCFNTTGNlcnRzMQ0wCwYDVQQLDARMREFQ
+MREwDwYDVQQLDAhTeW5jUmVwbDELMAkGA1UEAwwCbXgwHhcNMjQwOTA4MTgzNjU2
+WhcNMzQwOTA2MTgzNjU2WjBUMRAwDgYDVQQKDAdGcmlwb3N0MREwDwYDVQQLDAhT
+U0xjZXJ0czENMAsGA1UECwwETERBUDERMA8GA1UECwwIU3luY1JlcGwxCzAJBgNV
+BAMMAm14MCowBQYDK2VwAyEATR5gkOjpEYhG4e2fRjcowwSWkwLFjWHy1mGEjaru
+/jmjXTBbMBwGA1UdEQQVMBOBEWFkbWluQGZyaXBvc3Qub3JnMAwGA1UdEwEB/wQC
+MAAwDgYDVR0PAQH/BAQDAgWgMB0GA1UdDgQWBBSe9LYpYEdZNz7vx0Pe/LXFCJST
+PDAFBgMrZXADQQC0Isvso/VBCBrQx2uOVRUC8hZiKhKHX3SozqYGgrxlQBjxy8dZ
+cx3gsl4TGw/VWt80BSXQ+TqJHocjoyoy5/oE
+-----END CERTIFICATE-----
diff --git a/certs/ldap/syncrepl/mx@elefant.pem b/certs/ldap/syncrepl/mx@elefant.pem
new file mode 100644
index 0000000..bbd5f56
--- /dev/null
+++ b/certs/ldap/syncrepl/mx@elefant.pem
@@ -0,0 +1,12 @@
+-----BEGIN CERTIFICATE-----
+MIIBxzCCAXmgAwIBAgIUcwEP5HP6psC+HGMXHZBwf3Y/++UwBQYDK2VwMFQxEDAO
+BgNVBAoMB0ZyaXBvc3QxETAPBgNVBAsMCFNTTGNlcnRzMQ0wCwYDVQQLDARMREFQ
+MREwDwYDVQQLDAhTeW5jUmVwbDELMAkGA1UEAwwCbXgwHhcNMjQwOTA4MTgzNTIw
+WhcNMzQwOTA2MTgzNTIwWjBUMRAwDgYDVQQKDAdGcmlwb3N0MREwDwYDVQQLDAhT
+U0xjZXJ0czENMAsGA1UECwwETERBUDERMA8GA1UECwwIU3luY1JlcGwxCzAJBgNV
+BAMMAm14MCowBQYDK2VwAyEAp7jKBb1mYic6E+k7awOmDU2HVV+Ly9BNSqoWPmoG
+XhCjXTBbMBwGA1UdEQQVMBOBEWFkbWluQGZyaXBvc3Qub3JnMAwGA1UdEwEB/wQC
+MAAwDgYDVR0PAQH/BAQDAgWgMB0GA1UdDgQWBBQUeRpdKnUN37/2HJElOEgOiYNp
+IzAFBgMrZXADQQADKZwI8lJT+o2tuJD9tbAyjgJU72IxVRNsV8jkE3SEmI0E6w/3
+gf7T9BSPKe1Z23+Sc7Y5lKwHdxGp0Toao/UL
+-----END CERTIFICATE-----
diff --git a/certs/ssh_known_hosts b/certs/ssh_known_hosts
index 33f8d24..d6918bc 100644
--- a/certs/ssh_known_hosts
+++ b/certs/ssh_known_hosts
@@ -10,5 +10,4 @@ mistral.fripost.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCzGR8+jafHmXZF7b7DuOe8
mistral.fripost.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKtVVGS/t8LBTinXuDIlVthaOTq9fyP79j1nBOchF4A4
calima.fripost.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCWqe+XY9I+a4hemK5wIlwbqdDFC+jMP+nJ0SA5wX+5Lsu1sdj2FO4ziNZ0zluLA/YLyGawaqWhMWSBvDLtYa4KAv/kwzuc0Zifj6KfeBYhQnWaUZWIJp4y0KvZyaw1/QBYyea56j93zI4H0Ea9ay1jPL3kPTF9x8ynKNi34PhrEpXrXzvv9jrCgKwrwG1s5iqznzE5Rg0xJQIoKSOJXE+3xAbAA9ZGYtaFemMG+fcm67isGPYKS7DBmaMEsAQF0ri/qNsQOo7vMhw5lmYRNzehq74GL/njXzugp8cmClRGGk0YNWA0b9qfzHRYocX25OzAEQ1JE3b3cvctVeZcimqj
calima.fripost.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJbr+FgV+fnwbDsFJ/oiM79ku3V8N+SQwxuHxODIpsmk
-levante.fripost.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCkZEj63yRdHiCD/pDRQWW3zmeGt4opXZ8RaIZw0ne1k6L8D+KF1UH9jnmjOoCMnx6BwJU4BsMaywlzIg2a8eDZgQwF1V+NddflHosQyUh086xGVxNTIwMjpywUPYYR5O/Cx2pdSHHK6k9KyWzJv7hfZ6fFBh5b+vBUOLBsismAHI4tBx4DiKwhitBbdZfB+pS+8DEEZatEauD59qCFC8+S/WoSzLchF/d0Qc8plUtCL+wv+bLM6rxkBmfqwsRYw/Py9QT5XDUHCQdUCxyGQV3H7iNgE4R6jiKnF0f3LxV1iJtGm6etoK0KbCvnQbLLfn53qMtdgPvqi+i5J87h+srF
-levante.fripost.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBACec3QwQifr7Pu9ZCgkcv+vYPPAEp0PeYOWpMvOca1
+levante.fripost.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN5mdV1rI/3BUxsGracqSNhn/cywW1o7yyMewICka8+e
diff --git a/group_vars/all.yml b/group_vars/all.yml
index 6d711ec..f780262 100644
--- a/group_vars/all.yml
+++ b/group_vars/all.yml
@@ -2,9 +2,6 @@
non_free_packages:
elefant:
- firmware-bnx2
- levante:
- # for tg3
- - firmware-misc-nonfree
# Virtual (non-routable) IPv4 subnet for IPsec. It is always nullrouted
# in the absence of xfrm lookup (i.e., when there is no matching IPsec
@@ -48,7 +45,7 @@ postfix_instance:
, addr: "{{ (groups.all | length > 1) | ternary( ipsec[ hostvars[groups.lists[0]].inventory_hostname_short ], '127.0.0.1') }}"
, port: 2527 }
-imapsvr_addr: "{{ postfix_instance.IMAP.addr | ipaddr }}"
+imapsvr_addr: "{{ postfix_instance.IMAP.addr | ansible.utils.ipaddr }}"
dkim_keys:
giraff:
@@ -67,6 +64,9 @@ dkim_keys:
"guilhem.org":
d: guilhem.org
s: d32231afe345182ae1a9b376fa912dca
+ "guilhem.se":
+ d: guilhem.se
+ s: 138abf7e73c88d8dc67ca2d26881bc81
"hemdal.se":
d: hemdal.se
s: f032227401564da2cee5d5d0965969c4
@@ -79,6 +79,27 @@ dkim_keys:
"gbg.cmsmarx.org":
d: gbg.cmsmarx.org
s: a4b2e822cfcf594acd24f44587590eb1
+ "r0x.se":
+ d: r0x.se
+ s: 79992d8659ce1c2d3f5a9ad20d167c15
+ "ljhms.se":
+ d: ljhms.se
+ s: 9552b222c0c258daf13bd410f6b5a159
+ "dubre.me":
+ d: dubre.me
+ s: aa813339234ce48d3b3bbfa334fbf48e
+ "himmelkanten.se":
+ d: himmelkanten.se
+ s: caf0355abffeda8264045c3730362147
+ "vimmelkanten.se":
+ d: vimmelkanten.se
+ s: ccb92aa8f79aa6d76b2a9d6ecf6b30e6
+ "hemskaklubben.se":
+ d: hemskaklubben.se
+ s: 564736f16aac6a05b50ea67fd6259e16
+ "kodafritt.se":
+ d: kodafritt.se
+ s: ce3283cc9129cb6692174bd2ec480b88
"~": # catch-all, for our virtual domains
d: x.fripost.org
s: 9df9cdc7e101629b5003b587945afa70
diff --git a/lib/action_plugins/fetch_cmd.py b/lib/action_plugins/fetch_cmd.py
index 57d7220..93960eb 100644
--- a/lib/action_plugins/fetch_cmd.py
+++ b/lib/action_plugins/fetch_cmd.py
@@ -50,7 +50,7 @@ class ActionModule(ActionBase):
local_checksum = checksum(dest)
# calculate checksum for the remote file, don't bother if using become as slurp will be used
- remote_checksum = self._remote_checksum(stdout, all_vars=task_vars)
+ remote_checksum = self._execute_remote_stat(stdout, all_vars=task_vars, follow=True).get('checksum')
if remote_checksum != local_checksum:
makedirs_safe(os.path.dirname(dest))
diff --git a/lib/modules/mysql_user2 b/lib/modules/mysql_user2
deleted file mode 100644
index dc9a69e..0000000
--- a/lib/modules/mysql_user2
+++ /dev/null
@@ -1,495 +0,0 @@
-#!/usr/bin/python3
-
-# (c) 2012, Mark Theunissen <mark.theunissen@gmail.com>
-# Sponsored by Four Kitchens http://fourkitchens.com.
-#
-# This file is part of Ansible
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
-
-DOCUMENTATION = '''
----
-module: mysql_user2
-short_description: Adds or removes a user from a MySQL database.
-description:
- - Adds or removes a user from a MySQL database.
-version_added: "0.6"
-options:
- name:
- description:
- - name of the user (role) to add or remove
- required: true
- default: null
- password:
- description:
- - set the user's password
- required: false
- default: null
- host:
- description:
- - the 'host' part of the MySQL username
- required: false
- default: localhost
- login_user:
- description:
- - The username used to authenticate with
- required: false
- default: null
- login_password:
- description:
- - The password used to authenticate with
- required: false
- default: null
- login_host:
- description:
- - Host running the database
- required: false
- default: localhost
- login_port:
- description:
- - Port of the MySQL server
- required: false
- default: 3306
- version_added: '1.4'
- login_unix_socket:
- description:
- - The path to a Unix domain socket for local connections
- required: false
- default: null
- priv:
- description:
- - "MySQL privileges string in the format: C(db.table:priv1,priv2)"
- required: false
- default: null
- append_privs:
- description:
- - Append the privileges defined by priv to the existing ones for this
- user instead of overwriting existing ones.
- required: false
- choices: [ "yes", "no" ]
- default: "no"
- version_added: "1.4"
- state:
- description:
- - Whether the user should exist. When C(absent), removes
- the user.
- required: false
- default: present
- choices: [ "present", "absent" ]
- check_implicit_admin:
- description:
- - Check if mysql allows login as root/nopassword before trying supplied credentials.
- required: false
- type: bool
- default: no
- version_added: "1.3"
-notes:
- - Requires the MySQLdb Python package on the remote host. For Ubuntu, this
- is as easy as apt-get install python-mysqldb.
- - Both C(login_password) and C(login_username) are required when you are
- passing credentials. If none are present, the module will attempt to read
- the credentials from C(~/.my.cnf), and finally fall back to using the MySQL
- default login of 'root' with no password.
- - "MySQL server installs with default login_user of 'root' and no password. To secure this user
- as part of an idempotent playbook, you must create at least two tasks: the first must change the root user's password,
- without providing any login_user/login_password details. The second must drop a ~/.my.cnf file containing
- the new root credentials. Subsequent runs of the playbook will then succeed by reading the new credentials from
- the file."
-
-requirements: [ "ConfigParser", "MySQLdb" ]
-author: Mark Theunissen
-'''
-
-EXAMPLES = """
-# Create database user with name 'bob' and password '12345' with all database privileges
-- mysql_user: name=bob password=12345 priv=*.*:ALL state=present
-
-# Ensure no user named 'sally' exists, also passing in the auth credentials.
-- mysql_user: login_user=root login_password=123456 name=sally state=absent
-
-# Example privileges string format
-mydb.*:INSERT,UPDATE/anotherdb.*:SELECT/yetanotherdb.*:ALL
-
-# Example using login_unix_socket to connect to server
-- mysql_user: name=root password=abc123 login_unix_socket=/var/run/mysqld/mysqld.sock
-
-# Example .my.cnf file for setting the root password
-# Note: don't use quotes around the password, because the mysql_user module
-# will include them in the password but the mysql client will not
-
-[client]
-user=root
-password=n<_665{vS43y
-"""
-
-import ConfigParser
-import getpass
-import tempfile
-try:
- import MySQLdb
-except ImportError:
- mysqldb_found = False
-else:
- mysqldb_found = True
-
-# ===========================================
-# MySQL module specific support methods.
-#
-
-def user_exists(cursor, user, host):
- cursor.execute("SELECT count(*) FROM user WHERE user = %s AND host = %s", (user,host))
- count = cursor.fetchone()
- return count[0] > 0
-
-def load_plugin(cursor, plugin, soname):
- cursor.execute("SELECT count(*) FROM information_schema.plugins WHERE plugin_name = %s", plugin)
- count = cursor.fetchone()
- if count[0] == 0:
- if soname is None:
- module.fail_json(msg="missing plugin 'soname' parameter")
- cursor.execute("INSTALL PLUGIN %s SONAME %s", (plugin, soname))
-
-def user_add(cursor, user, host, password, new_priv, auth_plugin, soname):
- if password is None:
- # Automatically loaded on first first use.
- load_plugin(cursor, auth_plugin, soname)
- cursor.execute("CREATE USER %s@%s IDENTIFIED WITH %s", (user,host,auth_plugin))
- else:
- cursor.execute("CREATE USER %s@%s IDENTIFIED BY %s", (user,host,password))
- if new_priv is not None:
- for db_table, priv in new_priv.iteritems():
- privileges_grant(cursor, user,host,db_table,priv)
- return True
-
-def user_mod(cursor, user, host, password, new_priv, append_privs, auth_plugin):
- changed = False
- grant_option = False
-
- # Handle plugin.
- if auth_plugin is not None:
- cursor.execute("SELECT plugin FROM user WHERE user = %s AND host = %s", (user,host))
- if cursor.fetchone()[0] != auth_plugin:
- # Sadly there is no proper way to updade the authentication plugin:
- # http://bugs.mysql.com/bug.php?id=67449
- cursor.execute( "UPDATE user SET plugin = %s, password = '' WHERE user = %s AND host = %s"
- , (auth_plugin,user,host))
- cursor.execute("FLUSH PRIVILEGES")
- changed = True
-
- # Handle passwords.
- if password is not None:
- cursor.execute("SELECT password FROM user WHERE user = %s AND host = %s", (user,host))
- current_pass_hash = cursor.fetchone()
- cursor.execute("SELECT PASSWORD(%s)", (password,))
- new_pass_hash = cursor.fetchone()
- if current_pass_hash[0] != new_pass_hash[0]:
- cursor.execute("SET PASSWORD FOR %s@%s = PASSWORD(%s)", (user,host,password))
- changed = True
-
- # Handle privileges.
- if new_priv is not None:
- curr_priv = privileges_get(cursor, user,host)
-
- # If the user has privileges on a db.table that doesn't appear at all in
- # the new specification, then revoke all privileges on it.
- for db_table, priv in curr_priv.iteritems():
- # If the user has the GRANT OPTION on a db.table, revoke it first.
- if "GRANT" in priv:
- grant_option = True
- if db_table not in new_priv:
- if user != "root" and "PROXY" not in priv and not append_privs:
- privileges_revoke(cursor, user,host,db_table,grant_option)
- changed = True
-
- # If the user doesn't currently have any privileges on a db.table, then
- # we can perform a straight grant operation.
- for db_table, priv in new_priv.iteritems():
- if db_table not in curr_priv:
- privileges_grant(cursor, user,host,db_table,priv)
- changed = True
-
- # If the db.table specification exists in both the user's current privileges
- # and in the new privileges, then we need to see if there's a difference.
- db_table_intersect = set(new_priv.keys()) & set(curr_priv.keys())
- for db_table in db_table_intersect:
- priv_diff = set(new_priv[db_table]) ^ set(curr_priv[db_table])
- if (len(priv_diff) > 0):
- privileges_revoke(cursor, user,host,db_table,grant_option)
- privileges_grant(cursor, user,host,db_table,new_priv[db_table])
- changed = True
-
- return changed
-
-def user_delete(cursor, user, host):
- cursor.execute("DROP USER %s@%s", (user,host))
- return True
-
-def privileges_get(cursor, user,host):
- """ MySQL doesn't have a better method of getting privileges aside from the
- SHOW GRANTS query syntax, which requires us to then parse the returned string.
- Here's an example of the string that is returned from MySQL:
-
- GRANT USAGE ON *.* TO 'user'@'localhost' IDENTIFIED BY 'pass';
-
- This function makes the query and returns a dictionary containing the results.
- The dictionary format is the same as that returned by privileges_unpack() below.
- """
- output = {}
- cursor.execute("SHOW GRANTS FOR %s@%s", (user,host))
- grants = cursor.fetchall()
-
- def pick(x):
- if x == 'ALL PRIVILEGES':
- return 'ALL'
- else:
- return x
-
- for grant in grants:
- res = re.match("GRANT (.+) ON (.+) TO '.+'@'.+'( IDENTIFIED BY PASSWORD '.+')? ?(.*)", grant[0])
- if res is None:
- module.fail_json(msg="unable to parse the MySQL grant string")
- privileges = res.group(1).split(", ")
- privileges = [ pick(x) for x in privileges]
- if "WITH GRANT OPTION" in res.group(4):
- privileges.append('GRANT')
- db = res.group(2)
- output[db] = privileges
- return output
-
-def privileges_unpack(priv):
- """ Take a privileges string, typically passed as a parameter, and unserialize
- it into a dictionary, the same format as privileges_get() above. We have this
- custom format to avoid using YAML/JSON strings inside YAML playbooks. Example
- of a privileges string:
-
- mydb.*:INSERT,UPDATE/anotherdb.*:SELECT/yetanother.*:ALL
-
- The privilege USAGE stands for no privileges, so we add that in on *.* if it's
- not specified in the string, as MySQL will always provide this by default.
- """
- output = {}
- for item in priv.split('/'):
- pieces = item.split(':')
- if pieces[0].find('.') != -1:
- pieces[0] = pieces[0].split('.')
- for idx, piece in enumerate(pieces):
- if pieces[0][idx] != "*":
- pieces[0][idx] = "`" + pieces[0][idx] + "`"
- pieces[0] = '.'.join(pieces[0])
-
- output[pieces[0]] = [ g.strip() for g in pieces[1].upper().split(',') ]
-
- if '*.*' not in output:
- output['*.*'] = ['USAGE']
-
- return output
-
-def privileges_revoke(cursor, user,host,db_table,grant_option):
- if grant_option:
- query = "REVOKE GRANT OPTION ON %s FROM '%s'@'%s'" % (db_table,user,host)
- cursor.execute(query)
- query = "REVOKE ALL PRIVILEGES ON %s FROM '%s'@'%s'" % (db_table,user,host)
- cursor.execute(query)
-
-def privileges_grant(cursor, user,host,db_table,priv):
-
- priv_string = ",".join(filter(lambda x: x != 'GRANT', priv))
- query = "GRANT %s ON %s TO '%s'@'%s'" % (priv_string,db_table,user,host)
- if 'GRANT' in priv:
- query = query + " WITH GRANT OPTION"
- cursor.execute(query)
-
-
-def strip_quotes(s):
- """ Remove surrounding single or double quotes
-
- >>> print strip_quotes('hello')
- hello
- >>> print strip_quotes('"hello"')
- hello
- >>> print strip_quotes("'hello'")
- hello
- >>> print strip_quotes("'hello")
- 'hello
-
- """
- single_quote = "'"
- double_quote = '"'
-
- if s.startswith(single_quote) and s.endswith(single_quote):
- s = s.strip(single_quote)
- elif s.startswith(double_quote) and s.endswith(double_quote):
- s = s.strip(double_quote)
- return s
-
-
-def config_get(config, section, option):
- """ Calls ConfigParser.get and strips quotes
-
- See: http://dev.mysql.com/doc/refman/5.0/en/option-files.html
- """
- return strip_quotes(config.get(section, option))
-
-
-def _safe_cnf_load(config, path):
-
- data = {'user':'', 'password':''}
-
- # read in user/pass
- f = open(path, 'r')
- for line in f.readlines():
- line = line.strip()
- if line.startswith('user='):
- data['user'] = line.split('=', 1)[1].strip()
- if line.startswith('password=') or line.startswith('pass='):
- data['password'] = line.split('=', 1)[1].strip()
- f.close()
-
- # write out a new cnf file with only user/pass
- fh, newpath = tempfile.mkstemp(prefix=path + '.')
- f = open(newpath, 'wb')
- f.write('[client]\n')
- f.write('user=%s\n' % data['user'])
- f.write('password=%s\n' % data['password'])
- f.close()
-
- config.readfp(open(newpath))
- os.remove(newpath)
- return config
-
-def load_mycnf():
- config = ConfigParser.RawConfigParser()
- mycnf = os.path.expanduser('~/.my.cnf')
- if not os.path.exists(mycnf):
- return False
- try:
- config.readfp(open(mycnf))
- except (IOError):
- return False
- except:
- config = _safe_cnf_load(config, mycnf)
-
- # We support two forms of passwords in .my.cnf, both pass= and password=,
- # as these are both supported by MySQL.
- try:
- passwd = config_get(config, 'client', 'password')
- except (ConfigParser.NoOptionError):
- try:
- passwd = config_get(config, 'client', 'pass')
- except (ConfigParser.NoOptionError):
- return False
-
- # If .my.cnf doesn't specify a user, default to user login name
- try:
- user = config_get(config, 'client', 'user')
- except (ConfigParser.NoOptionError):
- user = getpass.getuser()
- creds = dict(user=user,passwd=passwd)
- return creds
-
-def connect(module, login_user, login_password):
- if module.params["login_unix_socket"]:
- db_connection = MySQLdb.connect(host=module.params["login_host"], unix_socket=module.params["login_unix_socket"], user=login_user, passwd=login_password, db="mysql")
- else:
- db_connection = MySQLdb.connect(host=module.params["login_host"], port=int(module.params["login_port"]), user=login_user, passwd=login_password, db="mysql")
- return db_connection.cursor()
-
-# ===========================================
-# Module execution.
-#
-
-def main():
- module = AnsibleModule(
- argument_spec = dict(
- login_user=dict(default=None),
- login_password=dict(default=None, no_log=True),
- login_host=dict(default="localhost"),
- login_port=dict(default=3306, type='int'),
- login_unix_socket=dict(default=None),
- user=dict(required=True, aliases=['name']),
- password=dict(default=None, no_log=True, type='str'),
- host=dict(default="localhost"),
- state=dict(default="present", choices=["absent", "present"]),
- priv=dict(default=None),
- append_privs=dict(default=False, type="bool"),
- check_implicit_admin=dict(default=False, type="bool"),
- auth_plugin=dict(default=None),
- soname=dict(default=None)
- )
- )
- user = module.params["user"]
- password = module.params["password"]
- host = module.params["host"]
- state = module.params["state"]
- priv = module.params["priv"]
- check_implicit_admin = module.params['check_implicit_admin']
- append_privs = module.boolean(module.params["append_privs"])
- auth_plugin = module.params['auth_plugin']
- soname = module.params['soname']
-
- if not mysqldb_found:
- module.fail_json(msg="the python mysqldb module is required")
-
- if priv is not None:
- try:
- priv = privileges_unpack(priv)
- except:
- module.fail_json(msg="invalid privileges string")
-
- # Either the caller passes both a username and password with which to connect to
- # mysql, or they pass neither and allow this module to read the credentials from
- # ~/.my.cnf.
- login_password = module.params["login_password"]
- login_user = module.params["login_user"]
- if login_user is None and login_password is None:
- mycnf_creds = load_mycnf()
- if mycnf_creds is False:
- login_user = "root"
- login_password = ""
- else:
- login_user = mycnf_creds["user"]
- login_password = mycnf_creds["passwd"]
- elif login_password is None or login_user is None:
- module.fail_json(msg="when supplying login arguments, both login_user and login_password must be provided")
-
- cursor = None
- try:
- if check_implicit_admin:
- try:
- cursor = connect(module, 'root', '')
- except:
- pass
-
- if not cursor:
- cursor = connect(module, login_user, login_password)
- except Exception as e:
- module.fail_json(msg="unable to connect to database, check login_user and login_password are correct or ~/.my.cnf has the credentials")
-
- if state == "present":
- if user_exists(cursor, user, host):
- changed = user_mod(cursor, user, host, password, priv, append_privs, auth_plugin)
- else:
- if (password is None and auth_plugin is None) or (password is not None and auth_plugin is not None):
- module.fail_json(msg="password xor auth_plugin is required when adding a user")
- changed = user_add(cursor, user, host, password, priv, auth_plugin, soname)
- elif state == "absent":
- if user_exists(cursor, user, host):
- changed = user_delete(cursor, user, host)
- else:
- changed = False
- module.exit_json(changed=changed, user=user)
-
-# this is magic, see lib/ansible/module_common.py
-#<<INCLUDE_ANSIBLE_MODULE_COMMON>>
-main()
diff --git a/lib/modules/openldap b/lib/modules/openldap
index 219c9a6..c09e791 100644
--- a/lib/modules/openldap
+++ b/lib/modules/openldap
@@ -49,10 +49,10 @@ indexedAttributes = frozenset([
# ('%s' in the attribute value is replaced with the value of the source
# entry.)
indexedDN = {
- 'olcSchemaConfig': [('cn', '{*}%s')],
- 'olcMdbConfig': [('olcDbDirectory', '%s' )],
- 'olcOverlayConfig': [('olcOverlay', '%s' )],
- 'olcMonitorConfig': [],
+ b'olcSchemaConfig': [('cn', '{*}%s')],
+ b'olcMdbConfig': [('olcDbDirectory', '%s' )],
+ b'olcOverlayConfig': [('olcOverlay', '%s' )],
+ b'olcMonitorConfig': [],
}
# Allow for flexible ACLs for user using SASL's EXTERNAL mechanism.
@@ -60,23 +60,23 @@ indexedDN = {
# "gidNumber=106+uidNumber=102,cn=peercred,cn=external,cn=auth" where
# 102 is postfix's UID and 106 its primary GID.
# (Regular expressions are not allowed.)
-sasl_ext_re = re.compile( r"""(?P<start>\sby\s+dn(?:\.exact)?)=
+sasl_ext_re = re.compile( b"""(?P<start>\sby\s+dn(?:\.exact)?)=
(?P<quote>['\"]?)username=(?P<user>_?[a-z][-a-z0-9_]*),
(?P<end>cn=peercred,cn=external,cn=auth)
(?P=quote)\s"""
, re.VERBOSE )
-multispaces = re.compile( r"\s+" )
+multispaces = re.compile( b"\s+" )
pwd_dict = {}
def acl_sasl_ext(m):
- u = m.group('user')
+ u = m.group('user').decode("utf-8")
if u not in pwd_dict.keys():
pwd_dict[u] = pwd.getpwnam(u)
- return '%s="gidNumber=%d+uidNumber=%d,%s" ' % ( m.group('start')
- , pwd_dict[u].pw_gid
- , pwd_dict[u].pw_uid
- , m.group('end')
- )
+ return b'%s="gidNumber=%d+uidNumber=%d,%s" ' % ( m.group('start')
+ , pwd_dict[u].pw_gid
+ , pwd_dict[u].pw_uid
+ , m.group('end')
+ )
# Run the given callback on each DN seen. If its return value is not
@@ -109,14 +109,14 @@ def flexibleSearch(module, l, dn, entry):
scope = ldap.SCOPE_ONELEVEL
f = []
for c in idxClasses:
- f.append ( filter_format('objectClass=%s', [c]) )
+ f.append ( filter_format('objectClass=%s', [c.decode("utf-8")]) )
for a,v in indexedDN[c]:
if a == h:
v2 = t
elif a not in entry.keys() or len(entry[a]) > 1:
module.fail_json(msg="Multiple values found! This is a bug. Please report.")
else:
- v2 = entry[a][0]
+ v2 = entry[a][0].decode("utf-8")
f.append ( filter_format(a+'='+v, [v2]) )
if len(f) == 1:
f = f[0]
@@ -139,7 +139,7 @@ def processEntry(module, l, dn, entry):
for x in indexedAttributes.intersection(entry.keys()):
# remove useless extra spaces in ACLs etc
- entry[x] = list(map( partial(multispaces.sub, ' '), entry[x] ))
+ entry[x] = list(map( partial(multispaces.sub, b' '), entry[x] ))
r = flexibleSearch( module, l, dn, entry )
if r is None:
@@ -156,7 +156,7 @@ def processEntry(module, l, dn, entry):
d,e = r
fst = str2dn(dn).pop(0)[0][0]
diff = []
- for a,v in e.iteritems():
+ for a,v in e.items():
if a not in entry.keys():
if a != fst:
# delete all values except for the first attribute,
@@ -169,7 +169,7 @@ def processEntry(module, l, dn, entry):
entry[a] = list(map ( partial(sasl_ext_re.sub, acl_sasl_ext)
, entry[a] ))
# add explicit indices in the entry from the LDIF
- entry[a] = list(map( (lambda x: '{%d}%s' % x)
+ entry[a] = list(map( (lambda x: b'{%d}%s' % x)
, zip(range(len(entry[a])),entry[a])))
if v != entry[a]:
diff.append(( ldap.MOD_REPLACE, a, entry[a] ))
@@ -231,31 +231,31 @@ def getDN_DB(module, l, a, v, attrlist=['']):
# Convert a *.schema file into *.ldif format. The algorithm can be found
# in /etc/ldap/schema/openldap.ldif .
def slapd_to_ldif(src, name):
- s = open( src, 'r' )
+ s = open( src, 'rb' )
d = tempfile.NamedTemporaryFile(delete=False)
atexit.register(lambda: os.unlink( d.name ))
- d.write('dn: cn=%s,cn=schema,cn=config\n' % name)
- d.write('objectClass: olcSchemaConfig\n')
+ d.write(b'dn: cn=%s,cn=schema,cn=config\n' % name.encode("utf-8"))
+ d.write(b'objectClass: olcSchemaConfig\n')
- re1 = re.compile( r'^objectIdentifier\s(.*)', re.I )
- re2 = re.compile( r'^objectClass\s(.*)', re.I )
- re3 = re.compile( r'^attributeType\s(.*)', re.I )
- reSp = re.compile( r'^\s+' )
+ re1 = re.compile( b'^objectIdentifier\s(.*)', re.I )
+ re2 = re.compile( b'^objectClass\s(.*)', re.I )
+ re3 = re.compile( b'^attributeType\s(.*)', re.I )
+ reSp = re.compile( b'^\s+' )
for line in s.readlines():
- if line == '\n':
- line = '#\n'
+ if line == b'\n':
+ line = b'#\n'
m1 = re1.match(line)
m2 = re2.match(line)
m3 = re3.match(line)
if m1 is not None:
- line = 'olcObjectIdentifier: %s' % m1.group(1)
+ line = b'olcObjectIdentifier: %s' % m1.group(1)
elif m2 is not None:
- line = 'olcObjectClasses: %s' % m2.group(1)
+ line = b'olcObjectClasses: %s' % m2.group(1)
elif m3 is not None:
- line = 'olcAttributeTypes: %s' % m3.group(1)
+ line = b'olcAttributeTypes: %s' % m3.group(1)
- d.write( reSp.sub(line, ' ') )
+ d.write( reSp.sub(line, b' ') )
s.close()
diff --git a/lib/modules/postmulti b/lib/modules/postmulti
index 3c0a522..e6f58e3 100644
--- a/lib/modules/postmulti
+++ b/lib/modules/postmulti
@@ -30,7 +30,7 @@ def postconf(k, instance=None):
cmd.extend([ os.path.join(os.sep, 'usr', 'sbin', 'postconf')
, '-h', k ])
- return subprocess.check_output(cmd, stderr=subprocess.STDOUT).rstrip()
+ return subprocess.check_output(cmd, stderr=subprocess.STDOUT).rstrip().decode("utf-8")
# To destroy an existing instance:
@@ -55,7 +55,7 @@ def main():
enable = postconf('multi_instance_enable')
wrapper = postconf('multi_instance_wrapper')
- if enable != "yes" or not wrapper:
+ if enable != "yes" or wrapper == "":
# Initiate postmulti
changed = True
if module.check_mode:
diff --git a/production b/production
index a35d2a6..970dafa 100644
--- a/production
+++ b/production
@@ -76,7 +76,6 @@ levante
[backports:children]
-webmail
# machines behind NAT
[NATed:children]
diff --git a/roles/IMAP/files/etc/dovecot/conf.d/10-auth.conf b/roles/IMAP/files/etc/dovecot/conf.d/10-auth.conf
index 7213fbb..f34bdeb 100644
--- a/roles/IMAP/files/etc/dovecot/conf.d/10-auth.conf
+++ b/roles/IMAP/files/etc/dovecot/conf.d/10-auth.conf
@@ -10,7 +10,7 @@
#disable_plaintext_auth = yes
# Authentication cache size (e.g. 10M). 0 means it's disabled. Note that
-# bsdauth, PAM and vpopmail require cache_key to be set for caching to be used.
+# bsdauth and PAM require cache_key to be set for caching to be used.
#auth_cache_size = 0
# Time to live for cached data. After TTL expires the cached record is no
# longer used, *except* if the main database lookup returns internal failure.
@@ -30,7 +30,7 @@
# Default realm/domain to use if none was specified. This is used for both
# SASL realms and appending @domain to username in plaintext logins.
-auth_default_realm = fripost.org
+#auth_default_realm =
# List of allowed characters in username. If the user-given username contains
# a character not listed in here, the login automatically fails. This is just
@@ -48,7 +48,7 @@ auth_default_realm = fripost.org
# the standard variables here, eg. %Lu would lowercase the username, %n would
# drop away the domain if it was given, or "%n-AT-%d" would change the '@' into
# "-AT-". This translation is done after auth_username_translation changes.
-auth_username_format = %Lu
+#auth_username_format = %Lu
# If you want to allow master users to log in by specifying the master
# username within the normal username string (ie. not using SASL mechanism's
@@ -73,7 +73,7 @@ auth_username_format = %Lu
# Kerberos keytab to use for the GSSAPI mechanism. Will use the system
# default (usually /etc/krb5.keytab) if not specified. You may need to change
# the auth service to run as root to be able to read this file.
-#auth_krb5_keytab =
+#auth_krb5_keytab =
# Do NTLM and GSS-SPNEGO authentication using Samba's winbind daemon and
# ntlm_auth helper. <doc/wiki/Authentication/Mechanisms/Winbind.txt>
@@ -88,16 +88,16 @@ auth_username_format = %Lu
# Require a valid SSL client certificate or the authentication fails.
#auth_ssl_require_client_cert = no
-# Take the username from client's SSL certificate, using
+# Take the username from client's SSL certificate, using
# X509_NAME_get_text_by_NID() which returns the subject's DN's
-# CommonName.
+# CommonName.
#auth_ssl_username_from_cert = no
# Space separated list of wanted authentication mechanisms:
-# plain login digest-md5 cram-md5 ntlm rpa apop anonymous gssapi otp skey
+# plain login digest-md5 cram-md5 ntlm rpa apop anonymous gssapi otp
# gss-spnego
# NOTE: See also disable_plaintext_auth setting.
-auth_mechanisms = plain login
+auth_mechanisms = plain
##
## Password and user databases
@@ -124,5 +124,4 @@ auth_mechanisms = plain login
!include auth-ldap.conf.ext
#!include auth-passwdfile.conf.ext
#!include auth-checkpassword.conf.ext
-#!include auth-vpopmail.conf.ext
#!include auth-static.conf.ext
diff --git a/roles/IMAP/files/etc/dovecot/conf.d/10-mail.conf b/roles/IMAP/files/etc/dovecot/conf.d/10-mail.conf
deleted file mode 100644
index d74b026..0000000
--- a/roles/IMAP/files/etc/dovecot/conf.d/10-mail.conf
+++ /dev/null
@@ -1,427 +0,0 @@
-##
-## Mailbox locations and namespaces
-##
-
-# Location for users' mailboxes. The default is empty, which means that Dovecot
-# tries to find the mailboxes automatically. This won't work if the user
-# doesn't yet have any mail, so you should explicitly tell Dovecot the full
-# location.
-#
-# If you're using mbox, giving a path to the INBOX file (eg. /var/mail/%u)
-# isn't enough. You'll also need to tell Dovecot where the other mailboxes are
-# kept. This is called the "root mail directory", and it must be the first
-# path given in the mail_location setting.
-#
-# There are a few special variables you can use, eg.:
-#
-# %u - username
-# %n - user part in user@domain, same as %u if there's no domain
-# %d - domain part in user@domain, empty if there's no domain
-# %h - home directory
-#
-# See doc/wiki/Variables.txt for full list. Some examples:
-#
-# mail_location = maildir:~/Maildir
-# mail_location = mbox:~/mail:INBOX=/var/mail/%u
-# mail_location = mbox:/var/mail/%d/%1n/%n:INDEX=/var/indexes/%d/%1n/%n
-#
-# <doc/wiki/MailLocation.txt>
-#
-mail_location = mdbox:~/mail
-
-# If you need to set multiple mailbox locations or want to change default
-# namespace settings, you can do it by defining namespace sections.
-#
-# You can have private, shared and public namespaces. Private namespaces
-# are for user's personal mails. Shared namespaces are for accessing other
-# users' mailboxes that have been shared. Public namespaces are for shared
-# mailboxes that are managed by sysadmin. If you create any shared or public
-# namespaces you'll typically want to enable ACL plugin also, otherwise all
-# users can access all the shared mailboxes, assuming they have permissions
-# on filesystem level to do so.
-namespace inbox {
- # Namespace type: private, shared or public
- #type = private
-
- # Hierarchy separator to use. You should use the same separator for all
- # namespaces or some clients get confused. '/' is usually a good one.
- # The default however depends on the underlying mail storage format.
- separator = /
-
- # Prefix required to access this namespace. This needs to be different for
- # all namespaces. For example "Public/".
- #prefix =
-
- # Physical location of the mailbox. This is in same format as
- # mail_location, which is also the default for it.
- #location =
-
- # There can be only one INBOX, and this setting defines which namespace
- # has it.
- inbox = yes
-
- # If namespace is hidden, it's not advertised to clients via NAMESPACE
- # extension. You'll most likely also want to set list=no. This is mostly
- # useful when converting from another server with different namespaces which
- # you want to deprecate but still keep working. For example you can create
- # hidden namespaces with prefixes "~/mail/", "~%u/mail/" and "mail/".
- #hidden = no
-
- # Show the mailboxes under this namespace with LIST command. This makes the
- # namespace visible for clients that don't support NAMESPACE extension.
- # "children" value lists child mailboxes, but hides the namespace prefix.
- #list = yes
-
- # Namespace handles its own subscriptions. If set to "no", the parent
- # namespace handles them (empty prefix should always have this as "yes")
- #subscriptions = yes
-}
-
-namespace virtual {
- prefix = virtual/
- separator = /
- location = virtual:/etc/dovecot/virtual:INDEX=MEMORY
- list = no
- hidden = no
- subscriptions = no
-}
-
-# Example shared namespace configuration
-#namespace {
- #type = shared
- #separator = /
-
- # Mailboxes are visible under "shared/user@domain/"
- # %%n, %%d and %%u are expanded to the destination user.
- #prefix = shared/%%u/
-
- # Mail location for other users' mailboxes. Note that %variables and ~/
- # expands to the logged in user's data. %%n, %%d, %%u and %%h expand to the
- # destination user's data.
- #location = maildir:%%h/Maildir:INDEX=~/Maildir/shared/%%u
-
- # Use the default namespace for saving subscriptions.
- #subscriptions = no
-
- # List the shared/ namespace only if there are visible shared mailboxes.
- #list = children
-#}
-# Should shared INBOX be visible as "shared/user" or "shared/user/INBOX"?
-#mail_shared_explicit_inbox = no
-
-# System user and group used to access mails. If you use multiple, userdb
-# can override these by returning uid or gid fields. You can use either numbers
-# or names. <doc/wiki/UserIds.txt>
-mail_uid = vmail
-mail_gid = vmail
-
-# Group to enable temporarily for privileged operations. Currently this is
-# used only with INBOX when either its initial creation or dotlocking fails.
-# Typically this is set to "mail" to give access to /var/mail.
-mail_privileged_group =
-
-# Grant access to these supplementary groups for mail processes. Typically
-# these are used to set up access to shared mailboxes. Note that it may be
-# dangerous to set these if users can create symlinks (e.g. if "mail" group is
-# set here, ln -s /var/mail ~/mail/var could allow a user to delete others'
-# mailboxes, or ln -s /secret/shared/box ~/mail/mybox would allow reading it).
-#mail_access_groups =
-
-# Allow full filesystem access to clients. There's no access checks other than
-# what the operating system does for the active UID/GID. It works with both
-# maildir and mboxes, allowing you to prefix mailboxes names with eg. /path/
-# or ~user/.
-#mail_full_filesystem_access = no
-
-# Dictionary for key=value mailbox attributes. This is used for example by
-# URLAUTH and METADATA extensions.
-#mail_attribute_dict =
-
-# A comment or note that is associated with the server. This value is
-# accessible for authenticated users through the IMAP METADATA server
-# entry "/shared/comment".
-mail_server_comment = "fripost - demokratisk e-post"
-
-# Indicates a method for contacting the server administrator. According to
-# RFC 5464, this value MUST be a URI (e.g., a mailto: or tel: URL), but that
-# is currently not enforced. Use for example mailto:admin@example.com. This
-# value is accessible for authenticated users through the IMAP METADATA server
-# entry "/shared/admin".
-mail_server_admin = mailto:postmaster@fripost.org
-
-##
-## Mail processes
-##
-
-# Don't use mmap() at all. This is required if you store indexes to shared
-# filesystems (NFS or clustered filesystem).
-#mmap_disable = no
-
-# Rely on O_EXCL to work when creating dotlock files. NFS supports O_EXCL
-# since version 3, so this should be safe to use nowadays by default.
-#dotlock_use_excl = yes
-
-# When to use fsync() or fdatasync() calls:
-# optimized (default): Whenever necessary to avoid losing important data
-# always: Useful with e.g. NFS when write()s are delayed
-# never: Never use it (best performance, but crashes can lose data)
-#mail_fsync = optimized
-
-# Locking method for index files. Alternatives are fcntl, flock and dotlock.
-# Dotlocking uses some tricks which may create more disk I/O than other locking
-# methods. NFS users: flock doesn't work, remember to change mmap_disable.
-#lock_method = fcntl
-
-# Directory where mails can be temporarily stored. Usually it's used only for
-# mails larger than >= 128 kB. It's used by various parts of Dovecot, for
-# example LDA/LMTP while delivering large mails or zlib plugin for keeping
-# uncompressed mails.
-#mail_temp_dir = /tmp
-
-# Valid UID range for users, defaults to 500 and above. This is mostly
-# to make sure that users can't log in as daemons or other system users.
-# Note that denying root logins is hardcoded to dovecot binary and can't
-# be done even if first_valid_uid is set to 0.
-first_valid_uid = 1
-#last_valid_uid = 0
-
-# Valid GID range for users, defaults to non-root/wheel. Users having
-# non-valid GID as primary group ID aren't allowed to log in. If user
-# belongs to supplementary groups with non-valid GIDs, those groups are
-# not set.
-#first_valid_gid = 1
-#last_valid_gid = 0
-
-# Maximum allowed length for mail keyword name. It's only forced when trying
-# to create new keywords.
-#mail_max_keyword_length = 50
-
-# ':' separated list of directories under which chrooting is allowed for mail
-# processes (ie. /var/mail will allow chrooting to /var/mail/foo/bar too).
-# This setting doesn't affect login_chroot, mail_chroot or auth chroot
-# settings. If this setting is empty, "/./" in home dirs are ignored.
-# WARNING: Never add directories here which local users can modify, that
-# may lead to root exploit. Usually this should be done only if you don't
-# allow shell access for users. <doc/wiki/Chrooting.txt>
-#valid_chroot_dirs =
-
-# Default chroot directory for mail processes. This can be overridden for
-# specific users in user database by giving /./ in user's home directory
-# (eg. /home/./user chroots into /home). Note that usually there is no real
-# need to do chrooting, Dovecot doesn't allow users to access files outside
-# their mail directory anyway. If your home directories are prefixed with
-# the chroot directory, append "/." to mail_chroot. <doc/wiki/Chrooting.txt>
-#mail_chroot =
-
-# UNIX socket path to master authentication server to find users.
-# This is used by imap (for shared users) and lda.
-#auth_socket_path = /var/run/dovecot/auth-userdb
-
-# Directory where to look up mail plugins.
-#mail_plugin_dir = /usr/lib/dovecot/modules
-
-# Space separated list of plugins to load for all services. Plugins specific to
-# IMAP, LDA, etc. are added to this list in their own .conf files.
-mail_plugins = quota virtual zlib
-
-##
-## Mailbox handling optimizations
-##
-
-# Mailbox list indexes can be used to optimize IMAP STATUS commands. They are
-# also required for IMAP NOTIFY extension to be enabled.
-#mailbox_list_index = yes
-
-# Trust mailbox list index to be up-to-date. This reduces disk I/O at the cost
-# of potentially returning out-of-date results after e.g. server crashes.
-# The results will be automatically fixed once the folders are opened.
-#mailbox_list_index_very_dirty_syncs = yes
-
-# Should INBOX be kept up-to-date in the mailbox list index? By default it's
-# not, because most of the mailbox accesses will open INBOX anyway.
-#mailbox_list_index_include_inbox = no
-
-# The minimum number of mails in a mailbox before updates are done to cache
-# file. This allows optimizing Dovecot's behavior to do less disk writes at
-# the cost of more disk reads.
-#mail_cache_min_mail_count = 0
-
-# When IDLE command is running, mailbox is checked once in a while to see if
-# there are any new mails or other changes. This setting defines the minimum
-# time to wait between those checks. Dovecot can also use inotify and
-# kqueue to find out immediately when changes occur.
-#mailbox_idle_check_interval = 30 secs
-
-# Save mails with CR+LF instead of plain LF. This makes sending those mails
-# take less CPU, especially with sendfile() syscall with Linux and FreeBSD.
-# But it also creates a bit more disk I/O which may just make it slower.
-# Also note that if other software reads the mboxes/maildirs, they may handle
-# the extra CRs wrong and cause problems.
-#mail_save_crlf = no
-
-# Max number of mails to keep open and prefetch to memory. This only works with
-# some mailbox formats and/or operating systems.
-#mail_prefetch_count = 0
-
-# How often to scan for stale temporary files and delete them (0 = never).
-# These should exist only after Dovecot dies in the middle of saving mails.
-#mail_temp_scan_interval = 1w
-
-# How many slow mail accesses sorting can perform before it returns failure.
-# With IMAP the reply is: NO [LIMIT] Requested sort would have taken too long.
-# The untagged SORT reply is still returned, but it's likely not correct.
-#mail_sort_max_read_count = 0
-
-protocol !indexer-worker {
- # If folder vsize calculation requires opening more than this many mails from
- # disk (i.e. mail sizes aren't in cache already), return failure and finish
- # the calculation via indexer process. Disabled by default. This setting must
- # be 0 for indexer-worker processes.
- #mail_vsize_bg_after_count = 0
-}
-
-##
-## Maildir-specific settings
-##
-
-# By default LIST command returns all entries in maildir beginning with a dot.
-# Enabling this option makes Dovecot return only entries which are directories.
-# This is done by stat()ing each entry, so it causes more disk I/O.
-# (For systems setting struct dirent->d_type, this check is free and it's
-# done always regardless of this setting)
-#maildir_stat_dirs = no
-
-# When copying a message, do it with hard links whenever possible. This makes
-# the performance much better, and it's unlikely to have any side effects.
-#maildir_copy_with_hardlinks = yes
-
-# Assume Dovecot is the only MUA accessing Maildir: Scan cur/ directory only
-# when its mtime changes unexpectedly or when we can't find the mail otherwise.
-#maildir_very_dirty_syncs = no
-
-# If enabled, Dovecot doesn't use the S=<size> in the Maildir filenames for
-# getting the mail's physical size, except when recalculating Maildir++ quota.
-# This can be useful in systems where a lot of the Maildir filenames have a
-# broken size. The performance hit for enabling this is very small.
-#maildir_broken_filename_sizes = no
-
-# Always move mails from new/ directory to cur/, even when the \Recent flags
-# aren't being reset.
-#maildir_empty_new = no
-
-##
-## mbox-specific settings
-##
-
-# Which locking methods to use for locking mbox. There are four available:
-# dotlock: Create <mailbox>.lock file. This is the oldest and most NFS-safe
-# solution. If you want to use /var/mail/ like directory, the users
-# will need write access to that directory.
-# dotlock_try: Same as dotlock, but if it fails because of permissions or
-# because there isn't enough disk space, just skip it.
-# fcntl : Use this if possible. Works with NFS too if lockd is used.
-# flock : May not exist in all systems. Doesn't work with NFS.
-# lockf : May not exist in all systems. Doesn't work with NFS.
-#
-# You can use multiple locking methods; if you do the order they're declared
-# in is important to avoid deadlocks if other MTAs/MUAs are using multiple
-# locking methods as well. Some operating systems don't allow using some of
-# them simultaneously.
-#
-# The Debian value for mbox_write_locks differs from upstream Dovecot. It is
-# changed to be compliant with Debian Policy (section 11.6) for NFS safety.
-# Dovecot: mbox_write_locks = dotlock fcntl
-# Debian: mbox_write_locks = fcntl dotlock
-#
-#mbox_read_locks = fcntl
-#mbox_write_locks = fcntl dotlock
-
-# Maximum time to wait for lock (all of them) before aborting.
-#mbox_lock_timeout = 5 mins
-
-# If dotlock exists but the mailbox isn't modified in any way, override the
-# lock file after this much time.
-#mbox_dotlock_change_timeout = 2 mins
-
-# When mbox changes unexpectedly we have to fully read it to find out what
-# changed. If the mbox is large this can take a long time. Since the change
-# is usually just a newly appended mail, it'd be faster to simply read the
-# new mails. If this setting is enabled, Dovecot does this but still safely
-# fallbacks to re-reading the whole mbox file whenever something in mbox isn't
-# how it's expected to be. The only real downside to this setting is that if
-# some other MUA changes message flags, Dovecot doesn't notice it immediately.
-# Note that a full sync is done with SELECT, EXAMINE, EXPUNGE and CHECK
-# commands.
-#mbox_dirty_syncs = yes
-
-# Like mbox_dirty_syncs, but don't do full syncs even with SELECT, EXAMINE,
-# EXPUNGE or CHECK commands. If this is set, mbox_dirty_syncs is ignored.
-#mbox_very_dirty_syncs = no
-
-# Delay writing mbox headers until doing a full write sync (EXPUNGE and CHECK
-# commands and when closing the mailbox). This is especially useful for POP3
-# where clients often delete all mails. The downside is that our changes
-# aren't immediately visible to other MUAs.
-#mbox_lazy_writes = yes
-
-# If mbox size is smaller than this (e.g. 100k), don't write index files.
-# If an index file already exists it's still read, just not updated.
-#mbox_min_index_size = 0
-
-# Mail header selection algorithm to use for MD5 POP3 UIDLs when
-# pop3_uidl_format=%m. For backwards compatibility we use apop3d inspired
-# algorithm, but it fails if the first Received: header isn't unique in all
-# mails. An alternative algorithm is "all" that selects all headers.
-#mbox_md5 = apop3d
-
-##
-## mdbox-specific settings
-##
-
-# Maximum dbox file size until it's rotated.
-#mdbox_rotate_size = 10M
-
-# Maximum dbox file age until it's rotated. Typically in days. Day begins
-# from midnight, so 1d = today, 2d = yesterday, etc. 0 = check disabled.
-#mdbox_rotate_interval = 0
-
-# When creating new mdbox files, immediately preallocate their size to
-# mdbox_rotate_size. This setting currently works only in Linux with some
-# filesystems (ext4, xfs).
-mdbox_preallocate_space = yes
-
-##
-## Mail attachments
-##
-
-# sdbox and mdbox support saving mail attachments to external files, which
-# also allows single instance storage for them. Other backends don't support
-# this for now.
-
-# Directory root where to store mail attachments. Disabled, if empty.
-mail_attachment_dir = /home/mail/attachments
-
-# Attachments smaller than this aren't saved externally. It's also possible to
-# write a plugin to disable saving specific attachments externally.
-#mail_attachment_min_size = 128k
-
-# Filesystem backend to use for saving attachments:
-# posix : No SiS done by Dovecot (but this might help FS's own deduplication)
-# sis posix : SiS with immediate byte-by-byte comparison during saving
-# sis-queue posix : SiS with delayed comparison and deduplication
-mail_attachment_fs = sis-queue /home/mail/attachments/queue:posix
-
-# Hash format to use in attachment filenames. You can add any text and
-# variables: %{md4}, %{md5}, %{sha1}, %{sha256}, %{sha512}, %{size}.
-# Variables can be truncated, e.g. %{sha256:80} returns only first 80 bits
-mail_attachment_hash = %{sha256}
-
-# Settings to control adding $HasAttachment or $HasNoAttachment keywords.
-# By default, all MIME parts with Content-Disposition=attachment, or inlines
-# with filename parameter are consired attachments.
-# add-flags-on-save - Add the keywords when saving new mails.
-# content-type=type or !type - Include/exclude content type. Excluding will
-# never consider the matched MIME part as attachment. Including will only
-# negate an exclusion (e.g. content-type=!foo/* content-type=foo/bar).
-# exclude-inlined - Exclude any Content-Disposition=inline MIME part.
-#mail_attachment_detection_options =
diff --git a/roles/IMAP/files/etc/dovecot/conf.d/10-ssl.conf b/roles/IMAP/files/etc/dovecot/conf.d/10-ssl.conf
deleted file mode 100644
index adeb879..0000000
--- a/roles/IMAP/files/etc/dovecot/conf.d/10-ssl.conf
+++ /dev/null
@@ -1,73 +0,0 @@
-##
-## SSL settings
-##
-
-# SSL/TLS support: yes, no, required. <doc/wiki/SSL.txt>
-ssl = required
-
-# PEM encoded X.509 SSL/TLS certificate and private key. They're opened before
-# dropping root privileges, so keep the key file unreadable by anyone but
-# root. Included doc/mkcert.sh can be used to easily generate self-signed
-# certificate, just make sure to update the domains in dovecot-openssl.cnf
-ssl_cert = </etc/dovecot/ssl/imap.fripost.org.pem
-ssl_key = </etc/dovecot/ssl/imap.fripost.org.key
-
-# If key file is password protected, give the password here. Alternatively
-# give it when starting dovecot with -p parameter. Since this file is often
-# world-readable, you may want to place this setting instead to a different
-# root owned 0600 file by using ssl_key_password = <path.
-#ssl_key_password =
-
-# PEM encoded trusted certificate authority. Set this only if you intend to use
-# ssl_verify_client_cert=yes. The file should contain the CA certificate(s)
-# followed by the matching CRL(s). (e.g. ssl_ca = </etc/ssl/certs/ca.pem)
-#ssl_ca =
-
-# Require that CRL check succeeds for client certificates.
-#ssl_require_crl = yes
-
-# Directory and/or file for trusted SSL CA certificates. These are used only
-# when Dovecot needs to act as an SSL client (e.g. imapc backend or
-# submission service). The directory is usually /etc/ssl/certs in
-# Debian-based systems and the file is /etc/pki/tls/cert.pem in
-# RedHat-based systems.
-ssl_client_ca_dir = /etc/ssl/certs
-#ssl_client_ca_file =
-
-# Request client to send a certificate. If you also want to require it, set
-# auth_ssl_require_client_cert=yes in auth section.
-#ssl_verify_client_cert = no
-
-# Which field from certificate to use for username. commonName and
-# x500UniqueIdentifier are the usual choices. You'll also need to set
-# auth_ssl_username_from_cert=yes.
-#ssl_cert_username_field = commonName
-
-# SSL DH parameters
-# Generate new params with `openssl dhparam -out /etc/dovecot/dh.pem 4096`
-# Or migrate from old ssl-parameters.dat file with the command dovecot
-# gives on startup when ssl_dh is unset.
-ssl_dh = </etc/ssl/dhparams.pem
-
-# Minimum SSL protocol version to use. Potentially recognized values are SSLv3,
-# TLSv1, TLSv1.1, and TLSv1.2, depending on the OpenSSL version used.
-ssl_min_protocol = TLSv1.2
-
-# SSL ciphers to use
-ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
-
-# Colon separated list of elliptic curves to use. Empty value (the default)
-# means use the defaults from the SSL library. P-521:P-384:P-256 would be an
-# example of a valid value.
-#ssl_curve_list =
-
-# Prefer the server's order of ciphers over client's.
-#ssl_prefer_server_ciphers = no
-
-# SSL crypto device to use, for valid values run "openssl engine"
-#ssl_crypto_device =
-
-# SSL extra options. Currently supported options are:
-# compression - Enable compression.
-# no_ticket - Disable SSL session tickets.
-#ssl_options =
diff --git a/roles/IMAP/files/etc/dovecot/conf.d/15-lda.conf b/roles/IMAP/files/etc/dovecot/conf.d/15-lda.conf
deleted file mode 100644
index 4bfd8a5..0000000
--- a/roles/IMAP/files/etc/dovecot/conf.d/15-lda.conf
+++ /dev/null
@@ -1,48 +0,0 @@
-##
-## LDA specific settings (also used by LMTP)
-##
-
-# Address to use when sending rejection mails.
-# Default is postmaster@%d. %d expands to recipient domain.
-#postmaster_address =
-
-# Hostname to use in various parts of sent mails (e.g. in Message-Id) and
-# in LMTP replies. Default is the system's real hostname@domain.
-#hostname =
-
-# If user is over quota, return with temporary failure instead of
-# bouncing the mail.
-#quota_full_tempfail = no
-
-# Binary to use for sending mails.
-sendmail_path = /usr/sbin/postmulti -i msa -x /usr/sbin/sendmail
-
-# If non-empty, send mails via this SMTP host[:port] instead of sendmail.
-#submission_host =
-
-# Subject: header to use for rejection mails. You can use the same variables
-# as for rejection_reason below.
-#rejection_subject = Rejected: %s
-
-# Human readable error message for rejection mails. You can use variables:
-# %n = CRLF, %r = reason, %s = original subject, %t = recipient
-#rejection_reason = Your message to <%t> was automatically rejected:%n%r
-
-# Delimiter character between local-part and detail in email address.
-#recipient_delimiter = +
-
-# Header where the original recipient address (SMTP's RCPT TO: address) is taken
-# from if not available elsewhere. With dovecot-lda -a parameter overrides this.
-# A commonly used header for this is X-Original-To.
-#lda_original_recipient_header =
-
-# Should saving a mail to a nonexistent mailbox automatically create it?
-#lda_mailbox_autocreate = no
-
-# Should automatically created mailboxes be also automatically subscribed?
-#lda_mailbox_autosubscribe = no
-
-protocol lda {
- # Space separated list of plugins to load (default is global mail_plugins).
- #mail_plugins = $mail_plugins
-}
diff --git a/roles/IMAP/files/etc/dovecot/conf.d/15-mailboxes.conf b/roles/IMAP/files/etc/dovecot/conf.d/15-mailboxes.conf
deleted file mode 100644
index 9c330be..0000000
--- a/roles/IMAP/files/etc/dovecot/conf.d/15-mailboxes.conf
+++ /dev/null
@@ -1,76 +0,0 @@
-##
-## Mailbox definitions
-##
-
-# Each mailbox is specified in a separate mailbox section. The section name
-# specifies the mailbox name. If it has spaces, you can put the name
-# "in quotes". These sections can contain the following mailbox settings:
-#
-# auto:
-# Indicates whether the mailbox with this name is automatically created
-# implicitly when it is first accessed. The user can also be automatically
-# subscribed to the mailbox after creation. The following values are
-# defined for this setting:
-#
-# no - Never created automatically.
-# create - Automatically created, but no automatic subscription.
-# subscribe - Automatically created and subscribed.
-#
-# special_use:
-# A space-separated list of SPECIAL-USE flags (RFC 6154) to use for the
-# mailbox. There are no validity checks, so you could specify anything
-# you want in here, but it's not a good idea to use flags other than the
-# standard ones specified in the RFC:
-#
-# \All - This (virtual) mailbox presents all messages in the
-# user's message store.
-# \Archive - This mailbox is used to archive messages.
-# \Drafts - This mailbox is used to hold draft messages.
-# \Flagged - This (virtual) mailbox presents all messages in the
-# user's message store marked with the IMAP \Flagged flag.
-# \Junk - This mailbox is where messages deemed to be junk mail
-# are held.
-# \Sent - This mailbox is used to hold copies of messages that
-# have been sent.
-# \Trash - This mailbox is used to hold messages that have been
-# deleted.
-#
-# comment:
-# Defines a default comment or note associated with the mailbox. This
-# value is accessible through the IMAP METADATA mailbox entries
-# "/shared/comment" and "/private/comment". Users with sufficient
-# privileges can override the default value for entries with a custom
-# value.
-
-# NOTE: Assumes "namespace inbox" has been defined in 10-mail.conf.
-namespace inbox {
- # These mailboxes are widely used and could perhaps be created automatically:
- mailbox Trash {
- auto = create
- special_use = \Trash
- }
- mailbox Drafts {
- auto = create
- special_use = \Drafts
- }
- mailbox Sent {
- auto = subscribe
- special_use = \Sent
- }
- mailbox Junk {
- auto = create
- special_use = \Junk
- }
-
- # If you have a virtual "All messages" mailbox:
- mailbox virtual/All {
- special_use = \All
- comment = All messages
- }
-
- # If you have a virtual "Flagged" mailbox:
- mailbox virtual/Flagged {
- special_use = \Flagged
- comment = All flagged messages
- }
-}
diff --git a/roles/IMAP/files/etc/dovecot/conf.d/20-imap.conf b/roles/IMAP/files/etc/dovecot/conf.d/20-imap.conf
deleted file mode 100644
index de1fbbb..0000000
--- a/roles/IMAP/files/etc/dovecot/conf.d/20-imap.conf
+++ /dev/null
@@ -1,108 +0,0 @@
-##
-## IMAP specific settings
-##
-
-# If nothing happens for this long while client is IDLEing, move the connection
-# to imap-hibernate process and close the old imap process. This saves memory,
-# because connections use very little memory in imap-hibernate process. The
-# downside is that recreating the imap process back uses some resources.
-imap_hibernate_timeout = 15s
-
-# Maximum IMAP command line length. Some clients generate very long command
-# lines with huge mailboxes, so you may need to raise this if you get
-# "Too long argument" or "IMAP command line too large" errors often.
-#imap_max_line_length = 64k
-
-# IMAP logout format string:
-# %i - total number of bytes read from client
-# %o - total number of bytes sent to client
-# %{fetch_hdr_count} - Number of mails with mail header data sent to client
-# %{fetch_hdr_bytes} - Number of bytes with mail header data sent to client
-# %{fetch_body_count} - Number of mails with mail body data sent to client
-# %{fetch_body_bytes} - Number of bytes with mail body data sent to client
-# %{deleted} - Number of mails where client added \Deleted flag
-# %{expunged} - Number of mails that client expunged, which does not
-# include automatically expunged mails
-# %{autoexpunged} - Number of mails that were automatically expunged after
-# client disconnected
-# %{trashed} - Number of mails that client copied/moved to the
-# special_use=\Trash mailbox.
-# %{appended} - Number of mails saved during the session
-#imap_logout_format = in=%i out=%o deleted=%{deleted} expunged=%{expunged} \
-# trashed=%{trashed} hdr_count=%{fetch_hdr_count} \
-# hdr_bytes=%{fetch_hdr_bytes} body_count=%{fetch_body_count} \
-# body_bytes=%{fetch_body_bytes}
-
-# Override the IMAP CAPABILITY response. If the value begins with '+',
-# add the given capabilities on top of the defaults (e.g. +XFOO XBAR).
-#imap_capability =
-
-# How long to wait between "OK Still here" notifications when client is
-# IDLEing.
-#imap_idle_notify_interval = 2 mins
-
-# ID field names and values to send to clients. Using * as the value makes
-# Dovecot use the default value. The following fields have default values
-# currently: name, version, os, os-version, support-url, support-email.
-#imap_id_send =
-
-# ID fields sent by client to log. * means everything.
-#imap_id_log =
-
-# Workarounds for various client bugs:
-# delay-newmail:
-# Send EXISTS/RECENT new mail notifications only when replying to NOOP
-# and CHECK commands. Some clients ignore them otherwise, for example OSX
-# Mail (<v2.1). Outlook Express breaks more badly though, without this it
-# may show user "Message no longer in server" errors. Note that OE6 still
-# breaks even with this workaround if synchronization is set to
-# "Headers Only".
-# tb-extra-mailbox-sep:
-# Thunderbird gets somehow confused with LAYOUT=fs (mbox and dbox) and
-# adds extra '/' suffixes to mailbox names. This option causes Dovecot to
-# ignore the extra '/' instead of treating it as invalid mailbox name.
-# tb-lsub-flags:
-# Show \Noselect flags for LSUB replies with LAYOUT=fs (e.g. mbox).
-# This makes Thunderbird realize they aren't selectable and show them
-# greyed out, instead of only later giving "not selectable" popup error.
-#
-# The list is space-separated.
-#imap_client_workarounds =
-
-# Host allowed in URLAUTH URLs sent by client. "*" allows all.
-#imap_urlauth_host =
-
-# Enable IMAP LITERAL- extension (replaces LITERAL+)
-#imap_literal_minus = no
-
-# What happens when FETCH fails due to some internal error:
-# disconnect-immediately:
-# The FETCH is aborted immediately and the IMAP client is disconnected.
-# disconnect-after:
-# The FETCH runs for all the requested mails returning as much data as
-# possible. The client is finally disconnected without a tagged reply.
-# no-after:
-# Same as disconnect-after, but tagged NO reply is sent instead of
-# disconnecting the client. If the client attempts to FETCH the same failed
-# mail more than once, the client is disconnected. This is to avoid clients
-# from going into infinite loops trying to FETCH a broken mail.
-#imap_fetch_failure = disconnect-immediately
-
-protocol imap {
- # Space separated list of plugins to load (default is global mail_plugins).
- mail_plugins = $mail_plugins imap_zlib
-
- # Maximum number of IMAP connections allowed for a user from each IP address.
- # NOTE: The username is compared case-sensitively.
- mail_max_userip_connections = 16
-
-# # TODO Load the 'antispam' plugin for people using the content filter.
-# # (Otherwise fallback to the static userdb.)
-# userdb {
-# driver = ldap
-# args = /etc/dovecot/dovecot-ldap-userdb.conf.ext
-#
-# # Default fields can be used to specify defaults that LDAP may override
-# default_fields = home=/home/mail/virtual/%d/%n
-# }
-}
diff --git a/roles/IMAP/files/etc/dovecot/conf.d/20-lmtp.conf b/roles/IMAP/files/etc/dovecot/conf.d/20-lmtp.conf
deleted file mode 100644
index 8fc5fa0..0000000
--- a/roles/IMAP/files/etc/dovecot/conf.d/20-lmtp.conf
+++ /dev/null
@@ -1,27 +0,0 @@
-##
-## LMTP specific settings
-##
-
-# Support proxying to other LMTP/SMTP servers by performing passdb lookups.
-#lmtp_proxy = no
-
-# When recipient address includes the detail (e.g. user+detail), try to save
-# the mail to the detail mailbox. See also recipient_delimiter and
-# lda_mailbox_autocreate settings.
-#lmtp_save_to_detail_mailbox = no
-
-# Verify quota before replying to RCPT TO. This adds a small overhead.
-#lmtp_rcpt_check_quota = no
-
-# Which recipient address to use for Delivered-To: header and Received:
-# header. The default is "final", which is the same as the one given to
-# RCPT TO command. "original" uses the address given in RCPT TO's ORCPT
-# parameter, "none" uses nothing. Note that "none" is currently always used
-# when a mail has multiple recipients.
-#lmtp_hdr_delivery_address = final
-
-protocol lmtp {
- postmaster_address = postmaster@fripost.org
- # Space separated list of plugins to load (default is global mail_plugins).
- mail_plugins = $mail_plugins sieve
-}
diff --git a/roles/IMAP/files/etc/dovecot/conf.d/90-plugin.conf b/roles/IMAP/files/etc/dovecot/conf.d/90-plugin.conf
deleted file mode 100644
index 52a81ca..0000000
--- a/roles/IMAP/files/etc/dovecot/conf.d/90-plugin.conf
+++ /dev/null
@@ -1,28 +0,0 @@
-##
-## Plugin settings
-##
-
-# All wanted plugins must be listed in mail_plugins setting before any of the
-# settings take effect. See <doc/wiki/Plugins.txt> for list of plugins and
-# their configuration. Note that %variable expansion is done for all values.
-
-plugin {
- antispam_backend = spool2dir
-
- antispam_trash = Trash
- antispam_unsure_pattern_ignorecase = MailTrain;MailTrain/*
- antispam_spam = Junk
-
- # The first %%lu is replaced by the current time.
- # The second %%lu is replaced by a counter to generate unique names.
- # These two tokens MUST be present in the template!
- antispam_spool2dir_spam = /home/mail/spamspool/%u-%%10lu-%%06lu.spam
- antispam_spool2dir_notspam = /home/mail/spamspool/%u-%%10lu-%%06lu.ham
-
- quota_rule = *:storage=0
- quota = count:User quota
- quota_vsizes = yes
-
- zlib_save = gz
- zlib_save_level = 6
-}
diff --git a/roles/IMAP/files/etc/dovecot/conf.d/90-sieve.conf b/roles/IMAP/files/etc/dovecot/conf.d/90-sieve.conf
deleted file mode 100644
index c1ff93e..0000000
--- a/roles/IMAP/files/etc/dovecot/conf.d/90-sieve.conf
+++ /dev/null
@@ -1,214 +0,0 @@
-##
-## Settings for the Sieve interpreter
-##
-
-# Do not forget to enable the Sieve plugin in 15-lda.conf and 20-lmtp.conf
-# by adding it to the respective mail_plugins= settings.
-
-# The Sieve interpreter can retrieve Sieve scripts from several types of
-# locations. The default `file' location type is a local filesystem path
-# pointing to a Sieve script file or a directory containing multiple Sieve
-# script files. More complex setups can use other location types such as
-# `ldap' or `dict' to fetch Sieve scripts from remote databases.
-#
-# All settings that specify the location of one ore more Sieve scripts accept
-# the following syntax:
-#
-# location = [<type>:]path[;<option>[=<value>][;...]]
-#
-# If the type prefix is omitted, the script location type is 'file' and the
-# location is interpreted as a local filesystem path pointing to a Sieve script
-# file or directory. Refer to Pigeonhole wiki or INSTALL file for more
-# information.
-
-plugin {
- # The location of the user's main Sieve script or script storage. The LDA
- # Sieve plugin uses this to find the active script for Sieve filtering at
- # delivery. The "include" extension uses this location for retrieving
- # :personal" scripts. This is also where the ManageSieve service will store
- # the user's scripts, if supported.
- #
- # Currently only the 'file:' location type supports ManageSieve operation.
- # Other location types like 'dict:' and 'ldap:' can currently only
- # be used as a read-only script source ().
- #
- # For the 'file:' type: use the ';active=' parameter to specify where the
- # active script symlink is located.
- # For other types: use the ';name=' parameter to specify the name of the
- # default/active script.
- sieve = file:~/sieve;active=~/dovecot.sieve
-
- # The default Sieve script when the user has none. This is the location of a
- # global sieve script file, which gets executed ONLY if user's personal Sieve
- # script doesn't exist. Be sure to pre-compile this script manually using the
- # sievec command line tool if the binary is not stored in a global location.
- # --> See sieve_before for executing scripts before the user's personal
- # script.
- #sieve_default = /var/lib/dovecot/sieve/default.sieve
-
- # The name by which the default Sieve script (as configured by the
- # sieve_default setting) is visible to the user through ManageSieve.
- #sieve_default_name =
-
- # Location for ":global" include scripts as used by the "include" extension.
- #sieve_global =
-
- # The location of a Sieve script that is run for any message that is about to
- # be discarded; i.e., it is not delivered anywhere by the normal Sieve
- # execution. This only happens when the "implicit keep" is canceled, by e.g.
- # the "discard" action, and no actions that deliver the message are executed.
- # This "discard script" can prevent discarding the message, by executing
- # alternative actions. If the discard script does nothing, the message is
- # still discarded as it would be when no discard script is configured.
- #sieve_discard =
-
- # Location Sieve of scripts that need to be executed before the user's
- # personal script. If a 'file' location path points to a directory, all the
- # Sieve scripts contained therein (with the proper `.sieve' extension) are
- # executed. The order of execution within that directory is determined by the
- # file names, using a normal 8bit per-character comparison.
- #
- # Multiple script locations can be specified by appending an increasing number
- # to the setting name. The Sieve scripts found from these locations are added
- # to the script execution sequence in the specified order. Reading the
- # numbered sieve_before settings stops at the first missing setting, so no
- # numbers may be skipped.
- #sieve_before = /var/lib/dovecot/sieve.d/
- #sieve_before2 = ldap:/etc/sieve-ldap.conf;name=ldap-domain
- #sieve_before3 = (etc...)
-
- # Identical to sieve_before, only the specified scripts are executed after the
- # user's script (only when keep is still in effect!). Multiple script
- # locations can be specified by appending an increasing number.
- #sieve_after =
- #sieve_after2 =
- #sieve_after2 = (etc...)
-
- # Which Sieve language extensions are available to users. By default, all
- # supported extensions are available, except for deprecated extensions or
- # those that are still under development. Some system administrators may want
- # to disable certain Sieve extensions or enable those that are not available
- # by default. This setting can use '+' and '-' to specify differences relative
- # to the default. For example `sieve_extensions = +imapflags' will enable the
- # deprecated imapflags extension in addition to all extensions were already
- # enabled by default.
- sieve_extensions = +editheader
-
- # Which Sieve language extensions are ONLY available in global scripts. This
- # can be used to restrict the use of certain Sieve extensions to administrator
- # control, for instance when these extensions can cause security concerns.
- # This setting has higher precedence than the `sieve_extensions' setting
- # (above), meaning that the extensions enabled with this setting are never
- # available to the user's personal script no matter what is specified for the
- # `sieve_extensions' setting. The syntax of this setting is similar to the
- # `sieve_extensions' setting, with the difference that extensions are
- # enabled or disabled for exclusive use in global scripts. Currently, no
- # extensions are marked as such by default.
- #sieve_global_extensions =
-
- # The Pigeonhole Sieve interpreter can have plugins of its own. Using this
- # setting, the used plugins can be specified. Check the Dovecot wiki
- # (wiki2.dovecot.org) or the pigeonhole website
- # (http://pigeonhole.dovecot.org) for available plugins.
- # The sieve_extprograms plugin is included in this release.
- #sieve_plugins =
-
- # The separator that is expected between the :user and :detail
- # address parts introduced by the subaddress extension. This may
- # also be a sequence of characters (e.g. '--'). The current
- # implementation looks for the separator from the left of the
- # localpart and uses the first one encountered. The :user part is
- # left of the separator and the :detail part is right. This setting
- # is also used by Dovecot's LMTP service.
- recipient_delimiter = +
-
- # The maximum size of a Sieve script. The compiler will refuse to compile any
- # script larger than this limit. If set to 0, no limit on the script size is
- # enforced.
- #sieve_max_script_size = 1M
-
- # The maximum number of actions that can be performed during a single script
- # execution. If set to 0, no limit on the total number of actions is enforced.
- #sieve_max_actions = 32
-
- # The maximum number of redirect actions that can be performed during a single
- # script execution. If set to 0, no redirect actions are allowed.
- #sieve_max_redirects = 4
-
- # The maximum number of personal Sieve scripts a single user can have. If set
- # to 0, no limit on the number of scripts is enforced.
- # (Currently only relevant for ManageSieve)
- #sieve_quota_max_scripts = 0
-
- # The maximum amount of disk storage a single user's scripts may occupy. If
- # set to 0, no limit on the used amount of disk storage is enforced.
- # (Currently only relevant for ManageSieve)
- #sieve_quota_max_storage = 0
-
- # The primary e-mail address for the user. This is used as a default when no
- # other appropriate address is available for sending messages. If this setting
- # is not configured, either the postmaster or null "<>" address is used as a
- # sender, depending on the action involved. This setting is important when
- # there is no message envelope to extract addresses from, such as when the
- # script is executed in IMAP.
- #sieve_user_email =
-
- # The path to the file where the user log is written. If not configured, a
- # default location is used. If the main user's personal Sieve (as configured
- # with sieve=) is a file, the logfile is set to <filename>.log by default. If
- # it is not a file, the default user log file is ~/.dovecot.sieve.log.
- #sieve_user_log =
-
- # Specifies what envelope sender address is used for redirected messages.
- # The following values are supported for this setting:
- #
- # "sender" - The sender address is used (default).
- # "recipient" - The final recipient address is used.
- # "orig_recipient" - The original recipient is used.
- # "user_email" - The user's primary address is used. This is
- # configured with the "sieve_user_email" setting. If
- # that setting is unconfigured, "user_mail" is equal to
- # "recipient".
- # "postmaster" - The postmaster_address configured for the LDA.
- # "<user@domain>" - Redirected messages are always sent from user@domain.
- # The angle brackets are mandatory. The null "<>" address
- # is also supported.
- #
- # This setting is ignored when the envelope sender is "<>". In that case the
- # sender of the redirected message is also always "<>".
- #sieve_redirect_envelope_from = sender
-
- ## TRACE DEBUGGING
- # Trace debugging provides detailed insight in the operations performed by
- # the Sieve script. These settings apply to both the LDA Sieve plugin and the
- # IMAPSIEVE plugin.
- #
- # WARNING: On a busy server, this functionality can quickly fill up the trace
- # directory with a lot of trace files. Enable this only temporarily and as
- # selective as possible.
-
- # The directory where trace files are written. Trace debugging is disabled if
- # this setting is not configured or if the directory does not exist. If the
- # path is relative or it starts with "~/" it is interpreted relative to the
- # current user's home directory.
- #sieve_trace_dir =
-
- # The verbosity level of the trace messages. Trace debugging is disabled if
- # this setting is not configured. Possible values are:
- #
- # "actions" - Only print executed action commands, like keep,
- # fileinto, reject and redirect.
- # "commands" - Print any executed command, excluding test commands.
- # "tests" - Print all executed commands and performed tests.
- # "matching" - Print all executed commands, performed tests and the
- # values matched in those tests.
- #sieve_trace_level =
-
- # Enables highly verbose debugging messages that are usually only useful for
- # developers.
- #sieve_trace_debug = no
-
- # Enables showing byte code addresses in the trace output, rather than only
- # the source line numbers.
- #sieve_trace_addresses = no
-}
diff --git a/roles/IMAP/files/etc/dovecot/ssl/config b/roles/IMAP/files/etc/dovecot/ssl/config
new file mode 100644
index 0000000..e5359de
--- /dev/null
+++ b/roles/IMAP/files/etc/dovecot/ssl/config
@@ -0,0 +1,2 @@
+ssl_cert = </etc/dovecot/ssl/imap.fripost.org.pem
+ssl_key = </etc/dovecot/ssl/imap.fripost.org.key
diff --git a/roles/IMAP/tasks/imap.yml b/roles/IMAP/tasks/imap.yml
index 4a157af..c2bdca9 100644
--- a/roles/IMAP/tasks/imap.yml
+++ b/roles/IMAP/tasks/imap.yml
@@ -139,15 +139,6 @@
register: r1
with_items:
- conf.d/10-auth.conf
- - conf.d/10-mail.conf
- - conf.d/10-ssl.conf
- - conf.d/15-mailboxes.conf
- # LDA is also used by LMTP
- - conf.d/15-lda.conf
- - conf.d/20-imap.conf
- - conf.d/20-lmtp.conf
- - conf.d/90-plugin.conf
- - conf.d/90-sieve.conf
- conf.d/auth-ldap.conf.ext
- dovecot-ldap.conf.ext
- dovecot-ldap-userdb.conf.ext
@@ -161,7 +152,16 @@
mode=0644
register: r2
with_items:
- - conf.d/10-master.conf
+ - conf.d/99-local.conf
+ notify:
+ - Restart Dovecot
+
+# TODO bookworm remove the below and inline the !include_try
+- name: Copy /etc/dovecot/ssl/config workaround
+ copy: src=etc/dovecot/ssl/config
+ dest=/etc/dovecot/ssl/config
+ owner=root group=root
+ mode=0600
notify:
- Restart Dovecot
diff --git a/roles/IMAP/tasks/spam.yml b/roles/IMAP/tasks/spam.yml
index c275b55..d70ccc9 100644
--- a/roles/IMAP/tasks/spam.yml
+++ b/roles/IMAP/tasks/spam.yml
@@ -63,8 +63,8 @@
- name: Create a 'amavis' SQL user
# This *must* be the user we run spamd as
# See https://svn.apache.org/repos/asf/spamassassin/trunk/sql/README.bayes
- mysql_user2: >
- name=amavis password= auth_plugin=auth_socket
+ mysql_user: >
+ name=amavis password= plugin=auth_socket
priv="spamassassin.awl: SELECT,INSERT,UPDATE,DELETE
/spamassassin.bayes_seen: SELECT,INSERT, DELETE
/spamassassin.bayes_token: SELECT,INSERT,UPDATE,DELETE
diff --git a/roles/IMAP/templates/etc/dovecot/conf.d/10-master.conf.j2 b/roles/IMAP/templates/etc/dovecot/conf.d/10-master.conf.j2
index daeecf4..d61c11b 100644
--- a/roles/IMAP/templates/etc/dovecot/conf.d/10-master.conf.j2
+++ b/roles/IMAP/templates/etc/dovecot/conf.d/10-master.conf.j2
@@ -4,7 +4,7 @@
# Default VSZ (virtual memory size) limit for service processes. This is mainly
# intended to catch and kill processes that leak memory before they eat up
# everything.
-default_vsz_limit = 512M
+default_vsz_limit = 1024M
# Login user is internally used by login processes. This is the most untrusted
# user in Dovecot system. It shouldn't have access to anything at all.
diff --git a/roles/IMAP/templates/etc/dovecot/conf.d/99-local.conf.j2 b/roles/IMAP/templates/etc/dovecot/conf.d/99-local.conf.j2
new file mode 100644
index 0000000..3560193
--- /dev/null
+++ b/roles/IMAP/templates/etc/dovecot/conf.d/99-local.conf.j2
@@ -0,0 +1,204 @@
+auth_default_realm = fripost.org
+auth_username_format = %Lu
+auth_mechanisms = plain login
+
+mail_uid = vmail
+mail_gid = vmail
+mail_privileged_group =
+
+first_valid_uid = 1
+last_valid_uid = 0
+
+default_vsz_limit = 1024M
+
+service imap-login {
+ inet_listener imap {
+{% if groups.all | length > 1 %}
+ address = {{ ipsec[inventory_hostname_short] }}
+ port = 143
+{% else %}
+ port = 0
+{% endif %}
+ }
+ process_limit = 256
+ process_min_avail = 4
+}
+
+service stats {
+ unix_listener stats-writer {
+ user = vmail
+ mode = 0600
+ }
+}
+
+service submission-login {
+ inet_listener submission {
+ port = 0
+ }
+}
+
+service lmtp {
+ user = vmail
+ unix_listener lmtp {
+ mode = 0
+ }
+ unix_listener /var/spool/postfix-mda/private/dovecot-lmtpd {
+ user = postfix
+ mode = 0600
+ }
+ process_min_avail = 4
+}
+
+service imap {
+ unix_listener imap-master {
+ user = $default_internal_user
+ mode = 0600
+ }
+}
+service imap-hibernate {
+ unix_listener imap-hibernate {
+ # Match user running imap processes, cf.
+ # https://dovecot.org/pipermail/dovecot/2015-August/101783.html
+ user = vmail
+ mode = 0600
+ }
+}
+
+service auth {
+ unix_listener auth-userdb {
+ user = vmail
+ mode = 0600
+ }
+
+ # Postfix smtp-auth
+ unix_listener /var/spool/postfix-msa/private/dovecot-auth {
+ user = postfix
+ group = postfix
+ mode = 0600
+ }
+}
+
+service auth-worker {
+ user = $default_internal_user
+}
+
+
+mail_server_comment = "fripost - demokratisk e-post"
+mail_server_admin = mailto:postmaster@fripost.org
+
+mail_plugins = quota virtual zlib
+
+mail_location = mdbox:~/mail
+mdbox_preallocate_space = yes
+
+mail_attachment_dir = /home/mail/attachments
+mail_attachment_fs = sis-queue /home/mail/attachments/queue:posix
+mail_attachment_hash = %{sha256}
+
+sendmail_path = /usr/sbin/postmulti -i msa -x /usr/sbin/sendmail
+
+ssl = required
+# XXX `doveadm exec imap` fails with "ssl_key: Can't open file
+# /etc/dovecot/ssl/imap.fripost.org.key"
+# https://dovecot.org/pipermail/dovecot/2020-August/119642.html
+# TODO bookworm inline the include_try
+!include_try ../ssl/config
+ssl_dh = </etc/ssl/dhparams.pem
+ssl_min_protocol = TLSv1.2
+ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
+
+namespace inbox {
+ inbox = yes
+ separator = /
+
+ mailbox Drafts {
+ auto = create
+ special_use = \Drafts
+ }
+ mailbox Junk {
+ auto = create
+ special_use = \Junk
+ }
+ mailbox "Sent Messages" {
+ auto = no
+ special_use = \Sent
+ }
+ mailbox Sent {
+ auto = subscribe
+ special_use = \Sent
+ }
+ mailbox Trash {
+ auto = create
+ special_use = \Trash
+ }
+ mailbox virtual/All {
+ comment = All messages
+ special_use = \All
+ }
+ mailbox virtual/Flagged {
+ comment = All flagged messages
+ special_use = \Flagged
+ }
+}
+
+namespace virtual {
+ prefix = virtual/
+ separator = /
+ location = virtual:/etc/dovecot/virtual:INDEX=MEMORY
+ list = no
+ hidden = no
+ subscriptions = no
+}
+
+imap_hibernate_timeout = 15s
+protocol imap {
+ mail_plugins = $mail_plugins imap_zlib
+ mail_max_userip_connections = 16
+
+ ## TODO Load the 'antispam' plugin for people using the content filter.
+ ## (Otherwise fallback to the static userdb.)
+ #userdb {
+ # driver = ldap
+ # args = /etc/dovecot/dovecot-ldap-userdb.conf.ext
+ #
+ # # Default fields can be used to specify defaults that LDAP may override
+ # default_fields = home=/home/mail/virtual/%d/%n
+ #}
+}
+
+protocol lmtp {
+ postmaster_address = postmaster@fripost.org
+ # Space separated list of plugins to load (default is global mail_plugins).
+ mail_plugins = $mail_plugins sieve
+}
+
+plugin {
+ antispam_backend = spool2dir
+
+ antispam_trash = Trash
+ antispam_unsure_pattern_ignorecase = MailTrain;MailTrain/*
+ antispam_spam = Junk
+
+ # The first %%lu is replaced by the current time.
+ # The second %%lu is replaced by a counter to generate unique names.
+ # These two tokens MUST be present in the template!
+ antispam_spool2dir_spam = /home/mail/spamspool/%u-%%10lu-%%06lu.spam
+ antispam_spool2dir_notspam = /home/mail/spamspool/%u-%%10lu-%%06lu.ham
+}
+
+plugin {
+ quota_rule = *:storage=0
+ quota = count:User quota
+ quota_vsizes = yes
+}
+
+plugin {
+ sieve = file:~/sieve;active=~/dovecot.sieve
+ sieve_extensions = +editheader
+ recipient_delimiter = +
+}
+
+plugin {
+ zlib_save = gz
+ zlib_save_level = 6
+}
diff --git a/roles/IMAP/templates/etc/postfix/main.cf.j2 b/roles/IMAP/templates/etc/postfix/main.cf.j2
index 2105d29..64a2a40 100644
--- a/roles/IMAP/templates/etc/postfix/main.cf.j2
+++ b/roles/IMAP/templates/etc/postfix/main.cf.j2
@@ -21,7 +21,7 @@ append_dot_mydomain = no
mynetworks = 127.0.0.0/8, [::1]/128
{%- if groups.all | length > 1 -%}
{%- for mx in groups.MX | sort -%}
- , {{ ipsec[ hostvars[mx].inventory_hostname_short ] | ipaddr }}
+ , {{ ipsec[ hostvars[mx].inventory_hostname_short ] | ansible.utils.ipaddr }}
{%- endfor %}
{% endif %}
diff --git a/roles/MSA/files/etc/postfix/anonymize_sender.pcre b/roles/MSA/files/etc/postfix/anonymize_sender.pcre
index 162e6c1..b91b981 100644
--- a/roles/MSA/files/etc/postfix/anonymize_sender.pcre
+++ b/roles/MSA/files/etc/postfix/anonymize_sender.pcre
@@ -1,6 +1,6 @@
/^Received:\s+from\s+(?:\S+\s+\(\S+\s+\[(?:IPv6:)?[[:xdigit:].:]{3,39}\]\))
(\s+\(using\s+(?:TLS|SSL)(?:v\S+)?\s+with\s+cipher\s+\S+\s+\(\S+\s+bits\)
- (?:\s+key-exchange\s+\S+\s+(?:\([^)]+\)\s+)?server-signature\s+\S+\s+\(\d+\s+bits\)\s+server-digest\s+\S+)?\)\s+).*
+ (?:\s+key-exchange\s+\S+\s+(?:\([^)]+\)\s+)?server-signature\s+\S+\s+\(\d+\s+bits\)(?:\s+server-[[:alnum:]]+\s+\S+)*)?\)\s+).*
(\bby\s+(?:\S+\.)?fripost\.org\s+\([^)]+\)
\s+with\s+E?SMTPS?A\s+id\s+[[:xdigit:]]+;?\s.*)/x
REPLACE Received: from [127.0.0.1] (localhost [127.0.0.1])${1}${2}
diff --git a/roles/MSA/templates/etc/postfix/main.cf.j2 b/roles/MSA/templates/etc/postfix/main.cf.j2
index a435b0f..6a544ac 100644
--- a/roles/MSA/templates/etc/postfix/main.cf.j2
+++ b/roles/MSA/templates/etc/postfix/main.cf.j2
@@ -20,7 +20,7 @@ append_dot_mydomain = no
mynetworks = 127.0.0.0/8, [::1]/128
{%- for h in groups.webmail | difference([inventory_hostname]) | sort -%}
- , {{ ipsec[ hostvars[h].inventory_hostname_short ] | ipaddr }}
+ , {{ ipsec[ hostvars[h].inventory_hostname_short ] | ansible.utils.ipaddr }}
{% endfor %}
queue_directory = /var/spool/postfix-{{ postfix_instance[inst].name }}
@@ -40,7 +40,7 @@ message_size_limit = 67108864
recipient_delimiter = +
# 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 =
@@ -121,4 +121,7 @@ smtpd_relay_restrictions =
smtpd_data_restrictions =
reject_unauth_pipelining
+smtpd_forbid_bare_newline = normalize
+smtpd_forbid_bare_newline_exclusions = $mynetworks
+
# vim: set filetype=pfmain :
diff --git a/roles/MX/files/etc/opendmarc.conf b/roles/MX/files/etc/opendmarc.conf
index 575d02d..ebbc850 100644
--- a/roles/MX/files/etc/opendmarc.conf
+++ b/roles/MX/files/etc/opendmarc.conf
@@ -30,7 +30,7 @@
## not be able to determine the Organizational Domain and only the presented
## domain will be evaluated.
#
-PublicSuffixList /usr/share/publicsuffix
+PublicSuffixList /usr/share/publicsuffix/public_suffix_list.dat
## RejectFailures { true | false }
## default "false"
@@ -56,7 +56,7 @@ RejectFailures false
## either in the configuration file or on the command line. If an IP
## address is used, it must be enclosed in square brackets.
#
-Socket local:/var/run/opendmarc/opendmarc.sock
+Socket local:/run/opendmarc/opendmarc.sock
## Syslog { true | false }
## default "false"
diff --git a/roles/MX/templates/etc/postfix/main.cf.j2 b/roles/MX/templates/etc/postfix/main.cf.j2
index 36315d1..d10f901 100644
--- a/roles/MX/templates/etc/postfix/main.cf.j2
+++ b/roles/MX/templates/etc/postfix/main.cf.j2
@@ -37,7 +37,7 @@ message_size_limit = 67108864
recipient_delimiter = +
# 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 =
diff --git a/roles/MX/templates/etc/postfix/virtual/transport.j2 b/roles/MX/templates/etc/postfix/virtual/transport.j2
index 126cb72..536748a 100644
--- a/roles/MX/templates/etc/postfix/virtual/transport.j2
+++ b/roles/MX/templates/etc/postfix/virtual/transport.j2
@@ -17,5 +17,5 @@
reserved.fripost.org reserved-alias:
discard.fripost.org discard:
-mda.fripost.org smtp:[{{ postfix_instance.IMAP.addr | ipaddr }}]:{{ postfix_instance.IMAP.port }}
-sympa.fripost.org smtp:[{{ postfix_instance.lists.addr | ipaddr }}]:{{ postfix_instance.lists.port }}
+mda.fripost.org smtp:[{{ postfix_instance.IMAP.addr | ansible.utils.ipaddr }}]:{{ postfix_instance.IMAP.port }}
+sympa.fripost.org smtp:[{{ postfix_instance.lists.addr | ansible.utils.ipaddr }}]:{{ postfix_instance.lists.port }}
diff --git a/roles/amavis/tasks/main.yml b/roles/amavis/tasks/main.yml
index 79c973c..7fc44c7 100644
--- a/roles/amavis/tasks/main.yml
+++ b/roles/amavis/tasks/main.yml
@@ -50,7 +50,7 @@
- dkim
- name: Generate a private key for DKIM signing
- command: genkeypair.sh dkim --privkey="/etc/amavis/dkim/{{ item.s }}:{{ item.d }}.pem" -t rsa -b 2048
+ command: genkeypair.sh dkim --owner=amavis --group=root --privkey="/etc/amavis/dkim/{{ item.s }}:{{ item.d }}.pem" -t rsa -b 2048
with_items: "{{ (dkim_keys[inventory_hostname_short] | default({})).values() | list }}"
register: dkim
changed_when: dkim.rc == 0
diff --git a/roles/bacula-dir/tasks/main.yml b/roles/bacula-dir/tasks/main.yml
index 2fdb35b..53d44ee 100644
--- a/roles/bacula-dir/tasks/main.yml
+++ b/roles/bacula-dir/tasks/main.yml
@@ -7,8 +7,8 @@
- bacula-director-mysql
- name: Create a 'bacula' SQL user
- mysql_user2: name=bacula password= auth_plugin=unix_socket
- state=present
+ mysql_user: name=bacula password= plugin=unix_socket
+ state=present
notify:
- Restart bacula-director
diff --git a/roles/common-LDAP/tasks/main.yml b/roles/common-LDAP/tasks/main.yml
index 89dd1d8..e17bc3a 100644
--- a/roles/common-LDAP/tasks/main.yml
+++ b/roles/common-LDAP/tasks/main.yml
@@ -8,7 +8,7 @@
- ldap-utils
- ldapvi
- db-util
- - python-ldap
+ - python3-ldap
# for the 'slapd2' munin plugin
- libnet-ldap-perl
- libauthen-sasl-perl
@@ -30,19 +30,13 @@
tags:
- genkey
-# XXX: It's ugly to list all roles here, and to prunes them with a
-# conditional...
- name: Generate a private key and a X.509 certificate for slapd
- # XXX: GnuTLS (libgnutls26 2.12.20-8+deb7u2, found in Wheezy) doesn't
- # support ECDSA; and slapd doesn't seem to support DHE (!?) so
- # we're stuck with "plain RSA" Key-Exchange. Also, there is a bug with
- # SHA-512.
command: genkeypair.sh x509
--pubkey=/etc/ldap/ssl/{{ item.name }}.pem
--privkey=/etc/ldap/ssl/{{ item.name }}.key
--ou=LDAP {{ item.ou }} --cn={{ item.name }}
- --usage=digitalSignature,keyEncipherment,keyCertSign
- -t rsa -b 4096 -h sha256
+ --usage=digitalSignature,keyEncipherment
+ -t ed25519
--owner=root --group=openldap --mode=0640
register: r2
changed_when: r2.rc == 0
@@ -52,6 +46,18 @@
- { group: 'MX', name: mx, ou: --ou=SyncRepl }
- { group: 'lists', name: lists, ou: --ou=SyncRepl }
when: "item.group in group_names"
+ notify:
+ - Restart slapd
+ tags:
+ - genkey
+
+- name: Fetch the SyncProv's X.509 certificate
+ # Ensure we don't fetch private data
+ become: False
+ fetch_cmd: cmd="openssl x509"
+ stdin=/etc/ldap/ssl/ldap.fripost.org.pem
+ dest=certs/ldap/ldap.fripost.org.pem
+ when: "'LDAP_provider' in group_names"
tags:
- genkey
@@ -60,9 +66,8 @@
become: False
fetch_cmd: cmd="openssl x509"
stdin=/etc/ldap/ssl/{{ item.name }}.pem
- dest=certs/ldap/{{ item.name }}.pem
+ dest=certs/ldap/syncrepl/{{ item.name }}@{{ inventory_hostname_short }}.pem
with_items:
- - { group: 'LDAP_provider', name: ldap.fripost.org }
- { group: 'MX', name: mx }
- { group: 'lists', name: lists }
when: "item.group in group_names"
@@ -79,17 +84,20 @@
- genkey
- name: Copy the SyncRepls's client certificates
- assemble: src=certs/ldap remote_src=no
- dest=/etc/ldap/ssl/clients.pem
+ assemble: src=certs/ldap/syncrepl remote_src=no
+ dest=/etc/ldap/ssl/syncrepl.pem
owner=root group=root
mode=0644
when: "'LDAP_provider' in group_names"
tags:
- genkey
+ register: r3
+ notify:
+ - Restart slapd
- name: Start slapd
service: name=slapd state=started
- when: not (r1.changed or r2.changed)
+ when: not (r1.changed or r2.changed or r3.changed)
- meta: flush_handlers
diff --git a/roles/common-LDAP/templates/etc/ldap/database.ldif.j2 b/roles/common-LDAP/templates/etc/ldap/database.ldif.j2
index 2c0db0b..a0ac705 100644
--- a/roles/common-LDAP/templates/etc/ldap/database.ldif.j2
+++ b/roles/common-LDAP/templates/etc/ldap/database.ldif.j2
@@ -34,7 +34,7 @@ olcTLSCertificateKeyFile: /etc/ldap/ssl/ldap.fripost.org.key
# terminate the connection. Not providing a certificate is fine for
# TLS-protected simple binds, though.
olcTLSVerifyClient: try
-olcTLSCACertificateFile: /etc/ldap/ssl/clients.pem
+olcTLSCACertificateFile: /etc/ldap/ssl/syncrepl.pem
olcAuthzRegexp: "^(cn=[^,]+,ou=syncRepl),ou=LDAP,ou=SSLcerts,o=Fripost$"
"dn.exact:$1,dc=fripost,dc=org"
olcSaslSecProps: minssf=128,noanonymous,noplain,nodict
diff --git a/roles/common-SQL/tasks/main.yml b/roles/common-SQL/tasks/main.yml
index 927f567..7e59f60 100644
--- a/roles/common-SQL/tasks/main.yml
+++ b/roles/common-SQL/tasks/main.yml
@@ -4,7 +4,7 @@
packages:
- mariadb-common
- mariadb-server
- - python-mysqldb
+ - python3-mysqldb
# for the 'mysql_' munin plugin
- libcache-cache-perl
@@ -23,12 +23,12 @@
# XXX Dirty fix for #742046
- name: Force root to use UNIX permissions
- mysql_user2: name=root password="" auth_plugin=unix_socket soname=auth_socket.so
- state=present
+ mysql_user: name=root password="" plugin=unix_socket
+ state=present
- name: Disallow anonymous and TCP/IP root login
- mysql_user2: name={{ item.name|default('') }} host={{ item.host }}
- state=absent
+ mysql_user: name={{ item.name|default('') }} host={{ item.host }}
+ state=absent
with_items:
- { host: '{{ inventory_hostname_short }}' }
- { host: 'localhost' }
diff --git a/roles/common-web/files/etc/nginx/sites-available/default b/roles/common-web/files/etc/nginx/sites-available/default
index 295cb6d..cae8fc0 100644
--- a/roles/common-web/files/etc/nginx/sites-available/default
+++ b/roles/common-web/files/etc/nginx/sites-available/default
@@ -1,6 +1,6 @@
server {
- listen 80 default_server;
- listen [::]:80 default_server;
+ listen 80 default_server;
+ listen [::]:80 default_server;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log info;
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/fail2ban/filter.d/dovecot.conf b/roles/common/files/etc/fail2ban/filter.d/dovecot.conf
deleted file mode 100644
index c8f5345..0000000
--- a/roles/common/files/etc/fail2ban/filter.d/dovecot.conf
+++ /dev/null
@@ -1,49 +0,0 @@
-# Fail2Ban filter Dovecot authentication and pop3/imap/managesieve server
-# guilhem 2020-05-19: This is the filter from Buster (fail2ban
-# 0.10.2-2.1) with managesieve to the list of protected services
-#
-
-[INCLUDES]
-
-before = common.conf
-
-[Definition]
-
-_auth_worker = (?:dovecot: )?auth(?:-worker)?
-_daemon = (?:dovecot(?:-auth)?|auth)
-
-prefregex = ^%(__prefix_line)s(?:%(_auth_worker)s(?:\([^\)]+\))?: )?(?:%(__pam_auth)s(?:\(dovecot:auth\))?: |(?:pop3|imap|managesieve)-login: )?(?:Info: )?<F-CONTENT>.+</F-CONTENT>$
-
-failregex = ^authentication failure; logname=\S* uid=\S* euid=\S* tty=dovecot ruser=\S* rhost=<HOST>(?:\s+user=\S*)?\s*$
- ^(?:Aborted login|Disconnected)(?::(?: [^ \(]+)+)? \((?:auth failed, \d+ attempts(?: in \d+ secs)?|tried to use (?:disabled|disallowed) \S+ auth)\):(?: user=<[^>]*>,)?(?: method=\S+,)? rip=<HOST>(?:[^>]*(?:, session=<\S+>)?)\s*$
- ^pam\(\S+,<HOST>(?:,\S*)?\): pam_authenticate\(\) failed: (?:User not known to the underlying authentication module: \d+ Time\(s\)|Authentication failure \(password mismatch\?\)|Permission denied)\s*$
- ^[a-z\-]{3,15}\(\S*,<HOST>(?:,\S*)?\): (?:unknown user|invalid credentials)\s*$
- <mdre-<mode>>
-
-mdre-aggressive = ^(?:Aborted login|Disconnected)(?::(?: [^ \(]+)+)? \((?:no auth attempts|disconnected before auth was ready,|client didn't finish \S+ auth,)(?: (?:in|waited) \d+ secs)?\):(?: user=<[^>]*>,)?(?: method=\S+,)? rip=<HOST>(?:[^>]*(?:, session=<\S+>)?)\s*$
-
-mdre-normal =
-
-# Parameter `mode` - `normal` or `aggressive`.
-# Aggressive mode can be used to match log-entries like:
-# 'no auth attempts', 'disconnected before auth was ready', 'client didn't finish SASL auth'.
-# Note it may produce lots of false positives on misconfigured MTAs.
-# Ex.:
-# filter = dovecot[mode=aggressive]
-mode = normal
-
-ignoreregex =
-
-journalmatch = _SYSTEMD_UNIT=dovecot.service
-
-datepattern = {^LN-BEG}TAI64N
- {^LN-BEG}
-
-# DEV Notes:
-# * the first regex is essentially a copy of pam-generic.conf
-# * Probably doesn't do dovecot sql/ldap backends properly (resolved in edit 21/03/2016)
-#
-# Author: Martin Waschbuesch
-# Daniel Black (rewrote with begin and end anchors)
-# Martin O'Neal (added LDAP authentication failure regex)
-# Sergey G. Brester aka sebres (reviewed, optimized, IPv6-compatibility)
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 f5b6d8d..3a4cb36 100644
--- a/roles/common/files/etc/logcheck/ignore.d.server/common-local
+++ b/roles/common/files/etc/logcheck/ignore.d.server/common-local
@@ -3,17 +3,35 @@
#
^\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:]]+\]: 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:]]+\]: (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:]]+\]: (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 \[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:]]+\]: 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:]]+\]: error: Protocol major versions differ: .+ vs\. .+$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: banner exchange: Connection from [[:xdigit:].:]{3,39} port [0-9]+: could not read protocol version$
+^\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: kex_protocol_error: type [0-9]+ seq [0-9]+ \[preauth\]$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: fatal: ssh_packet_send_debug: Broken pipe$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: error: send_error: write: Connection reset by peer$
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: fatal: userauth_pubkey: parse request failed: incomplete message \[preauth\]$
+^\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:]-]+ sshd\[[[:digit:]]+\]: User .+ from [[:xdigit:].:]{3,39} not allowed because none of user's groups are listed in AllowGroups$
^\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$
@@ -28,15 +46,19 @@ no matching cipher found: client [.@[:alnum:]-]+(,[.@[:alnum:]-]+)* server [.@[:
^\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:]]+( 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-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:]-]+ 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|updated) \(version: [[:digit:]]+, sigs: [[:digit:]]+, f-level: [[:digit:]]+, builder: [._[:alnum:]-]+\)$
+^\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$
@@ -49,6 +71,7 @@ no matching cipher found: client [.@[:alnum:]-]+(,[.@[:alnum:]-]+)* server [.@[:
^\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$
@@ -56,10 +79,14 @@ no matching cipher found: client [.@[:alnum:]-]+(,[.@[:alnum:]-]+)* server [.@[:
^\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:]-]+ 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:]-]+ ansible-([_a-z0-9.]+|<stdin>): Invoked with
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ python3(\.[0-9]+)?\[[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} - |Ignore [[:xdigit:].:]{3,39} by ip$)
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ fail2ban-server\[[0-9]+\]: fail2ban\.actions\s*\[[0-9]+\]: NOTICE\s+\[[._[:alnum:]-]+\] (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]+\]: notice Sympa::(Bulk|Spool)::store\(\)
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: info Sympa::Spool::_create\(\) Creating directory /var/spool/sympa/auth
@@ -84,8 +111,12 @@ no matching cipher found: client [.@[:alnum:]-]+(,[.@[:alnum:]-]+)* server [.@[:
^\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\(\)
@@ -103,3 +134,5 @@ no matching cipher found: client [.@[:alnum:]-]+(,[.@[:alnum:]-]+)* server [.@[:
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ auditd\[[[:digit:]]+\]: Audit daemon rotating log files$
^\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]+$
+###
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ slapd\[[[:digit:]]+\]: connection_read\([[:digit:]]+\): no connection!$
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 11185f8..532a2a0 100644
--- a/roles/common/files/etc/logcheck/ignore.d.server/dovecot-local
+++ b/roles/common/files/etc/logcheck/ignore.d.server/dovecot-local
@@ -2,18 +2,19 @@
# Do NOT edit this file directly!
#
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: lmtp\([-_.@[:alnum:]]+\): Connect from local$
-^\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\([-_.@[: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(: 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)[:,]
^\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: (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\([-_.@[: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:]-]+\)| [[:alnum:]]+ action)?: (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:]]+\)$
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 5abe69d..dcc1198 100644
--- a/roles/common/files/etc/logcheck/ignore.d.server/postfix-local
+++ b/roles/common/files/etc/logcheck/ignore.d.server/postfix-local
@@ -15,6 +15,7 @@
^\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:]_/+.$@-]+|[^,()]+@[.[: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:]]+\))?
@@ -26,14 +27,14 @@
^\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 [[: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/smtpd\[[[:digit:]]+\]: warning: [-._[:alnum:]]+\[[[:xdigit:].:]{3,39}\]: SASL [[:alpha:]]+ authentication (failed|aborted)(:|$)
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: improper command pipelining after (CONNECT|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|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}\]: 5[[:digit:]]{2} 5(\.[[:digit:]]+){2} Service unavailable; (Unverified Client host|Sender address) \[\S+\] blocked using [._[:alnum:]-]+(; Listed by DBL, see 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)$
@@ -60,7 +61,7 @@
^\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}|unknown)\]: (lost connection|Connection reset by peer|-?[[:digit:]]+|Connection timed out)$
+^\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:]].*$
@@ -78,8 +79,9 @@
^\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|msa)/(smtpd|tlsproxy)\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:(ssl3_get_record:(wrong version number|http request)|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_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:]]+>$
@@ -123,7 +125,9 @@
^\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 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 df67675..e78e9f0 100644
--- a/roles/common/files/etc/logcheck/ignore.d.server/strongswan-local
+++ b/roles/common/files/etc/logcheck/ignore.d.server/strongswan-local
@@ -20,3 +20,5 @@
^\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:]-]+ (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 ef38ab6..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
@@ -596,7 +596,6 @@ EXISTWHITELIST=/usr/bin/fgrep
#
SCRIPTWHITELIST=/bin/egrep
SCRIPTWHITELIST=/bin/fgrep
-SCRIPTWHITELIST=/bin/which
SCRIPTWHITELIST=/usr/bin/egrep
SCRIPTWHITELIST=/usr/bin/fgrep
SCRIPTWHITELIST=/usr/bin/which
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..efb241c 100644
--- a/roles/common/files/etc/strongswan.d/charon.conf
+++ b/roles/common/files/etc/strongswan.d/charon.conf
@@ -1,10 +1,15 @@
# 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
- # Maximum number of half-open IKE_SAs for a single peer IP.
+ # Maximum number of half-open IKE_SAs (including unprocessed IKE_SA_INITs)
+ # for a single peer IP.
# block_threshold = 5
# Whether Certificate Revocation Lists (CRLs) fetched via HTTP or LDAP
@@ -17,14 +22,26 @@ 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
# Close the IKE_SA if setup of the CHILD_SA along with IKE_AUTH failed.
# close_ike_on_child_failure = no
- # Number of half-open IKE_SAs that activate the cookie mechanism.
- # cookie_threshold = 10
+ # Number of half-open IKE_SAs (including unprocessed IKE_SA_INITs) that
+ # activate the cookie mechanism.
+ # cookie_threshold = 30
+
+ # Number of half-open IKE_SAs (including unprocessed IKE_SA_INITs) for a
+ # single peer IP that activate the cookie mechanism.
+ # cookie_threshold_ip = 3
# Delete CHILD_SAs right after they got successfully rekeyed (IKEv1 only).
# delete_rekeyed = no
@@ -51,15 +68,16 @@ charon {
# checks.
# dos_protection = yes
- # Compliance with the errata for RFC 4753.
- # ecp_x_coordinate_only = yes
-
# Free objects during authentication (might conflict with plugins).
# flush_auth_cfg = no
# 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 +153,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 +199,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
@@ -233,6 +259,10 @@ charon {
# Whether to use RSA with PSS padding instead of PKCS#1 padding by default.
# rsa_pss = no
+ # Whether to encode an explicit trailerField value of 0x01 in the RSA-PSS
+ # algorithmIdentifier (CONTEXT3) or using the DEFAULT value by omitting it.
+ # rsa_pss_trailerfield = no
+
# Delay in ms for sending packets, to simulate larger RTT.
# send_delay = 0
@@ -254,6 +284,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
@@ -308,11 +345,12 @@ charon {
# Includes source file names and line numbers in leak detective output.
# detailed = yes
- # Threshold in bytes for leaks to be reported (0 to report all).
+ # Threshold in bytes for allocations to be included in usage reports (0
+ # to include all).
# usage_threshold = 10240
- # Threshold in number of allocations for leaks to be reported (0 to
- # report all).
+ # Threshold in number of allocations for allocations to be included in
+ # usage reports (0 to include all).
# usage_threshold_count = 0
}
@@ -344,15 +382,30 @@ charon {
# List of TLS encryption ciphers.
# cipher =
+ # List of TLS key exchange groups.
+ # ke_group =
+
# List of TLS key exchange methods.
# key_exchange =
# List of TLS MAC algorithms.
# mac =
+ # Whether to include CAs in a server's CertificateRequest message.
+ # send_certreq_authorities = yes
+
+ # List of TLS signature schemes.
+ # signature =
+
# List of TLS cipher suites.
# suites =
+ # Maximum TLS version to negotiate.
+ # version_max = 1.2
+
+ # Minimum TLS version to negotiate.
+ # version_min = 1.2
+
}
x509 {
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/bin/genkeypair.sh b/roles/common/files/usr/local/bin/genkeypair.sh
index ad65aef..72102f4 100755
--- a/roles/common/files/usr/local/bin/genkeypair.sh
+++ b/roles/common/files/usr/local/bin/genkeypair.sh
@@ -119,14 +119,16 @@ done
case "$type" in
# XXX: genrsa and dsaparam have been deprecated in favor of genpkey.
# genpkey can also create explicit EC parameters, but not named.
- rsa) genkey=genrsa; genkeyargs="-f4 ${bits:-2048}";;
- dsa) genkey=dsaparam; genkeyargs="-noout -genkey ${bits:-1024}";;
+ rsa) genkey=genrsa; genkeyargs="-rand /dev/urandom -f4 ${bits:-2048}";;
+ dsa) genkey=dsaparam; genkeyargs="-rand /dev/urandom -noout -genkey ${bits:-1024}";;
# See 'openssl ecparam -list_curves' for the list of supported
# curves. StrongSwan doesn't support explicit curve parameters
# (however explicit parameters might be required to make exotic
# curves work with some clients.)
ecdsa) genkey=ecparam
- genkeyargs="-noout -name ${bits:-secp224r1} -param_enc named_curve -genkey";;
+ genkeyargs="-rand /dev/urandom -noout -name ${bits:-secp224r1} -param_enc named_curve -genkey";;
+ x25519|x448|ed25519|ed448) genkey=genpkey
+ genkeyargs="-algorithm $type";;
*) echo "Unrecognized key type: $type" >&2; exit 2
esac
@@ -173,7 +175,7 @@ if [ -s "$privkey" -a $force -eq 0 ]; then
exit 1
elif [ ! -s "$privkey" -o $force -ge 2 ]; then
install --mode="${mode:-0600}" ${owner:+--owner="$owner"} ${group:+--group="$group"} /dev/null "$privkey" || exit 2
- openssl $genkey -rand /dev/urandom $genkeyargs >"$privkey" || exit 2
+ openssl $genkey $genkeyargs >"$privkey" || exit 2
[ "$cmd" = dkim ] && exit
fi
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 bbaaef5..18462cb 100644
--- a/roles/common/handlers/main.yml
+++ b/roles/common/handlers/main.yml
@@ -29,6 +29,9 @@
- name: Restart rsyslog
service: name=rsyslog state=restarted
+- name: Restart systemd-resolved
+ service: name=systemd-resolved.service state=restarted
+
- name: Restart systemd-timesyncd
service: name=systemd-timesyncd state=restarted
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..699c6e3 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
@@ -41,7 +40,7 @@
- name: Configure logcheck (1)
copy: src=etc/logcheck/{{ item }}
dest=/etc/logcheck/{{ item }}
- owner=root group=logcheck
+ owner=root group=root
mode=0644
with_items:
- logcheck.conf
@@ -60,8 +59,8 @@
line={{ item }}
state=present
create=yes
- owner=root group=logcheck
- mode=0640
+ owner=root group=root
+ mode=0644
with_items:
- /var/log/syslog
- /var/log/auth.log
diff --git a/roles/common/tasks/main.yml b/roles/common/tasks/main.yml
index fc692fa..1dc286e 100644
--- a/roles/common/tasks/main.yml
+++ b/roles/common/tasks/main.yml
@@ -19,6 +19,11 @@
when: "'webmail' in group_names and 'LDAP_provider' not in group_names"
- import_tasks: auditd.yml
tags: auditd
+- import_tasks: resolved.yml
+ tags:
+ - resolv
+ - resolved
+ - dns
- import_tasks: unbound.yml
tags:
- unbound
@@ -82,6 +87,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/ntp.yml b/roles/common/tasks/ntp.yml
index 60ffef9..2ff9e49 100644
--- a/roles/common/tasks/ntp.yml
+++ b/roles/common/tasks/ntp.yml
@@ -1,9 +1,12 @@
-- name: Install/Remove ntp
- # TODO bullseye: install new package 'systemd-timesyncd'
+- 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
diff --git a/roles/common/tasks/resolved.yml b/roles/common/tasks/resolved.yml
new file mode 100644
index 0000000..2834eaa
--- /dev/null
+++ b/roles/common/tasks/resolved.yml
@@ -0,0 +1,36 @@
+- name: Install systemd-resolved
+ apt: pkg={{ packages }}
+ vars:
+ packages:
+ - systemd-resolved
+ - libnss-resolve
+ - libnss-myhostname
+
+- name: Create directory /etc/systemd/resolved.conf.d
+ file: path=/etc/systemd/resolved.conf.d
+ state=directory
+ owner=root group=root
+ mode=0755
+
+- name: Configure systemd-resolved
+ template: src=etc/systemd/resolved.conf.d/local.conf.j2
+ dest=/etc/systemd/resolved.conf.d/local.conf
+ owner=root group=root
+ mode=0644
+ notify:
+ - Restart systemd-resolved
+
+- name: Start systemd-resolved
+ service: name=systemd-resolved.service enabled=true state=started
+
+- meta: flush_handlers
+
+- name: Remove resolvconf
+ apt: pkg=resolvconf state=absent purge=yes
+
+- name: Configure /etc/nsswitch.conf
+ lineinfile: "dest=/etc/nsswitch.conf create=no
+ regexp='^(hosts:\\s+).*'
+ line='\\1resolve [!UNAVAIL=return] files myhostname dns'
+ backrefs=true"
+ tags: nsswitch
diff --git a/roles/common/tasks/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 f95b7fa..08a1b13 100644
--- a/roles/common/tasks/sysctl.yml
+++ b/roles/common/tasks/sysctl.yml
@@ -13,11 +13,9 @@
# 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
- # TODO bullseye: remove net.core.somaxconn as 5.4 and later default to 4096
- { name: 'net.ipv4.tcp_syncookies', value: 0 }
- { name: 'net.ipv4.tcp_synack_retries', value: 1 }
- { name: 'net.ipv4.tcp_max_syn_backlog', value: 32768 }
- - { name: 'net.core.somaxconn', value: 4096 }
# We rate-limit not only the default ICMP types 3, 4, 11 and 12
# (0x1818), but also types 0 and 8. See icmp(7).
diff --git a/roles/common/tasks/unbound.yml b/roles/common/tasks/unbound.yml
index b4554ac..dda6769 100644
--- a/roles/common/tasks/unbound.yml
+++ b/roles/common/tasks/unbound.yml
@@ -19,14 +19,3 @@
when: not r.changed
#- meta: flush_handlers
-
-- name: Use the local DNS server
- lineinfile: dest=/etc/resolv.conf create=yes
- regexp='^nameserver\s+127\.0\.0\.1\s*$'
- line='nameserver 127.0.0.1'
- insertbefore='^\s*#*?nameserver\s'
- firstmatch=yes
- tags:
- - resolver
- notify:
- - Restart Postfix
diff --git a/roles/common/templates/etc/apt/preferences.j2 b/roles/common/templates/etc/apt/preferences.j2
index 383037f..39b610e 100644
--- a/roles/common/templates/etc/apt/preferences.j2
+++ b/roles/common/templates/etc/apt/preferences.j2
@@ -1,10 +1,10 @@
# {{ ansible_managed }}
# Do NOT edit this file directly!
-# Install updates as soon as they're available
-Package: *
-Pin: release o=Debian, n={{ ansible_lsb.codename }}-updates
-Pin-Priority: 990
+## Install updates as soon as they're available
+#Package: *
+#Pin: release o=Debian, n={{ ansible_lsb.codename }}-updates
+#Pin-Priority: 990
{% if 'backports' in group_names -%}
# Automatically packages from backports (those manually installed)
@@ -20,7 +20,7 @@ Pin: release o=Debian
Pin-Priority: 200
{% endif %}
-{% if ansible_processor[1] is search('^(Genuine)?Intel.*') and not ansible_virtualization_role == 'guest' -%}
+{% if ansible_processor[1] is search('^(Genuine)?Intel.*') and not ansible_virtualization_role == 'guest' and ansible_lsb.major_release | int < 12 -%}
# Automatically upgrade the microcode (when manually installed)
Package: intel-microcode iucode-tool
Pin: release o=Debian
diff --git a/roles/common/templates/etc/apt/sources.list.j2 b/roles/common/templates/etc/apt/sources.list.j2
index 47a7cda..f524f2f 100644
--- a/roles/common/templates/etc/apt/sources.list.j2
+++ b/roles/common/templates/etc/apt/sources.list.j2
@@ -2,11 +2,11 @@
# Do NOT edit this file directly!
# vim: set filetype=debsources :
-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 {{ 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' and ansible_lsb.major_release | int < 12) %} contrib non-free{% endif %}{% if ansible_lsb.major_release | int >= 12 %} non-free-firmware{% 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' and ansible_lsb.major_release | int < 12) %} contrib non-free{% endif %}{% if ansible_lsb.major_release | int >= 12 %} non-free-firmware{% endif %}
-deb https://deb.debian.org/debian {{ ansible_lsb.codename }}-updates main
+deb https://deb.debian.org/debian {{ ansible_lsb.codename }}-updates main{% if ansible_lsb.major_release | int >= 12 %} non-free-firmware{% endif %}
{% if 'backports' in group_names -%}
deb https://deb.debian.org/debian {{ ansible_lsb.codename }}-backports 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..eaa9a08 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,8 @@ 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
+ reqid = {{ ipsec[ hostvars[host].inventory_hostname_short ].replace(":",".").split(".")[-1] }}
{% 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 8d81d4c..f603ed9 100755
--- a/roles/common/templates/etc/nftables.conf.j2
+++ b/roles/common/templates/etc/nftables.conf.j2
@@ -73,7 +73,7 @@ table netdev filter {
# 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 | ipaddr('10.0.0.0/8') %}
+{% 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)
@@ -82,7 +82,7 @@ table netdev filter {
, 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 | ipaddr('192.168.0.0/16') %}
+{% 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)
@@ -145,7 +145,7 @@ table inet raw {
}
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; }
@@ -155,16 +155,8 @@ table inet filter {
iif lo accept
- # XXX Bullseye: this is a rather crude match as nftables 0.9.0 lacks support for ipsec expressions
- # to match match inbound resp. outbound policies and source resp. destination tunnel addresses.
- # https://serverfault.com/questions/971735/how-to-match-reqid-in-nftables
- # https://blog.fraggod.net/2016/09/25/nftables-re-injected-ipsec-matching-without-xt_policy.html
- # (We can't use marks to match post-ESP decapsulation here because that doesn't work well with UDP
- # encapsulation.) We'll also pin the reqid to the lowest address byte in ipsec.conf(5); that way
- # peers can't impersonate each other.
meta l4proto esp accept
- # 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
+ ip daddr {{ ipsec[inventory_hostname_short] }} jump ipsec-in
# incoming ICMP/ICMPv6 traffic was filtered in the ingress chain already
meta l4proto { icmp, icmpv6 } counter accept
@@ -186,8 +178,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
@@ -200,12 +192,8 @@ table inet filter {
oif lo accept
- # XXX Bullseye: unlike for input we can't use marks or test for
- # secpath existence here, because by the time we see a packet to
- # 172.16.0.0/24 we don't know if it'll be encapsulated
meta l4proto esp accept
- # 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
+ ip saddr {{ ipsec[inventory_hostname_short] }} jump ipsec-out
meta l4proto { icmp, icmpv6 } counter accept
@@ -234,4 +222,17 @@ table inet filter {
meta l4proto udp counter reject
counter reject
}
+
+ chain ipsec-in {
+{% for h in ipsec.keys() | difference([inventory_hostname_short]) | sort %}
+ ip saddr {{ ipsec[h] }} ipsec in reqid {{ ipsec[h].replace(":",".").split(".")[-1] }} counter accept
+{% endfor %}
+ log prefix "ipsec-in " drop
+ }
+ chain ipsec-out {
+{% for h in ipsec.keys() | difference([inventory_hostname_short]) | sort %}
+ ip daddr {{ ipsec[h] }} ipsec out reqid {{ ipsec[h].replace(":",".").split(".")[-1] }} counter accept
+{% endfor %}
+ log prefix "ipsec-out " drop
+ }
}
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/systemd/resolved.conf.d/local.conf.j2 b/roles/common/templates/etc/systemd/resolved.conf.d/local.conf.j2
new file mode 100644
index 0000000..044170a
--- /dev/null
+++ b/roles/common/templates/etc/systemd/resolved.conf.d/local.conf.j2
@@ -0,0 +1,11 @@
+[Resolve]
+LLMNR=no
+{% if ansible_processor[1] is search('^(Genuine)?Intel.*') and not ansible_virtualization_role == 'guest' %}
+DNS=127.0.0.1
+# Quad9
+FallbackDNS=9.9.9.9#dns.quad9.net 149.112.112.112#dns.quad9.net 2620:fe::fe#dns.quad9.net 2620:fe::9#dns.quad9.net
+{% else %}
+# Quad9
+DNS=9.9.9.9#dns.quad9.net 149.112.112.112#dns.quad9.net 2620:fe::fe#dns.quad9.net 2620:fe::9#dns.quad9.net
+{% endif %}
+Domains=fripost.org
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"
diff --git a/roles/lacme/files/etc/lacme/lacme.conf b/roles/lacme/files/etc/lacme/lacme.conf
index b49c87a..28633b6 100644
--- a/roles/lacme/files/etc/lacme/lacme.conf
+++ b/roles/lacme/files/etc/lacme/lacme.conf
@@ -8,30 +8,28 @@
# The value of "socket" specifies the path to the lacme-accountd(1)
# UNIX-domain socket to connect to for signature requests from the ACME
-# client. lacme(1) aborts if the socket is readable or writable by
+# client. lacme(8) aborts if the socket is readable or writable by
# other users, or if its parent directory is writable by other users.
-# Default: "$XDG_RUNTIME_DIR/S.lacme" if the XDG_RUNTIME_DIR environment
-# variable is set.
-# This option is ignored when lacme-accountd(1) is spawned by lacme(1),
+# This setting is ignored when lacme-accountd(1) is spawned by lacme(8),
# since the two processes communicate through a socket pair. See the
# "accountd" section below for details.
#
-#socket =
+#socket = %t/S.lacme
# username to drop privileges to (setting both effective and real uid).
-# Preserve root privileges if the value is empty (not recommended).
+# Skip privilege drop if the value is empty (not recommended).
#
-user = _lacme
+#user = _lacme-client
# groupname to drop privileges to (setting both effective and real gid,
# and also setting the list of supplementary gids to that single group).
-# Preserve root privileges if the value is empty (not recommended).
+# Skip privilege drop if the value is empty (not recommended).
#
-group = nogroup
+#group = nogroup
-# Path to the ACME client executable.
+# ACME client command.
#
-#command = /usr/lib/lacme/client
+#command = /usr/libexec/lacme/client
# URI of the ACME server's directory. NOTE: Use the staging server
# <https://acme-staging-v02.api.letsencrypt.org/directory> for testing
@@ -42,19 +40,19 @@ group = nogroup
# Timeout in seconds after which the client stops polling the ACME
# server and considers the request failed.
#
-#timeout = 10
+#timeout = 30
# Whether to verify the server certificate chain.
#
-SSL_verify = yes
+#SSL_verify = yes
# Specify the version of the SSL protocol used to transmit data.
#
-SSL_version = SSLv23:!TLSv1_1:!TLSv1:!SSLv3:!SSLv2
+#SSL_version = SSLv23:!TLSv1_1:!TLSv1:!SSLv3:!SSLv2
# Specify the cipher list for the connection.
#
-SSL_cipher_list = EECDH+AESGCM:EECDH+CHACHA20!MEDIUM!LOW!EXP!aNULL!eNULL
+#SSL_cipher_list = EECDH+AESGCM:!MEDIUM:!LOW:!EXP:!aNULL:!eNULL
[webserver]
@@ -64,32 +62,62 @@ SSL_cipher_list = EECDH+AESGCM:EECDH+CHACHA20!MEDIUM!LOW!EXP!aNULL!eNULL
#
#listen = /run/lacme-www.socket
-# Non-existent directory under which an external HTTP daemon is
-# configured to serve GET requests for challenge files under
-# "/.well-known/acme-challenge/" (for each virtual host requiring
-# authorization) as static files.
+# Directory under which an external HTTP daemon is configured to serve
+# GET requests for challenge files under "/.well-known/acme-challenge/"
+# (for each virtual host requiring authorization) as static files.
+# NOTE: the directory must exist and be writable by the lacme client
+# user.
#
#challenge-directory =
# username to drop privileges to (setting both effective and real uid).
-# Preserve root privileges if the value is empty (not recommended).
+# Skip privilege drop if the value is empty (not recommended).
#
-user = www-data
+#user = _lacme-www
# groupname to drop privileges to (setting both effective and real gid,
# and also setting the list of supplementary gids to that single group).
-# Preserve root privileges if the value is empty (not recommended).
+# Skip privilege drop if the value is empty (not recommended).
#
-group = www-data
+#group = nogroup
-# Path to the ACME webserver executable.
+# ACME webserver command.
#
-#command = /usr/lib/lacme/webserver
+#command = /usr/libexec/lacme/webserver
# Whether to automatically install iptables(8) rules to open the
# ADDRESS[:PORT] specified with listen. Theses rules are automatically
-# removed once lacme(1) exits.
+# removed once lacme(8) exits.
#
#iptables = No
+
+[accountd]
+# lacme-accound(1) section. Comment out this section (including its
+# header), or use the --socket= CLI option, to make lacme(8) connect to
+# an existing lacme-accountd(1) process via a UNIX-domain socket.
+
+# username to drop privileges to (setting both effective and real uid).
+# Skip privilege drop if the value is empty.
+#
+#user =
+
+# groupname to drop privileges to (setting both effective and real gid,
+# and also setting the list of supplementary gids to that single group).
+# Skip privilege drop if the value is empty.
+#
+#group =
+
+# lacme-accountd(1) command.
+#
+#command = /usr/bin/lacme-accountd
+
+# Path to the lacme-accountd(1) configuration file.
+#
+#config =
+
+# Be quiet.
+#
+#quiet = Yes
+
; vim:ft=dosini
diff --git a/roles/lacme/tasks/main.yml b/roles/lacme/tasks/main.yml
index 5ae2597..b031b25 100644
--- a/roles/lacme/tasks/main.yml
+++ b/roles/lacme/tasks/main.yml
@@ -5,15 +5,6 @@
- liblwp-protocol-https-perl
- lacme
-- name: Create '_lacme' user
- user: name=_lacme system=yes
- group=nogroup
- createhome=no
- home=/nonexistent
- shell=/usr/sbin/nologin
- password=!
- state=present
-
- name: Copy lacme/lacme-certs.conf
copy: src=etc/lacme/lacme.conf
dest=/etc/lacme/lacme.conf
diff --git a/roles/lists/files/etc/nginx/sites-available/sympa b/roles/lists/files/etc/nginx/sites-available/sympa
index 89d79f3..9b6aed2 100644
--- a/roles/lists/files/etc/nginx/sites-available/sympa
+++ b/roles/lists/files/etc/nginx/sites-available/sympa
@@ -26,7 +26,7 @@ server {
include snippets/headers.conf;
add_header Content-Security-Policy
- "default-src 'none'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self'; font-src 'self'; frame-ancestors 'none'; form-action 'self'; base-uri lists.fripost.org";
+ "default-src 'none'; connect-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self'; font-src 'self'; frame-ancestors 'none'; form-action 'self'; base-uri lists.fripost.org";
include snippets/ssl.conf;
ssl_certificate ssl/lists.fripost.org.pem;
@@ -72,7 +72,7 @@ server {
return 404;
}
- fastcgi_split_path_info ^(/[^/]+/sympa)(.*)$;
+ fastcgi_split_path_info ^/[^/]+(/sympa)(.*)$;
include snippets/fastcgi.conf;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SERVER_NAME $vhost;
diff --git a/roles/lists/files/etc/sympa/sympa/sympa.conf b/roles/lists/files/etc/sympa/sympa/sympa.conf
index 75072cf..a864a14 100644
--- a/roles/lists/files/etc/sympa/sympa/sympa.conf
+++ b/roles/lists/files/etc/sympa/sympa/sympa.conf
@@ -48,7 +48,7 @@ etc /etc/sympa
## Syslog facility for sympa
## Do not forget to edit syslog.conf
-syslog `cat /etc/sympa/facility`
+syslog LOCAL1
## Log verbosity
## 0: normal, 2,3,4: for debug
@@ -164,7 +164,7 @@ queueautomatic /var/spool/sympa/automatic
## Supported languages
## This is the set of language that will be proposed to your users for the Sympa GUI. Don't select a language if you don't have the proper locale packages installed.
-supported_lang sv,en_US
+supported_lang sv,en_US,fr
## Default language (one of supported languages)
## This is the default language used by Sympa
@@ -285,7 +285,7 @@ dkim_signature_apply_on md5_authenticated_messages,smime_authenticated_messages,
## DMARC protection
## https://sympa-community.github.io/manual/customize/dmarc-protection.html
-dmarc_protection_mode dmarc_reject
+dmarc_protection_mode all
###\\\\ Antivirus plug-in ////###
@@ -364,7 +364,7 @@ ldap_force_canonical_email 1
## Syslog facility for wwsympa, archived and bounced
## Default is to use previously defined sympa log facility.
-log_facility `cat /etc/sympa/facility`
+log_facility LOCAL1
#log_module
@@ -393,3 +393,5 @@ use_fast_cgi 1
## Default number of lines of the array displaying the log entries in the logs
## page
viewlogs_page_size 25
+
+shared_feature on
diff --git a/roles/lists/tasks/sympa.yml b/roles/lists/tasks/sympa.yml
index 0d5eac1..27a5823 100644
--- a/roles/lists/tasks/sympa.yml
+++ b/roles/lists/tasks/sympa.yml
@@ -10,8 +10,8 @@
- libcrypt-openssl-x509-perl
- name: Make the 'sympa' MySQL user use unix_socket
- mysql_user2: name=sympa password= auth_plugin=unix_socket
- state=present
+ mysql_user: name=sympa password= plugin=unix_socket
+ state=present
- name: Configure Sympa
copy: src=etc/sympa/{{ item }}
diff --git a/roles/lists/templates/etc/postfix/main.cf.j2 b/roles/lists/templates/etc/postfix/main.cf.j2
index 1bf02eb..2be1b41 100644
--- a/roles/lists/templates/etc/postfix/main.cf.j2
+++ b/roles/lists/templates/etc/postfix/main.cf.j2
@@ -21,7 +21,7 @@ append_dot_mydomain = no
mynetworks = 127.0.0.0/8, [::1]/128
{%- if groups.all | length > 1 -%}
{%- for mx in groups.MX | sort -%}
- , {{ ipsec[ hostvars[mx].inventory_hostname_short ] | ipaddr }}
+ , {{ ipsec[ hostvars[mx].inventory_hostname_short ] | ansible.utils.ipaddr }}
{%- endfor %}
{% endif %}
diff --git a/roles/lists/templates/etc/sympa/robot.conf.j2 b/roles/lists/templates/etc/sympa/robot.conf.j2
index 75687d8..28998e3 100644
--- a/roles/lists/templates/etc/sympa/robot.conf.j2
+++ b/roles/lists/templates/etc/sympa/robot.conf.j2
@@ -1,3 +1,2 @@
-http_host {{ item }}
+#wwsympa_url_local https://{{ item }}/sympa
wwsympa_url https://{{ item }}/sympa
-# wwsympa_url https://lists.fripost.org/{{ item }}/sympa
diff --git a/roles/nextcloud/files/etc/ldap/ldap.conf b/roles/nextcloud/files/etc/ldap/ldap.conf
index 5f388f1..b4ebe34 100644
--- a/roles/nextcloud/files/etc/ldap/ldap.conf
+++ b/roles/nextcloud/files/etc/ldap/ldap.conf
@@ -6,5 +6,5 @@
# This file should be world readable but not world writable.
# TLS certificates (needed for GnuTLS)
-TLS_CACERT /etc/ldap/ssl/ldap.fripost.org.pem
-TLS_REQCERT hard
+TLS_CACERT /etc/ldap/ssl/ldap.fripost.org.pem
+TLS_REQCERT hard
diff --git a/roles/nextcloud/files/etc/nginx/sites-available/nextcloud b/roles/nextcloud/files/etc/nginx/sites-available/nextcloud
index 52f24e0..f1f4dcc 100644
--- a/roles/nextcloud/files/etc/nginx/sites-available/nextcloud
+++ b/roles/nextcloud/files/etc/nginx/sites-available/nextcloud
@@ -23,7 +23,7 @@ server {
root /usr/local/share/nextcloud;
include snippets/headers.conf;
- add_header X-Robots-Tag none;
+ add_header X-Robots-Tag "noindex, nofollow";
add_header X-Download-Options noopen;
add_header X-Permitted-Cross-Domain-Policies none;
@@ -32,6 +32,12 @@ server {
ssl_certificate_key ssl/cloud.fripost.org.key;
include snippets/cloud.fripost.org.hpkp-hdr;
+ include mime.types;
+ types {
+ text/javascript js mjs;
+ application/wasm wasm;
+ }
+
location = /robots.txt {
allow all;
log_not_found off;
@@ -41,8 +47,11 @@ server {
access_log /var/log/nginx/cloud.access.log;
error_log /var/log/nginx/cloud.error.log info;
- location = /.well-known/carddav { return 301 $scheme://$host/remote.php/dav; }
- location = /.well-known/caldav { return 301 $scheme://$host/remote.php/dav; }
+ index index.php index.html /index.php$request_uri;
+
+ location = /.well-known/carddav { return 301 /remote.php/dav; }
+ location = /.well-known/caldav { return 301 /remote.php/dav; }
+ location ^~ /.well-known/ { return 301 /index.php$request_uri; }
# set max upload size
client_max_body_size 512M;
@@ -57,38 +66,42 @@ server {
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
- error_page 403 /core/templates/403.php;
- error_page 404 /core/templates/404.php;
-
- location = / { return 303 $scheme://$host/apps/files/; }
- location / { rewrite ^ /index.php$uri last; }
+ location = / { return 303 /apps/files/; }
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ { internal; }
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { internal; }
- location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|oc[ms]-provider/.+|core/templates/40[34])\.php(?:$|/) {
+ location ~ \.php(?:$|/) {
+ # Required for legacy support
+ rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|ocs-provider\/.+|.+\/richdocumentscode(_arm64)?\/proxy) /index.php$request_uri;
+
include snippets/fastcgi-php.conf;
fastcgi_param modHeadersAvailable true;
fastcgi_param front_controller_active true;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
- fastcgi_pass unix:/run/php/php7.3-fpm@nextcloud.sock;
- }
-
- location ~ ^/(?:updater|oc[ms]-provider)(?:$|/) {
- try_files $uri/ =404;
- index index.php;
+ fastcgi_pass unix:/run/php/php8.2-fpm@nextcloud.sock;
}
- location ~ \.(?:css|js|woff2?|svg|gif|map)$ {
- expires 30d;
+ location ~ \.(?:css|js|mjs|svg|gif|png|jpg|ico|wasm|tflite|map|ogg|flac)$ {
try_files $uri /index.php$uri$is_args$args;
}
-
+ location ~ \.woff2?$ {
+ try_files $uri /index.php$request_uri;
+ expires 7d;
+ }
location ~ \.(?:png|html|ttf|ico|jpg|jpeg|bcmap)$ {
try_files $uri /index.php$uri$is_args$args;
}
+ location /remote {
+ return 301 /remote.php$request_uri;
+ }
+
+ location / {
+ try_files $uri $uri/ /index.php$request_uri;
+ }
+
location = /core/img/favicon.ico {
alias /var/www/nextcloud/fripost.ico;
}
diff --git a/roles/nextcloud/files/etc/php/fpm/pool.d/nextcloud.conf b/roles/nextcloud/files/etc/php/fpm/pool.d/nextcloud.conf
index eb92adb..898ce60 100644
--- a/roles/nextcloud/files/etc/php/fpm/pool.d/nextcloud.conf
+++ b/roles/nextcloud/files/etc/php/fpm/pool.d/nextcloud.conf
@@ -1,7 +1,7 @@
[nextcloud]
user = _nextcloud
group = nogroup
-listen = /run/php/php7.3-fpm@nextcloud.sock
+listen = /run/php/php8.2-fpm@nextcloud.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0600
diff --git a/roles/nextcloud/handlers/main.yml b/roles/nextcloud/handlers/main.yml
index 1e48524..a14d6e1 100644
--- a/roles/nextcloud/handlers/main.yml
+++ b/roles/nextcloud/handlers/main.yml
@@ -1,6 +1,6 @@
---
-- name: Restart php7.3-fpm
- service: name=php7.3-fpm state=restarted
+- name: Restart php8.2-fpm
+ service: name=php8.2-fpm state=restarted
- name: Restart Redis
service: name=redis-server state=restarted
diff --git a/roles/nextcloud/tasks/main.yml b/roles/nextcloud/tasks/main.yml
index 4a366fa..14bc02c 100644
--- a/roles/nextcloud/tasks/main.yml
+++ b/roles/nextcloud/tasks/main.yml
@@ -19,8 +19,8 @@
- php-json
- php-gmp
-- name: Configure PHP 7.3 Zend opcache
- lineinfile: dest=/etc/php/7.3/fpm/php.ini
+- name: Configure PHP 8.2 Zend opcache
+ lineinfile: dest=/etc/php/8.2/fpm/php.ini
regexp='^;?{{ item.var }}\\s*='
line="{{ item.var }} = {{ item.value }}"
owner=root group=root
@@ -28,8 +28,18 @@
with_items:
- { var: opcache.memory_consumption, value: 512 }
- { var: opcache.revalidate_freq, value: 180 }
+ - { var: opcache.interned_strings_buffer, value: 12 }
notify:
- - Restart php7.3-fpm
+ - Restart php8.2-fpm
+
+- name: Configure PHP 8.2 CLI
+ lineinfile: dest=/etc/php/8.2/cli/php.ini
+ regexp='^;?{{ item.var }}\\s*='
+ line="{{ item.var }} = {{ item.value }}"
+ owner=root group=root
+ mode=0644
+ with_items:
+ - { var: apc.enable_cli, value: 1 }
- name: Create '_nextcloud' user
user: name=_nextcloud system=yes
@@ -40,21 +50,21 @@
password=!
state=present
-- name: Delete PHP 7.3 FPM's www pool
- file: path=/etc/php/7.3/fpm/pool.d/www.conf state=absent
+- name: Delete PHP 8.2 FPM's www pool
+ file: path=/etc/php/8.2/fpm/pool.d/www.conf state=absent
notify:
- - Restart php7.3-fpm
+ - Restart php8.2-fpm
-- name: Configure PHP 7.3 FPM's nextcloud pool
+- name: Configure PHP 8.2 FPM's nextcloud pool
copy: src=etc/php/fpm/pool.d/nextcloud.conf
- dest=/etc/php/7.3/fpm/pool.d/nextcloud.conf
+ dest=/etc/php/8.2/fpm/pool.d/nextcloud.conf
owner=root group=root
mode=0644
notify:
- - Restart php7.3-fpm
+ - Restart php8.2-fpm
-- name: Start php7.3-fpm
- service: name=php7.3-fpm state=started
+- name: Start php8.2-fpm
+ service: name=php8.2-fpm state=started
- name: Copy /etc/cron.d/nextcloud
copy: src=etc/cron.d/nextcloud
@@ -181,4 +191,10 @@
- name: Add '_nextcloud' user to 'redis' group
user: name=_nextcloud groups=redis append=yes
notify:
- - Restart php7.3-fpm
+ - Restart php8.2-fpm
+
+- name: Install other Nextcloud dependencies
+ apt: pkg={{ packages }}
+ vars:
+ packages:
+ - libmagickcore-6.q16-6-extra
diff --git a/roles/webmail/files/etc/nginx/sites-available/roundcube b/roles/webmail/files/etc/nginx/sites-available/roundcube
index 46012f8..602668f 100644
--- a/roles/webmail/files/etc/nginx/sites-available/roundcube
+++ b/roles/webmail/files/etc/nginx/sites-available/roundcube
@@ -65,7 +65,7 @@ server {
# https://www.sjoerdlangkemper.nl/2016/11/07/current-state-of-breach-attack/#same-site-cookies
gzip off;
include snippets/fastcgi-php-ssl.conf;
- fastcgi_pass unix:/var/run/php/php7.3-fpm@roundcube.sock;
+ fastcgi_pass unix:/var/run/php/php7.4-fpm@roundcube.sock;
}
location ~ "^/(?:plugins|program/js|program/resources|skins)(?:/[[:alnum:]][[:alnum:]\-\._]*)+\.(?:css|eot|gif|html|ico|jpg|js|pdf|png|svg|tiff?|ttf|webp|woff2?)$" {
diff --git a/roles/webmail/files/etc/php/fpm/pool.d/roundcube.conf b/roles/webmail/files/etc/php/fpm/pool.d/roundcube.conf
index 1512d66..1a7a1d8 100644
--- a/roles/webmail/files/etc/php/fpm/pool.d/roundcube.conf
+++ b/roles/webmail/files/etc/php/fpm/pool.d/roundcube.conf
@@ -1,7 +1,7 @@
[roundcube]
user = _roundcube
group = nogroup
-listen = /run/php/php7.3-fpm@roundcube.sock
+listen = /run/php/php7.4-fpm@roundcube.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0600
diff --git a/roles/webmail/handlers/main.yml b/roles/webmail/handlers/main.yml
index 5b730d7..8c70168 100644
--- a/roles/webmail/handlers/main.yml
+++ b/roles/webmail/handlers/main.yml
@@ -2,8 +2,8 @@
- name: Restart stunnel@ldap
service: name=stunnel4@ldap state=restarted
-- name: Restart php7.3-fpm
- service: name=php7.3-fpm state=restarted
+- name: Restart php7.4-fpm
+ service: name=php7.4-fpm state=restarted
- name: Restart Nginx
service: name=nginx state=restarted
diff --git a/roles/webmail/tasks/roundcube.yml b/roles/webmail/tasks/roundcube.yml
index 1e27841..bd174bc 100644
--- a/roles/webmail/tasks/roundcube.yml
+++ b/roles/webmail/tasks/roundcube.yml
@@ -10,8 +10,8 @@
- php-enchant
## TODO: run php as a dedicated system user
-- name: Configure PHP 7.3 Zend opcache
- lineinfile: dest=/etc/php/7.3/fpm/php.ini
+- name: Configure PHP 7.4 Zend opcache
+ lineinfile: dest=/etc/php/7.4/fpm/php.ini
regexp='^;?{{ item.var }}\\s*='
line="{{ item.var }} = {{ item.value }}"
owner=root group=root
@@ -20,7 +20,7 @@
- { var: opcache.memory_consumption, value: 128 }
- { var: opcache.revalidate_freq, value: 60 }
notify:
- - Restart php7.3-fpm
+ - Restart php7.4-fpm
- name: Create '_roundcube' user
user: name=_roundcube system=yes
@@ -31,21 +31,21 @@
password=!
state=present
-- name: Delete PHP 7.3 FPM's www pool
- file: path=/etc/php/7.3/fpm/pool.d/www.conf state=absent
+- name: Delete PHP 7.4 FPM's www pool
+ file: path=/etc/php/7.4/fpm/pool.d/www.conf state=absent
notify:
- - Restart php7.3-fpm
+ - Restart php7.4-fpm
-- name: Configure PHP 7.3 FPM's roundcube pool
+- name: Configure PHP 7.4 FPM's roundcube pool
copy: src=etc/php/fpm/pool.d/roundcube.conf
- dest=/etc/php/7.3/fpm/pool.d/roundcube.conf
+ dest=/etc/php/7.4/fpm/pool.d/roundcube.conf
owner=root group=root
mode=0644
notify:
- - Restart php7.3-fpm
+ - Restart php7.4-fpm
-- name: Start php7.3-fpm
- service: name=php7.3-fpm state=started
+- name: Start php7.4-fpm
+ service: name=php7.4-fpm state=started
# Make it sticky: `dpkg-statoverride --add _roundcube nogroup 0700 /var/lib/roundcube/temp`
- name: Create cache directory /var/lib/roundcube/temp
@@ -75,7 +75,7 @@
- aspell-sv
- name: Install Roundcube
- apt: pkg={{ packages }} default_release={{ ansible_lsb.codename }}-backports
+ apt: pkg={{ packages }}
vars:
packages:
- roundcube-core
@@ -110,19 +110,21 @@
# IMAP
# WARNING: After hostname change update of mail_host column in users
# table is required to match old user data records with the new host.
- - { var: default_host, value: "'{{ imapsvr_addr | ipaddr }}'" }
- - { var: default_port, value: "143" }
- - { var: imap_auth_type, value: "'PLAIN'" }
- - { var: imap_cache, value: "null" }
- - { var: imap_timeout, value: "180" }
- - { var: imap_force_ns, value: "true" }
- - { var: messages_cache, value: "false" }
+ - { var: default_host, value: "'{{ imapsvr_addr | ansible.utils.ipaddr }}'" }
+ - { var: default_port, value: "143" }
+ - { var: imap_auth_type, value: "'PLAIN'" }
+ - { var: imap_cache, value: "null" }
+ - { var: imap_timeout, value: "180" }
+ - { var: imap_force_ns, value: "true" }
+ - { var: messages_cache, value: "false" }
# SMTP
- - { var: smtp_server, value: "'{{ postfix_instance.MSA.addr | ipaddr }}'" }
- - { var: smtp_port, value: "{{ postfix_instance.MSA.port }}" }
- - { var: smtp_auth_type, value: "'PLAIN'" }
- - { var: smtp_user, value: "'%u'" }
- - { var: smtp_pass, value: "'%p'" }
+ - { var: smtp_server, value: "'{{ postfix_instance.MSA.addr | ansible.utils.ipaddr }}'" }
+ - { var: smtp_port, value: "{{ postfix_instance.MSA.port }}" }
+ - { var: smtp_auth_type, value: "'PLAIN'" }
+ - { var: smtp_user, value: "'%u'" }
+ - { var: smtp_pass, value: "'%p'" }
+ # avoid timeout
+ - { var: max_recipients, value: "15" }
# System
- { var: force_https, value: "true" }
- { var: login_autocomplete, value: "2" }
@@ -182,8 +184,8 @@
with_items:
- managesieve
-- name: Start php7.3-fpm
- service: name=php7.3-fpm state=started
+- name: Start php7.4-fpm
+ service: name=php7.4-fpm state=started
- name: Copy /etc/cron.d/roundcube-core
copy: src=etc/cron.d/roundcube-core
diff --git a/roles/webmail/templates/etc/roundcube/plugins/managesieve/config.inc.php.j2 b/roles/webmail/templates/etc/roundcube/plugins/managesieve/config.inc.php.j2
index 66af466..7b424e4 100644
--- a/roles/webmail/templates/etc/roundcube/plugins/managesieve/config.inc.php.j2
+++ b/roles/webmail/templates/etc/roundcube/plugins/managesieve/config.inc.php.j2
@@ -10,7 +10,7 @@ $config['managesieve_port'] = 4190;
// %n - http hostname ($_SERVER['SERVER_NAME'])
// %d - domain (http hostname without the first part)
// For example %n = mail.domain.tld, %d = domain.tld
-$config['managesieve_host'] = '{{ imapsvr_addr | ipaddr }}';
+$config['managesieve_host'] = '{{ imapsvr_addr | ansible.utils.ipaddr }}';
// authentication method. Can be CRAM-MD5, DIGEST-MD5, PLAIN, LOGIN, EXTERNAL
// or none. Optional, defaults to best method supported by server.
@@ -60,7 +60,7 @@ $config['managesieve_replace_delimiter'] = '';
// mailbox, mboxmetadata, regex, reject, relational, servermetadata,
// spamtest, spamtestplus, subaddress, vacation, variables, virustest, etc.
// Note: not all extensions are implemented
-$config['managesieve_disabled_extensions'] = array();
+$config['managesieve_disabled_extensions'] = array('reject','ereject');
// Enables debugging of conversation with sieve server. Logs it into <log_dir>/sieve
$config['managesieve_debug'] = false;