diff options
127 files changed, 1468 insertions, 2416 deletions
diff --git a/ansible.cfg b/ansible.cfg index fac3b72..09c8745 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -39,6 +39,6 @@ become_ask_pass=True [ssh_connection] -control_path = ~/.ssh/S.ansible-%%C +control_path = ${XDG_RUNTIME_DIR}/ssh-ansible-%%C ssh_args = -oHashKnownHosts=no -oUserKnownHostsFile=./certs/ssh_known_hosts -oStrictHostKeyChecking=yes -oControlMaster=auto -oControlPersist=60s pipelining = True diff --git a/certs/dkim/0ef2a7235861d65c872faf4e72b29a29:jakmedlem.se.pub b/certs/dkim/0ef2a7235861d65c872faf4e72b29a29:jakmedlem.se.pub new file mode 100644 index 0000000..07b06bc --- /dev/null +++ b/certs/dkim/0ef2a7235861d65c872faf4e72b29a29:jakmedlem.se.pub @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA631Sqr0EH+zzmS8g1I6f +JziGSCos24MbNjt//uqJVdkSEO6syumWePmYLzVz/G4PhFl4D1Y3ZtbXS8bR+BZ6 +MJNy+U+nGfyqo/MOxEPXIT/tRVa/8Ikniq1mvasIhX+TZllCf86wLCo061bgn9cH +IiZS6zeSgxGbLWEQdSE7Kb/Pd0vzH2piaVEA4MzZQyonguqMlm3AU4kQ0k8pMp6k +caMSUr7WxEPE6k5p5ah+mJ54fAvezkXyBs7oDuc3SrExkv2mfjBifN+GlGzMsYbb +iQl4ixfxPAw1pLwP4/sPDhdIZf0vQcrSgxuEMGmFr23BD7moCLXn0lXxalICkz7m +xwIDAQAB +-----END PUBLIC KEY----- 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/a4b2e822cfcf594acd24f44587590eb1:gbg.cmsmarx.org.pub b/certs/dkim/a4b2e822cfcf594acd24f44587590eb1:gbg.cmsmarx.org.pub new file mode 100644 index 0000000..e4b2949 --- /dev/null +++ b/certs/dkim/a4b2e822cfcf594acd24f44587590eb1:gbg.cmsmarx.org.pub @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvmO04P51AngD41CpgrTm +5Mjs4M4iT10In9JF9X2l83opAoiGDoTPElcXxmmGvOvwbUV1Q2sNb2/WKLhNvlRp +EgZiBqBd9Gf1Rf9OxpoQlfZjdhbQ5UPhxma4f/saN3RNNvAgDH+TE6DltAvZF+kW +sjRlBabVdB+vPHBwfSBIEHvzS2rJLwx8jzzsWJQpBRkjBcueX2v4AmPIw2Lc0RJh +/76a63xyeyGXcvKzHrBlhZPl+P6Yz5KXOE9eGJmdS9ahArZTUs5ACSwWlSrJyDUo +hT7UeuDp0/J3HMKY51CsMwTLUxfrUoNMIAyJTJg20XeqkYzymMG5hgFilhdJdS4C +PwIDAQAB +-----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/gencerts.sh b/certs/gencerts.sh index b796339..3314757 100755 --- a/certs/gencerts.sh +++ b/certs/gencerts.sh @@ -26,8 +26,8 @@ x509fpr() { host="${msg%%,*}"; host="${host%% *}"; host="${host#\`}" pub="$DIR/${host%%:*}.pub" spki=$(openssl pkey -pubin -outform DER <"$pub" | openssl dgst -sha256 | sed -nr 's/^[^=]+=\s*//p') - [ "$typ" = mdwn ] && printf '\n[%s](https://crt.sh/?spkisha256=%s&iCAID=16418&exclude=expired)\n\n' "$msg" "$spki" \ - || printf '\n%s\n\n: X.509: https://crt.sh/?spkisha256=%s&iCAID=16418&exclude=expired\n SPKI:\n' \ + [ "$typ" = mdwn ] && printf '\n[%s](https://crt.sh/?spkisha256=%s&exclude=expired)\n\n' "$msg" "$spki" \ + || printf '\n%s\n\n: X.509: https://crt.sh/?spkisha256=%s&exclude=expired\n SPKI:\n' \ "$(printf '%s' "$msg" | tr -d '`' )" "$spki" [ "$typ" = mdwn ] && indent=":${indent#?}" for h in sha1 sha256; do @@ -124,10 +124,10 @@ admin@fripost.org These certificates are all issued by the Let's Encrypt Certificate -Authority, and are submitted to Certificate Transparency logs. You can -view all issued Let's Encrypt certificates at crt.sh: +Authority, and are submitted to Certificate Transparency logs. You can +view all issued certificates at crt.sh: - https://crt.sh/?Identity=%25fripost.org&iCAID=16418 + https://crt.sh/?Identity=fripost.org The SPKI of our X.509 certificates are also available in PEM format at: @@ -155,8 +155,8 @@ the [signed version of this page](/certs.asc).) These certificates are all issued by the [Let's Encrypt Certificate Authority](https://letsencrypt.org), and are submitted to [Certificate Transparency logs](https://www.certificate-transparency.org). -You can view all issued Let's Encrypt certificates at -[crt.sh](https://crt.sh/?Identity=%25fripost.org&iCAID=16418). +You can view all issued certificates at +[crt.sh](https://crt.sh/?Identity=fripost.org). The SPKI of our X.509 certificates are also available in PEM format under our [Git repository]($VCS_BROWSER/tree/certs/public), from which this fingerprint list was [generated]($VCS_BROWSER/tree/certs/gencerts.sh), at diff --git a/certs/ipsec/benjamin.pem b/certs/ipsec/benjamin.pem deleted file mode 100644 index bfb094e..0000000 --- a/certs/ipsec/benjamin.pem +++ /dev/null @@ -1,14 +0,0 @@ ------BEGIN PUBLIC KEY----- -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwOODNQ5sdVXFrzAeo9bC -hbauUP69uXoc6OP/l1xB9kjzmErEnoAlVjKO05nUE6Uus03/RkEPdyaMCfKarAhb -FHaowtylUjUcIsVJkGsem4vRtuLv929vLx4TdL8BN5NCMsXOecoI5z//lfJ4YVfp -mLQ+OUM8kWNcHOPRpnLLZq/Pwvn93WbzWmxlcmVZUwq66f0N9zBSk8678TikZGx2 -dJ/HZwigswo0PSxTIbvE2eoDdFohi9RrBxpXTnsxCAXpFIV7SLobw+tQvuv+r2oK -5oGOnHIGmJZWVC3bRIb+PPELeB1g3TfNz7bP5PRKpXnP0cdK/0J2A+vQqArr8ACs -gzxsKUb7t9OASLH14fQ25FJ3nsc+CS9snXIxJourd5d2cyhMe3xBo0tzPLC8sc3m -wIyuz60o0pOjvIfzlYyldtYk3CTCVKMs1UpLnea8DDIvzhWn+TLX2yAKS/KNG0Tw -72aLc86ZUVKV0+fkwjRWtIAWSJQZL/tOl4iDyU+T9dG9dDR1KlsfW0JBGTkyZOLZ -rSBVQvDj/aUQjgc8e54MghJsS5QdAvD2rTO5liqB8YzHY77Nj2d4f5kqBHj41Kwt -GOQT4nXYI+rdOpkmkMj5kOGoeRICSv+eszXADnHHtoPS73rjej0gseibSvvm9n3i -Kkd5mm2N2oZ9Q5pF52CUFfMCAwEAAQ== ------END PUBLIC KEY----- diff --git a/certs/ipsec/levante.pem b/certs/ipsec/levante.pem new file mode 100644 index 0000000..ace22c1 --- /dev/null +++ b/certs/ipsec/levante.pem @@ -0,0 +1,14 @@ +-----BEGIN PUBLIC KEY----- +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 0eebead..d6918bc 100644 --- a/certs/ssh_known_hosts +++ b/certs/ssh_known_hosts @@ -1,7 +1,5 @@ antilop.fripost.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCmmS3Cs0ldlSEfgaL1ltfWpu2xA+1vj2pP5/zNp0aCdwqKoD/wYIa9T2kZKTzFC3J65v8E3fn/tRyDRolqhCeXWDrfBgJstLGH4ZpDMblbDjWnYmz6SY86TvE15BqWqrzDxDgcewHZlCmAxUETBgFNHSVyb1OXsfW4OmqLilbkTxY6v2QzKYzxfZTWOK2yGTO+dnT6dCN54CCItsbExLlDgqQhS/cTitL4MwpPOnMZ1cNiVyTwfDu8sFK/mDA2O+chgmplQemmuSLqnBKlcpnERcySQTetSX/bnZBvCVsDzg1tFn0Zg0PzgPCYauQMRgpk7J4jcv8P0VCK31ppuGsY4a+snvKiHUnFK7DRrJcnqSpRfwV1uL3t0khfBYiogl+zoQJ4G2yE2vKiFHVSe8LKSjgSOcnn4VwvqBNFARXMEF3Wvy72d9ZX+0kzbzp3r95vcWwqMeYDG9QEDI5lgENdhzxTcZD3Pn1hYxf862NO6UIBQW4uUhEI54QLb4bsjl/ZJ1l9KPB7bH4n58tizXlXweimzlJA+PeUzfA5BFhKjIiX9fJkVMcIFi84JmbjGMgw/B9VHewhblN+0Q8UO1PqDSlFIhE3NfWCI+1wMH2Um+zv/7M5aJYfZJvuPsvOx6D9lXOns8+kSNcdYdjkbOsgq+tdHG0eWkBuC7CRdmiKzw== antilop.fripost.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ6R2d9q2fFtu7P4Br7z141ccR8yhY+hgyi2ylNvrcgQ -benjamin.skangas.se ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEArhPJlY+UhU0CILq7EBDLFpZFIemGJsW+d2euZyyYKbZppEtLQHIhXpiW8de1MErT3bkOeS8v8L8v0ZQLvlI/uN6i4yuTDPcf2qYTnoL4P5lzNLDIyNq6YRd26FId0M1A9YJz6t9mORb/Opb3Nq033iz40T2VJ1iJPHlCAcGOyjuxfcaiIrgPWPsKShQNdLkp5k3V0EnJoraB+bgvDfBBH5Cs4cab3EMeWBeZXB2rrICRyKZkm2dXFdDGp9UgujEQazWF0uXKMVZw1A4ZeTKc6GN66Icz5ceBTnJu38pI8ogreVyyKV5WNHeJBTpKhIT6vNQSeu98y1hrF6jIXPuQkw== -benjamin.skangas.se ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN7Y77PUARUSb10sGZE4/W+ULh+0AFbzThQzBVspa7zS civett.fripost.org,git.fripost.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCmlIwAthHdsufAedoBpABqvdrRI6HK7Rl02gC/ErEmtF1TvLsO2IbC2H0jEl8l6yL6eADkmQP9N7xQvpr8EH8v6AKiU6ufo3lih0Xv/OYtyVN2TdD9zzJ6Y0PxeiBaMRM0blMnfxwcfGe6Q61YQE2sbRnfUHINbEODVw5nMBxc7349x6qvsIeleL6cgEA7WWAZvDgucxXZv5IgTBT1amWDfZIadvzz6s5C6EnrGm/XrrVo7P8yD7tT3wcMFEW65S4tx9xE54Z3UydSstiJ+ZMDv4hJsZ6LYj9hgpMDWRiIZxiq/f2AoV87D54T7nSI4txkeXVPgaS7loxPtaJOzRo0prnV3yYuBq/8HaVhAOKTOK2SYFUUNay5BduxrfrQiRIqpL3uUIBA3kyVxR2YQ+FVPDHcve294CPvtTj5IYffMxJnQhkXCFSMgHYFUt9NSKqpq/9Ti3MImUtqgTq7oubwCDeltIKmiOUF9EHTM25ukmcJDvH+r5fyuOddB4/h2D/RJJ75SvKhJnz/H/pIhtYnEDaSEa3Xv9bk6KGj4Y3s49km3lcLOHE909ov0B2m1xFDT3pAiQ2v68hHrbbM/luA/sura5+Ic0mRIA9ZfsTCU1HvBAHM3AtItbrgNAvQfbPlvbZ/6hvlDW0L2CaWNSWO/mc3lcQS5UQC44T1/zkd4w== civett.fripost.org,git.fripost.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINCKzoiQ3Ue81kQKl3t1mE2MDuS2ffVfNpNgTI0xKF5B elefant.fripost.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDQnJ9OqxH1Xe49NYUfriyHs4mz05ECMLADT0VKNGkBAG67DzRL0QyEdBaKM7tUvgBeL9NdtXgt9OUBbCd9aDE45W2Y51r6A94TQqzRtEmlneprEWMuMKigXBpx/Y7l5XyocNvPFBgFM6l3mpoQEX13dJtCtEq/EvF/GGmAjYBUsG2LGbNZdotKyjWOtoSYZRCrON0xyUrQNt/JEw9RdmftHNqvaa04Kj17WZRAg2NT98rniIMhkMMkHr8ONE69YbomP/hfmnwjUb3VHbqSNPdhSdW3+WW1sBAe2+0UMsPurQ+qEO3c/sn0BUg+y+f2If7GVv8hSQP5GEixx9q0aVJ62MJfrXarZRPQWhN5CRcP2gWrUZEG/GnLDixzBid3cP8dEOAXBslZS7wP2GCLYqE9vj/hQ6Wl1kecMsKGEYKfll3GjtzYvi2F1HkdhxhzETw/d+sVk9plVRCHI758uIkXDrcULO5QXzOUGRdytS15IihbpJil4anh9mgqfxN9DpnZ9ZPeWnWfu2qpwjxTlylayHT0d4v+t9XqYI577jy0/9yxFbALYzDEzYxrbp7oh8YQ4olrgjtWaflwSnz1kYtOrl6n5cKYbwIGLv9mGFWyBurpU5aSnyuyzmUYDYciCO0/xjEtb1Xntne+Mb4tbZT8m9AlSv39yOQ0oYZySvrg4Q== @@ -12,3 +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-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN5mdV1rI/3BUxsGracqSNhn/cywW1o7yyMewICka8+e diff --git a/group_vars/all.yml b/group_vars/all.yml index ca01f7d..f780262 100644 --- a/group_vars/all.yml +++ b/group_vars/all.yml @@ -11,7 +11,7 @@ ipsec: # Virtual (non-routable) addresses for IPsec. They all need to be # distinct and belong to the above subnet 'ipsec_subnet'. antilop: 172.16.0.1 - benjamin: 172.16.0.2 + levante: 172.16.0.2 civett: 172.16.0.3 elefant: 172.16.0.4 giraff: 172.16.0.5 @@ -45,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: @@ -64,12 +64,42 @@ dkim_keys: "guilhem.org": d: guilhem.org s: d32231afe345182ae1a9b376fa912dca + "guilhem.se": + d: guilhem.se + s: 138abf7e73c88d8dc67ca2d26881bc81 "hemdal.se": d: hemdal.se s: f032227401564da2cee5d5d0965969c4 "tevs.net": d: tevs.net s: 5fd8ba74ecb12069964e21a0ba90a516 + "jakmedlem.se": + d: jakmedlem.se + s: 0ef2a7235861d65c872faf4e72b29a29 + "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: @@ -13,8 +13,8 @@ antilop.fripost.org geoip=se [civett] civett.fripost.org geoip=se mxno=2 -[benjamin] -benjamin.skangas.se geoip=se +[levante] +levante.fripost.org geoip=se [calima] calima.fripost.org geoip=se @@ -49,10 +49,10 @@ IMAP giraff [bacula_dir:children] -benjamin +levante [bacula_sd:children] -benjamin +levante # webmail.fripost.org [webmail:children] @@ -72,20 +72,19 @@ wiki calima [munin_master:children] -benjamin +levante [backports:children] -webmail # machines behind NAT [NATed:children] -benjamin +levante # hostnames resolving to a dynamic IP [DynDNS:children] -benjamin +levante # need dhcp client [dhclient:children] -benjamin +levante 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/tasks/main.yml b/roles/MSA/tasks/main.yml index 4b38974..bf17702 100644 --- a/roles/MSA/tasks/main.yml +++ b/roles/MSA/tasks/main.yml @@ -40,6 +40,19 @@ notify: - systemctl daemon-reload +- name: Copy the SMTP TLS policy maps + template: src=etc/postfix/smtp_tls_policy.j2 + dest=/etc/postfix-{{ postfix_instance[inst].name }}/smtp_tls_policy + owner=root group=root + mode=0644 + +- name: Compile the SMTP TLS policy maps + postmap: cmd=postmap src=/etc/postfix-{{ postfix_instance[inst].name }}/smtp_tls_policy db=lmdb + owner=root group=root + mode=0644 + notify: + - Reload Postfix + - meta: flush_handlers - name: Enable Postfix sender login socketmap 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/MSA/templates/etc/postfix/smtp_tls_policy.j2 b/roles/MSA/templates/etc/postfix/smtp_tls_policy.j2 new file mode 120000 index 0000000..b40876f --- /dev/null +++ b/roles/MSA/templates/etc/postfix/smtp_tls_policy.j2 @@ -0,0 +1 @@ +../../../../out/templates/etc/postfix/smtp_tls_policy.j2
\ No newline at end of file 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 075b770..7fc44c7 100644 --- a/roles/amavis/tasks/main.yml +++ b/roles/amavis/tasks/main.yml @@ -50,14 +50,12 @@ - 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 failed_when: dkim.rc > 1 when: "'out' in group_names" - notify: - - Restart Amavis tags: - genkey - dkim diff --git a/roles/bacula-dir/files/etc/systemd/system/bacula-director.service b/roles/bacula-dir/files/etc/systemd/system/bacula-director.service.d/override.conf index 8b2f5ff..f0d36c4 100644 --- a/roles/bacula-dir/files/etc/systemd/system/bacula-director.service +++ b/roles/bacula-dir/files/etc/systemd/system/bacula-director.service.d/override.conf @@ -1,14 +1,4 @@ -[Unit] -Description=Bacula Director service -After=network.target - [Service] -Type=simple -StandardOutput=syslog -User=bacula -Group=bacula -ExecStart=/usr/sbin/bacula-dir -f -c /etc/bacula/bacula-dir.conf - # Hardening NoNewPrivileges=yes PrivateDevices=yes @@ -16,12 +6,8 @@ ProtectHome=yes ProtectSystem=strict ReadWriteDirectories=-/var/lib/bacula ReadWriteDirectories=-/var/log/bacula -RuntimeDirectory=bacula PrivateDevices=yes ProtectControlGroups=yes ProtectKernelModules=yes ProtectKernelTunables=yes RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 - -[Install] -WantedBy=multi-user.target diff --git a/roles/bacula-dir/tasks/main.yml b/roles/bacula-dir/tasks/main.yml index 2f7ab25..53d44ee 100644 --- a/roles/bacula-dir/tasks/main.yml +++ b/roles/bacula-dir/tasks/main.yml @@ -7,12 +7,12 @@ - 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 -# Create with: +# Populate with: # echo bconsole $(pwgen -sn 64 1) | sudo tee -a /etc/bacula/passwords-dir # echo $sd-sd $(pwgen -sn 64 1) | sudo tee -a /etc/bacula/passwords-dir # echo $fd-fd $(pwgen -sn 64 1) | sudo tee -a /etc/bacula/passwords-dir @@ -41,9 +41,15 @@ notify: - Restart bacula-director -- name: Copy bacula-director.service - copy: src=etc/systemd/system/bacula-director.service - dest=/etc/systemd/system/bacula-director.service +- name: Create /etc/systemd/system/bacula-director.service.d + file: path=/etc/systemd/system/bacula-director.service.d + state=directory + owner=root group=root + mode=0755 + +- name: Copy bacula-director.service override + copy: src=etc/systemd/system/bacula-director.service.d/override.conf + dest=/etc/systemd/system/bacula-director.service.d/override.conf owner=root group=root mode=0644 notify: diff --git a/roles/bacula-dir/templates/etc/bacula/bacula-dir.conf.j2 b/roles/bacula-dir/templates/etc/bacula/bacula-dir.conf.j2 index 3e37614..ab22375 100644 --- a/roles/bacula-dir/templates/etc/bacula/bacula-dir.conf.j2 +++ b/roles/bacula-dir/templates/etc/bacula/bacula-dir.conf.j2 @@ -79,7 +79,7 @@ JobDefs { Runs On Success = yes Runs On Failure = yes Runs When = after - Command = "/usr/bin/find /var/lib/bacula/tmp -type f \( -name '*.ldif' -o -name 'slapd-*' \) -delete" + Command = "/usr/bin/find /var/lib/bacula/tmp -type f \( -name \"*.ldif\" -o -name \"slapd-*\" \) -delete" } Pool = database Priority = 20 @@ -190,69 +190,71 @@ Schedule { Run = Level=Full Pool=mailboxes-full w17 mon at 02:00 Run = Level=Full Pool=mailboxes-full w30 mon at 02:00 Run = Level=Full Pool=mailboxes-full w43 mon at 02:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 01:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet w05-w16 mon-sun at 02:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet w18-w29 mon-sun at 02:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet w31-w42 mon-sun at 02:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet w44-w03 mon-sun at 02:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 03:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 04:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 05:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 06:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 07:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 08:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 09:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 10:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 11:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 12:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 13:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 14:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 15:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 16:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 17:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 18:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 19:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 20:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 21:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 22:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 23:00 - Run = Level=Incremental Pool=mailboxes-inc FullPool=mailboxes-full Messages=Quiet mon-sun at 00:00 + Run = Level=Differential Pool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet w05-w16 mon at 02:00 + Run = Level=Differential Pool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet w18-w29 mon at 02:00 + Run = Level=Differential Pool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet w31-w42 mon at 02:00 + Run = Level=Differential Pool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet w44-w03 mon at 02:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 00:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 01:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet tue-sun at 02:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 03:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 04:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 05:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 06:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 07:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 08:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 09:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 10:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 11:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 12:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 13:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 14:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 15:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 16:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 17:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 18:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 19:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 20:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 21:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 22:00 + Run = Level=Incremental Pool=mailboxes-inc DifferentialPool=mailboxes-diff FullPool=mailboxes-full Messages=Quiet mon-sun at 23:00 } # Backup Nextcloud data: full backup every 3 months, hourly incremental backup Schedule { Name = Nextcloud13WeeksCycle - Run = Level=Full Pool=nextcloud-full w04 mon at 02:00 - Run = Level=Full Pool=nextcloud-full w17 mon at 02:00 - Run = Level=Full Pool=nextcloud-full w30 mon at 02:00 - Run = Level=Full Pool=nextcloud-full w43 mon at 02:00 - Run = Level=Incremental Pool=nextcloud-inc FullPool=nextcloud-full Messages=Quiet mon-sun at 01:00 - Run = Level=Incremental Pool=nextcloud-inc FullPool=nextcloud-full Messages=Quiet w05-w16 mon-sun at 02:00 - Run = Level=Incremental Pool=nextcloud-inc FullPool=nextcloud-full Messages=Quiet w18-w29 mon-sun at 02:00 - Run = Level=Incremental Pool=nextcloud-inc FullPool=nextcloud-full Messages=Quiet w31-w42 mon-sun at 02:00 - Run = Level=Incremental Pool=nextcloud-inc FullPool=nextcloud-full Messages=Quiet w44-w03 mon-sun at 02:00 - Run = Level=Incremental Pool=nextcloud-inc FullPool=nextcloud-full Messages=Quiet mon-sun at 03:00 - Run = Level=Incremental Pool=nextcloud-inc FullPool=nextcloud-full Messages=Quiet mon-sun at 04:00 - Run = Level=Incremental Pool=nextcloud-inc FullPool=nextcloud-full Messages=Quiet mon-sun at 05:00 - Run = Level=Incremental Pool=nextcloud-inc FullPool=nextcloud-full Messages=Quiet mon-sun at 06:00 - Run = Level=Incremental Pool=nextcloud-inc FullPool=nextcloud-full Messages=Quiet mon-sun at 07:00 - Run = Level=Incremental Pool=nextcloud-inc FullPool=nextcloud-full Messages=Quiet mon-sun at 08:00 - Run = Level=Incremental Pool=nextcloud-inc FullPool=nextcloud-full Messages=Quiet mon-sun at 09:00 - Run = Level=Incremental Pool=nextcloud-inc FullPool=nextcloud-full Messages=Quiet mon-sun at 10:00 - Run = Level=Incremental Pool=nextcloud-inc FullPool=nextcloud-full Messages=Quiet mon-sun at 11:00 - Run = Level=Incremental Pool=nextcloud-inc FullPool=nextcloud-full Messages=Quiet mon-sun at 12:00 - Run = Level=Incremental Pool=nextcloud-inc FullPool=nextcloud-full Messages=Quiet mon-sun at 13:00 - Run = Level=Incremental Pool=nextcloud-inc FullPool=nextcloud-full Messages=Quiet mon-sun at 14:00 - Run = Level=Incremental Pool=nextcloud-inc FullPool=nextcloud-full Messages=Quiet mon-sun at 15:00 - Run = Level=Incremental Pool=nextcloud-inc FullPool=nextcloud-full Messages=Quiet mon-sun at 16:00 - Run = Level=Incremental Pool=nextcloud-inc FullPool=nextcloud-full Messages=Quiet mon-sun at 17:00 - Run = Level=Incremental Pool=nextcloud-inc FullPool=nextcloud-full Messages=Quiet mon-sun at 18:00 - Run = Level=Incremental Pool=nextcloud-inc FullPool=nextcloud-full Messages=Quiet mon-sun at 19:00 - Run = Level=Incremental Pool=nextcloud-inc FullPool=nextcloud-full Messages=Quiet mon-sun at 20:00 - Run = Level=Incremental Pool=nextcloud-inc FullPool=nextcloud-full Messages=Quiet mon-sun at 21:00 - Run = Level=Incremental Pool=nextcloud-inc FullPool=nextcloud-full Messages=Quiet mon-sun at 22:00 - Run = Level=Incremental Pool=nextcloud-inc FullPool=nextcloud-full Messages=Quiet mon-sun at 23:00 - Run = Level=Incremental Pool=nextcloud-inc FullPool=nextcloud-full Messages=Quiet mon-sun at 00:00 + Run = Level=Full Pool=nextcloud-full w05 mon at 02:30 + Run = Level=Full Pool=nextcloud-full w18 mon at 02:30 + Run = Level=Full Pool=nextcloud-full w31 mon at 02:30 + Run = Level=Full Pool=nextcloud-full w44 mon at 02:30 + Run = Level=Differential Pool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet w06-w17 mon at 02:30 + Run = Level=Differential Pool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet w19-w30 mon at 02:30 + Run = Level=Differential Pool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet w32-w43 mon at 02:30 + Run = Level=Differential Pool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet w45-w04 mon at 02:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 00:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 01:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet tue-sun at 02:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 03:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 04:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 05:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 06:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 07:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 08:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 09:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 10:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 11:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 12:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 13:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 14:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 15:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 16:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 17:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 18:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 19:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 20:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 21:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 22:30 + Run = Level=Incremental Pool=nextcloud-inc DifferentialPool=nextcloud-diff FullPool=nextcloud-full Messages=Quiet mon-sun at 23:30 } # This schedule does the databases. It starts after the WeeklyCycle @@ -369,6 +371,7 @@ FileSet { File = /exports File = /misc File = /media + File = /lost+found } } @@ -404,9 +407,26 @@ FileSet { FileSet { Name = Mailboxes Include { + # NOTE: debug FileSet with: + # `sudo -u bacula bconsole <<<"estimate job=mistral-mailboxes level=Full listing" | grep -F -e.{log,cache}` + # we use RegexFile here since bacula's doesn't set FNM_PATHNAME so the `*' and `?' metacharacters match `/' Options { - WildDir = /home/mail/attachments/queue Exclude = yes + + # cached mailbox data: $mail_location/mailboxes/INBOX/dbox-Mails/dovecot.index.cache + RegexFile = "^/home/mail/virtual/[^/]+/[^/]+/mail/mailboxes/([^/]+/)+dbox-Mails/dovecot\\.index\\.cache$" + # transaction log file: $mail_location/mailboxes/INBOX/dbox-Mails/dovecot.index.log + RegexFile = "^/home/mail/virtual/[^/]+/[^/]+/mail/mailboxes/([^/]+/)+dbox-Mails/dovecot\\.index\\.log(\\.[0-9])?$" + RegexFile = "^/home/mail/virtual/[^/]+/[^/]+/mail/storage/dovecot\\.map\\.index\\.log(\\.[0-9])?$" + # mailbox list index files: $mail_location/dovecot.list.index.log + RegexFile = "^/home/mail/virtual/[^/]+/[^/]+/mail/dovecot\\.list\\.index\\.log(\\.[0-9])?$" + # mailbox changelog: $mail_location/dovecot.mailbox.log + RegexFile = "^/home/mail/virtual/[^/]+/[^/]+/mail/dovecot\\.mailbox\\.log(\\.[0-9])?$" + # sieve logfile: ~/dovecot.sieve + RegexFile = "^/home/mail/virtual/[^/]+/[^/]+/dovecot\\.sieve\\.log(\\.[0-9])?$" + + # exclude queued files for SiS deduplication + Wild = "/home/mail/attachments/queue/*" } Options { signature = SHA1 @@ -416,21 +436,27 @@ FileSet { File = /home/mail/attachments File = /home/mail/spamspool } + Exclude { + File = "/home/mail/lost+found" + } } FileSet { Name = NextcloudData Include { Options { - WildFile = "/mnt/nextcloud-data/nextcloud.log" - WildFile = "/mnt/nextcloud-data/nextcloud.log.*" - WildDir = "/mnt/nextcloud-data/lost+found" - WildDir = "/mnt/nextcloud-data/*/cache" - WildDir = "/mnt/nextcloud-data/*/files_trashbin" - WildDir = "/mnt/nextcloud-data/*/files_versions" - WildDir = "/mnt/nextcloud-data/*/preview" - WildDir = "/mnt/nextcloud-data/*/uploads" Exclude = yes + RegexFile = "^/mnt/nextcloud-data/nextcloud\\.log(\\.[0-9])?$" + RegexFile = "^/mnt/nextcloud-data/updater\\.log(\\.[0-9])?$" + RegexDir = "^/mnt/nextcloud-data/[a-z0-9\\-]+/files_trashbin$" + RegexDir = "^/mnt/nextcloud-data/[a-z0-9\\-]+/files_versions$" + RegexDir = "^/mnt/nextcloud-data/[a-z0-9\\-]+/cache$" + RegexDir = "^/mnt/nextcloud-data/[a-z0-9\\-]+/uploads$" + RegexDir = "^/mnt/nextcloud-data/__groupfolders/trash$" + RegexDir = "^/mnt/nextcloud-data/__groupfolders/versions$" + RegexDir = "^/mnt/nextcloud-data/updater-[[:alnum:]]+$" + RegexDir = "^/mnt/nextcloud-data/appdata_[[:alnum:]]+/preview$" + RegexDir = "^/mnt/nextcloud-data/appdata_[[:alnum:]]+/[^/]+/cache$" } Options { signature = SHA1 @@ -438,6 +464,9 @@ FileSet { } File = /mnt/nextcloud-data } + Exclude { + File = "/mnt/nextcloud-data/lost+found" + } } @@ -508,9 +537,22 @@ Pool { Pool Type = Backup Recycle = yes AutoPrune = yes - Volume Retention = 26 weeks - Maximum Volume Bytes = 5GB - Label Format = "mailboxes-full-${NumVols:p/4/0/r}" + Volume Retention = 26 weeks # >13 weeks cycle + Maximum Volume Jobs = 1 + Label Format = "mailboxes-full-" + Maximum Volumes = 3 # >2 volumes used at the end of retention period +} + +# Mailbox pool definition (diff backup) +Pool { + Name = mailboxes-diff + Pool Type = Backup + Recycle = yes + AutoPrune = yes + Volume Retention = 15 weeks # >13 weeks cycle + Maximum Volume Jobs = 1 + Label Format = "mailboxes-diff-" + Maximum Volumes = 20 # >15 volumes used at the end of retention period } # Mailbox pool definition (inc backup) @@ -519,9 +561,10 @@ Pool { Pool Type = Backup Recycle = yes AutoPrune = yes - Volume Retention = 26 weeks - Maximum Volume Bytes = 5GB - Label Format = "mailboxes-inc-${NumVols:p/4/0/r}" + Volume Retention = 8 days # >1 week cycle + Maximum Volume Jobs = 24 # group by day + Label Format = "mailboxes-inc-" + Maximum Volumes = 10 # >8 volumes used at the end of retention period } # Nextcloud pool definition (full backup) @@ -530,9 +573,22 @@ Pool { Pool Type = Backup Recycle = yes AutoPrune = yes - Volume Retention = 26 weeks - Maximum Volume Bytes = 5GB - Label Format = "nextcloud-full-${NumVols:p/4/0/r}" + Volume Retention = 26 weeks # >13 weeks cycle + Maximum Volume Jobs = 1 + Label Format = "nextcloud-full-" + Maximum Volumes = 3 # >2 volumes used at the end of retention period +} + +# Nextcloud pool definition (diff backup) +Pool { + Name = nextcloud-diff + Pool Type = Backup + Recycle = yes + AutoPrune = yes + Volume Retention = 15 weeks # >13 weeks cycle + Maximum Volume Jobs = 1 + Label Format = "nextcloud-diff-" + Maximum Volumes = 20 # >15 volumes used at the end of retention period } # Nextcloud pool definition (inc backup) @@ -541,9 +597,10 @@ Pool { Pool Type = Backup Recycle = yes AutoPrune = yes - Volume Retention = 26 weeks - Maximum Volume Bytes = 5GB - Label Format = "nextcloud-inc-${NumVols:p/4/0/r}" + Volume Retention = 8 days # >1 week cycle + Maximum Volume Jobs = 24 # group by day + Label Format = "nextcloud-inc-" + Maximum Volumes = 10 # >8 volumes used at the end of retention period } # Database pool definition diff --git a/roles/bacula-sd/files/etc/systemd/system/bacula-sd.service b/roles/bacula-sd/files/etc/systemd/system/bacula-sd.service.d/override.conf index 61ba01d..b228078 100644 --- a/roles/bacula-sd/files/etc/systemd/system/bacula-sd.service +++ b/roles/bacula-sd/files/etc/systemd/system/bacula-sd.service.d/override.conf @@ -1,14 +1,4 @@ -[Unit] -Description=Bacula Storage Daemon service -After=network.target - [Service] -Type=simple -StandardOutput=syslog -User=bacula -Group=tape -ExecStart=/usr/sbin/bacula-sd -f -c /etc/bacula/bacula-sd.conf - # Hardening NoNewPrivileges=yes PrivateDevices=yes @@ -16,12 +6,8 @@ ProtectHome=yes ProtectSystem=strict ReadWriteDirectories=-/var/lib/bacula ReadWriteDirectories=/mnt/backup/bacula -RuntimeDirectory=bacula PrivateDevices=yes ProtectControlGroups=yes ProtectKernelModules=yes ProtectKernelTunables=yes RestrictAddressFamilies=AF_INET AF_INET6 - -[Install] -WantedBy=multi-user.target diff --git a/roles/bacula-sd/tasks/main.yml b/roles/bacula-sd/tasks/main.yml index 93958a8..f30fe7f 100644 --- a/roles/bacula-sd/tasks/main.yml +++ b/roles/bacula-sd/tasks/main.yml @@ -1,7 +1,7 @@ - name: Install bacula-sd apt: pkg=bacula-sd -# Create with: +# Populate with: # echo $director-dir $(pwgen -sn 64 1) | sudo tee -a /etc/bacula/passwords-sd - name: Ensure /etc/bacula/passwords-sd exists file: path=/etc/bacula/passwords-sd @@ -17,9 +17,15 @@ notify: - Restart bacula-sd -- name: Copy bacula-sd.service - copy: src=etc/systemd/system/bacula-sd.service - dest=/etc/systemd/system/bacula-sd.service +- name: Create /etc/systemd/system/bacula-sd.service.d + file: path=/etc/systemd/system/bacula-sd.service.d + state=directory + owner=root group=root + mode=0755 + +- name: Copy bacula-sd.service override + copy: src=etc/systemd/system/bacula-sd.service.d/override.conf + dest=/etc/systemd/system/bacula-sd.service.d/override.conf owner=root group=root mode=0644 notify: 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/files/etc/mysql/mariadb.conf.d/99-user.cnf b/roles/common-SQL/files/etc/mysql/mariadb.conf.d/99-user.cnf new file mode 100644 index 0000000..f3323f9 --- /dev/null +++ b/roles/common-SQL/files/etc/mysql/mariadb.conf.d/99-user.cnf @@ -0,0 +1,4 @@ +[mysqld] +skip-networking +innodb_file_per_table +innodb_flush_method = O_DIRECT diff --git a/roles/common-SQL/files/etc/mysql/my.cnf b/roles/common-SQL/files/etc/mysql/my.cnf deleted file mode 100644 index e1dff58..0000000 --- a/roles/common-SQL/files/etc/mysql/my.cnf +++ /dev/null @@ -1,131 +0,0 @@ -# -# The MySQL database server configuration file. -# -# You can copy this to one of: -# - "/etc/mysql/my.cnf" to set global options, -# - "~/.my.cnf" to set user-specific options. -# -# One can use all long options that the program supports. -# Run program with --help to get a list of available options and with -# --print-defaults to see which it would actually understand and use. -# -# For explanations see -# http://dev.mysql.com/doc/mysql/en/server-system-variables.html - -# This will be passed to all mysql clients -# It has been reported that passwords should be enclosed with ticks/quotes -# escpecially if they contain "#" chars... -# Remember to edit /etc/mysql/debian.cnf when changing the socket location. -[client] -port = 3306 -socket = /var/run/mysqld/mysqld.sock - -# Here is entries for some specific programs -# The following values assume you have at least 32M ram - -# This was formally known as [safe_mysqld]. Both versions are currently parsed. -[mysqld_safe] -socket = /var/run/mysqld/mysqld.sock -nice = 0 - -[mysqld] -# -# * Basic Settings -# -user = mysql -pid-file = /var/run/mysqld/mysqld.pid -socket = /var/run/mysqld/mysqld.sock -port = 3306 -basedir = /usr -datadir = /var/lib/mysql -tmpdir = /tmp -lc-messages-dir = /usr/share/mysql -character_set_server = utf8 -collation_server = utf8_unicode_ci -skip-external-locking -# -# Instead of skip-networking the default is now to listen only on -# localhost which is more compatible and is not less secure. -#bind-address = 127.0.0.1 -skip-networking -# -# * Fine Tuning -# -key_buffer_size = 16M -max_allowed_packet = 16M -thread_stack = 192K -thread_cache_size = 8 -# This replaces the startup script and checks MyISAM tables if needed -# the first time they are touched -myisam-recover = BACKUP -#max_connections = 100 -#table_cache = 64 -#thread_concurrency = 10 -# -# * Query Cache Configuration -# -query_cache_limit = 1M -query_cache_size = 16M -# -# * Logging and Replication -# -# Both location gets rotated by the cronjob. -# Be aware that this log type is a performance killer. -# As of 5.1 you can enable the log at runtime! -#general_log_file = /var/log/mysql/mysql.log -#general_log = 1 -# -# Error logging goes to syslog due to /etc/mysql/conf.d/mysqld_safe_syslog.cnf. -# -# Here you can see queries with especially long duration -#log_slow_queries = /var/log/mysql/mysql-slow.log -#long_query_time = 2 -#log-queries-not-using-indexes -# -# The following can be used as easy to replay backup logs or for replication. -# note: if you are setting up a replication slave, see README.Debian about -# other settings you may need to change. -#server-id = 1 -#log_bin = /var/log/mysql/mysql-bin.log -expire_logs_days = 10 -max_binlog_size = 100M -#binlog_do_db = include_database_name -#binlog_ignore_db = include_database_name -# -# * InnoDB -# -# InnoDB is enabled by default with a 10MB datafile in /var/lib/mysql/. -# Read the manual for more InnoDB related options. There are many! - -innodb_flush_method = O_DIRECT -innodb_file_per_table = 1 - -# * Security Features -# -# Read the manual, too, if you want chroot! -# chroot = /var/lib/mysql/ -# -# For generating SSL certificates I recommend the OpenSSL GUI "tinyca". -# -# ssl-ca=/etc/mysql/cacert.pem -# ssl-cert=/etc/mysql/server-cert.pem -# ssl-key=/etc/mysql/server-key.pem - - - -[mysqldump] -quick -quote-names -max_allowed_packet = 16M - -[mysql] -#no-auto-rehash # faster start of mysql but no tab completition - -[isamchk] -key_buffer_size = 16M - -# -# * IMPORTANT: Additional settings that can override those from this file! -# The files must end with '.cnf', otherwise they'll be ignored. -# -!includedir /etc/mysql/conf.d/ diff --git a/roles/common-SQL/tasks/main.yml b/roles/common-SQL/tasks/main.yml index cd1d091..7e59f60 100644 --- a/roles/common-SQL/tasks/main.yml +++ b/roles/common-SQL/tasks/main.yml @@ -4,13 +4,13 @@ packages: - mariadb-common - mariadb-server - - python-mysqldb + - python3-mysqldb # for the 'mysql_' munin plugin - libcache-cache-perl - name: Copy MySQL/MariaDB configuration - copy: src=etc/mysql/my.cnf - dest=/etc/mysql/my.cnf + copy: src=etc/mysql/mariadb.conf.d/99-user.cnf + dest=/etc/mysql/mariadb.conf.d/99-user.cnf owner=root group=root mode=0644 register: r @@ -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-web/files/etc/nginx/snippets/ssl.conf b/roles/common-web/files/etc/nginx/snippets/ssl.conf index 57a317b..0284b0a 100644 --- a/roles/common-web/files/etc/nginx/snippets/ssl.conf +++ b/roles/common-web/files/etc/nginx/snippets/ssl.conf @@ -1,9 +1,6 @@ # https://wiki.mozilla.org/Security/Server_Side_TLS # https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=nginx-1.14.2&openssl=1.1.1c&hsts=yes&profile=intermediate -# certs sent to the client in SERVER HELLO are concatenated in ssl_certificate -# ~$ cat /etc/nginx/ssl/srvcert.pem /usr/share/lacme/lets-encrypt-x3-cross-signed.pem | sudo tee /etc/nginx/ssl/srvcert.chained.pem - ssl on; ssl_session_timeout 1d; @@ -26,4 +23,4 @@ ssl_stapling on; ssl_stapling_verify on; # verify chain of trust of OCSP response using Root CA and Intermediate certs -ssl_trusted_certificate /usr/share/lacme/lets-encrypt-x3-cross-signed.pem; +ssl_trusted_certificate /usr/share/lacme/ca-certificates.crt; 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 e64ec44..3a4cb36 100644 --- a/roles/common/files/etc/logcheck/ignore.d.server/common-local +++ b/roles/common/files/etc/logcheck/ignore.d.server/common-local @@ -1,43 +1,66 @@ # Ansible Managed # Do NOT edit this file directly! # -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: subsystem request for sftp by user [-_.[:alnum:]]+$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: User [-_.[:alnum:]]+ not allowed because account is locked$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: fatal: Read from socket failed: (Connection reset by peer|Connection timed out) \[preauth\]$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: (error: )?Received disconnect from [:.[:xdigit:]]+: (3|11|14): .* \[preauth\]$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Disconnecting: Change of username or service not allowed: \(\S+\) -> (\(\S+\) )?\[preauth\]$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Disconnecting: Too many authentication failures for invalid user [-_.[:alnum:]]+ from [:.[:xdigit:]]+ port [[:digit:]]+ ssh2? \[preauth\]$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: (error: )?Received disconnect from [:.[:xdigit:]]+ port [0-9]+:(3|11|14): .* \[preauth\]$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: (Disconnected from|Connection (closed|reset) by) [[:xdigit:].:]{3,39} port [0-9]+ \[preauth\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: error: maximum authentication attempts exceeded for invalid user .* from [:.[:xdigit:]]+ port [0-9]+ ssh2 \[preauth\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: (Disconnected from|Connection (closed|reset) by)( invalid user .*)? [[:xdigit:].:]{3,39} port [0-9]+( \[preauth\])?$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: (Did not receive identification string|Invalid user .*) from [[:xdigit:].:]{3,39} port [0-9]+$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Invalid user .* from [:.[:xdigit:]]+$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: input_userauth_request: invalid user .* \[preauth\]$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: userauth_pubkey: unsupported public key algorithm: [[:alnum:]-]+ \[preauth\]$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: fatal: Write failed: (Connection (timed out|reset by peer)|Broken pipe) \[preauth\]$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: fatal: (no hostkey alg|Unable to negotiate a key exchange method) \[preauth\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: (Disconnected from|Connection closed by) (invalid|authenticating) user .* \[preauth\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Disconnecting (authenticating|invalid) user .* [[:xdigit:].:]{3,39} port [0-9]+: (Change of username or service not allowed: .* -> .*|Too many authentication failures) \[preauth\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: ssh_dispatch_run_fatal: Connection from (invalid user .* )?[[:xdigit:].:]{3,39} port [0-9]+: (message authentication code incorrect|Connection corrupted|Broken pipe) \[preauth\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Disconnected from user [a-z0-9]+ [[:xdigit:].:]{3,39} port [0-9]+$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Unable to negotiate with [:.[:xdigit:]]+ port [[:digit:]]+: no matching (host key type|key exchange method|cipher) found\. Their offer: [@.[:alnum:],-]+ \[preauth\]$ no matching cipher found: client [.@[:alnum:]-]+(,[.@[:alnum:]-]+)* server [.@[:alnum:]-]+(,[.@[:alnum:]-]+)* \[preauth\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Bad packet length [0-9]+\. \[preauth\]$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Bad protocol version identification '.*' from [:.[:xdigit:]]+ port [[:digit:]]+$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Accepted publickey for [^[:space:]]+ from [^[:space:]]+ port [[:digit:]]+( (ssh|ssh2))?(: (DSA|RSA|ECDSA|ED25519) ([[:xdigit:]]{2}:){15}[[:xdigit:]]{2})?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: WARNING: no suitable primes in /etc/ssh/primes$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: dispatch_protocol_error: type [0-9]+ seq [0-9]+ \[preauth\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: error: Bad remote protocol version identification: '.*'$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Corrupted MAC on input\. \[preauth\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Protocol major versions differ for [[:xdigit:].:]{3,39} port [0-9]+: .+ vs\. .+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: 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$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: (Created|Removed) slice User Slice of [-[:alnum:]]+\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: (Created|Removed) slice User Slice of UID [-[:alnum:]]+\.$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[[0-9]+\]: (Listening on|Closed) .*\.$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: Start(ing|ed) Cleanup of Temporary Directories\.(\.\.)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: Starting (Cleanup of Temporary Directories|Daily man-db regeneration)\.\.\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: Started (Cleanup of Temporary Directories|Daily man-db regeneration)\.$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: Start(ing|ed) Session [0-9]+ of user [-[:alnum:]]+\.$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[[0-9]+\]: Startup finished in \S+\.$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd: pam_unix\(systemd-user:session\): session (opened|closed) for user [-[:alnum:]]+( by \(uid=0\))?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[[0-9]+\]: [-[:alnum:]\\_@]+\.(mount|scope|service|socket): Succeeded\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd(-[a-z]+)?\[[0-9]+\]: \[/[^]]+:[0-9]+\] Line references path below legacy directory /var/run/, updating /var/run/ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: /lib/systemd/system/[-[:alnum:]\\_@]+\.service:[0-9]+: PIDFile= references path below legacy directory /var/run/, updating /var/run/ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ runuser: pam_unix\(runuser:session\): session (opened|closed) for user [-[:alnum:]]+( by \(uid=0\))?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ CRON\[[0-9]+\]: pam_unix\(cron:session\): session (opened|closed) for user _?[-[:alnum:]]+(\(uid=[0-9]+\))?( by \(uid=0\))?$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: Start(ing|ed) Session [0-9]+ of user [-[:alnum:]]+\.$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[[0-9]+\]: Received SIGRTMIN\+24 from PID [0-9]+ \(kill\)\.$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd-logind\[[0-9]+\]: New session c?[0-9]+ of user [-[:alnum:]]+\.$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd-logind\[[0-9]+\]: Removed session c?[0-9]+\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd-logind\[[0-9]+\]: Session [0-9]+ logged out\. Waiting for processes to exit\.$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: apt-daily(-upgrade)?\.timer: Adding .* random time\.$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sudo:[[:space:]]+[_[:alnum:].-]+ : TTY=(unknown|(pts/|tty|vc/)[[:digit:]]+) ; PWD=[^;]+ ; USER=[._[:alnum:]-]+ (; ENV=([_a-zA-Z]+=\S* )+)?; COMMAND=(/(usr|etc|bin|sbin)/|sudoedit ) -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> (bytecode|main|daily)\.(cld|cvd) (is up to date|updated) \(version: [[:digit:]]+, sigs: [[:digit:]]+, f-level: [[:digit:]]+, builder: [._[:alnum:]-]+\)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: Starting Daily apt-listbugs preferences cleanup\.\.\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: Finished (Daily apt-listbugs preferences cleanup|Cleanup of Temporary Directories|Autocommit of changes in /etc directory|Clean php session files|Launch apticron to notify of packages pending an update|Online ext4 Metadata Check for All Filesystems|Autocommit of changes in /etc directory)\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: [[:alnum:]@-]+\.(service|scope): Consumed ([0-9]+min )?[0-9.]+s CPU time\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: rsyslog\.service: Sent signal SIGHUP to main process [0-9]+ \(rsyslogd\) on client request\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sudo:[[:space:]]+[_[:alnum:].-]+ : (TTY=(unknown|(pts/|tty|vc/)[[:digit:]]+) ; )?PWD=[^;]+ ; USER=[._[:alnum:]-]+ (; ENV=([_a-zA-Z]+=\S* )+)?; COMMAND=(/(usr|etc|bin|sbin)/|sudoedit ) +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> daily database available for update \(local version: [[:digit:]]+, remote version: [[:digit:]]+\)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> (bytecode|main|daily)\.(cld|cvd) (database )?(is up to date|is up-to-date|updated) \(version: [[:digit:]]+, sigs: [[:digit:]]+, f-level: [[:digit:]]+, builder: [._[:alnum:]-]+\)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Testing database: '/var/lib/clamav/tmp[^/]*/clamav-.*' \.\.\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Database test passed\.$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Received signal: wake up$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> ClamAV update process started at \w{3} \w{3} [ :[:digit:]]{16}$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: (\w{3} \w{3} [ :[:digit:]]{16} -> \^|WARNING: )Your ClamAV installation is OUTDATED!$ @@ -45,26 +68,71 @@ no matching cipher found: client [.@[:alnum:]-]+(,[.@[:alnum:]-]+)* server [.@[: ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: WARNING: getfile: [._[:alnum:]-]+ not found on remote server \(IP: [.[:digit:]]+\)$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: WARNING: Incremental update failed, trying to download daily\.cvd$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: (WARNING|ERROR): (getpatch: )?Can't download [._[:alnum:]-]+ from [.[:alnum:]-]+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> \*Can't query [._[:alnum:]-]+$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Downloading [._[:alnum:]-]+ \[[[:digit:]]+%\]$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> DON'T PANIC! Read https?://www\.clamav\.net/(support/faq|documents/upgrading-clamav)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> DON'T PANIC! Read https://docs\.clamav\.net/manual/Installing\.html$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[0-9]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Database updated \([0-9]+ signatures\) from .* \(IP: [[:xdigit:].:]{3,39}\)$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[0-9]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Clamd successfully notified about the update\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Received signal: re-opening log file$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ clamd\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Reading databases from /var/lib/clamav$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ clamd\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> SelfCheck: Database status OK\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ clamd\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> SelfCheck: (Database status OK|Database modification detected\. Forcing reload)\.$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ clamd\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Database correctly reloaded \([0-9]+ signatures\)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ clamd\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> SIGHUP caught: re-opening log file\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ clamd\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Activating the newly loaded database\.\.\.$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ kernel: \[ *[[:digit:]]+\.[[:digit:]]+ *\] Peer [.[:digit:]]+:[[:digit:]]+/[[:digit:]]+ unexpectedly shrunk window [[:digit:]]+:[[:digit:]]+ \(repaired\)$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ liblogging-stdlog: \[origin software="rsyslogd" swVersion="[0-9.]+" x-pid="[0-9]+" x-info="http://www\.rsyslog\.com"\] rsyslogd was HUPed$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ ansible-([_a-z0-9]+|<stdin>): Invoked with +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ rsyslogd: \[origin software="rsyslogd" swVersion="[0-9.]+" x-pid="[0-9]+" x-info="https://www\.rsyslog\.com"\] rsyslogd was HUPed$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ smartd\[[0-9]+\]: Device: /dev/sd[a-z] \[SAT\], CHECK POWER STATUS spins up disk \(0x[0-9a-f]{2} -> 0xff\)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ ansible-([_a-z0-9.]+|<stdin>): Invoked with +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ python3(\.[0-9]+)?\[[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]+\]: info Sympa::Request::Handler:: -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: notice Sympa::Bulk::store\(\) +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: notice Sympa::(Bulk|Spool)::store\(\) +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: info Sympa::Spool::_create\(\) Creating directory /var/spool/sympa/auth ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: (info|notice) Sympa::Spindle::Process(Incoming|Message|Template|Digest):: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: info Sympa::Spindle::Do(Command|Message):: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: info Sympa::Request::Handler::(subscribe|confirm|reject|signoff|distribute)::_twist\(\) +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: (info|notice) Sympa::Spindle::To(List|Moderation|Auth|Held):: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: notice Sympa::Spindle::AuthorizeMessage::_twist\(\) Message Sympa::Message .* rejected\(\) because sender not allowed$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: err main::#[0-9]+ > Sympa::Spindle::spin#[0-9]+ > ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ task_manager\[[0-9]+\]: (info|notice) main:: -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: info main::do_ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[[:digit:]]+\]: notice main:: \([.[:alnum:]-]+\) \[robot [.[:alnum:]-]+\] \[client [[:xdigit:].:]{3,39}\] Does NOT match HTTP_HOST; setting cookie_domain to [.[:alnum:]-]+$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[[:digit:]]+\]: notice Sympa::(Spindle::ProcessTemplate::_twist|Bulk::store)\(\) -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ bulk\[[[:digit:]]+\]: notice Sympa::(Spindle::ProcessOutgoing::_twist|Mailer::store)\(\) +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ task_manager\[[0-9]+\]: (info|notice) Sympa::(Spindle::ProcessTask|Spool):: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: info main:: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: info Sympa::Ticket::load\(\) Ticket: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: notice main:: Redirecting to\s +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: notice main::do_login\(\) Authentication failed$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: err main::#[0-9]+ > main::do_login#[0-9]+ > Sympa::WWW::Auth::check_auth#[0-9]+ > Sympa::WWW::Auth::authentication#[0-9]+ Incorrect password for user\s +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: notice Sympa::WWW::Tools::_get_css_url\(\) Template file /usr/share/sympa/default/web_tt2/css\.tt2 or configuration has changed; updating CSS file /var/lib/sympa/css/[.[:alnum:]-]+/style\.css$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: info Sympa::WWW::Session::new\(\) Ignoring unknown session cookie +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: err main::#[0-9]+ > main::get_parameters#[0-9]+ \[robot [.[:alnum:]-]+\] \[client [[:xdigit:].:]{3,39}\] Syntax error for parameter action value "(lists|search_list_request)#[^"]+" not conform to regexp: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: err main::#[0-9]+ > main::check_action_parameters#[0-9]+ \[robot [.[:alnum:]-]+\] \[session [[:xdigit:]]+\] \[client [[:xdigit:].:]{3,39}\] \[list [.[:alnum:]-]+\] User not logged in$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: err main::#[0-9]+ > main::do_arc#[0-9]+ \[robot [.[:alnum:]-]+\] \[session [[:xdigit:]]+\] \[client [[:xdigit:].:]{3,39}\] \[list [.[:alnum:]-]+\] Empty archive Sympa::Archive < +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: notice Sympa::Spindle::Process(Request|Template)::_twist\(\) Processing Sympa:: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: info Sympa::Spindle::ToAuth:: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: notice Sympa::Bulk::store\(\) Message Sympa::Message::Template < +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (wwsympa|sympa_msg)\[[0-9]+\]: notice Sympa::Spool::Outgoing::store\(\) Message Sympa::Message::Template < +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: notice Sympa::Spool::store\(\) Sympa::Request < +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: info Sympa::Request::Handler::(add|signoff|subscribe)::_twist\(\) +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: info Sympa::Scenario::authz\(\) Sympa::Scenario <create_list\.[.[:alnum:]-]+;ERROR>: No rule match, reject$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: err main::#[0-9]+ > main::check_param_in#[0-9]+ > Sympa::Scenario::new#[0-9]+ Unable to find scenario file " +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: notice Sympa::Spool::Outgoing::store\(\) Message Sympa::Message <[^>]+> is stored into bulk spool as <[^>]+>$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ mysqld\[[0-9]+\]: [0-9: -]{19} [0-9]+ \[Warning\] Aborted connection [0-9]+ to db: '[^']+' user: '[^']+' host: 'localhost' \(Got (timeout|an error) reading communication packets\)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ bulk\[[0-9]+\]: notice main:: Bulk exited normally due to signal$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ bulk\[[0-9]+\]: notice Sympa::Mailer::store\(\) +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ bulk\[[0-9]+\]: (info|notice) Sympa::Spindle::ProcessOutgoing:: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ bounced\[[0-9]+\]: notice Sympa::Tracking::store\(\) Sympa::Message < +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ bounced\[[0-9]+\]: notice Sympa::Spindle::ProcessBounce::_twist\(\) +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ bounced\[[0-9]+\]: info Sympa::Spindle::ProcessBounce::_twist\(\) No address found in message Sympa::Message < +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ archived\[[0-9]+\]: notice Sympa::Spindle::ProcessArchive:: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ archived\[[0-9]+\]: (info|notice) Sympa::Archive:: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ ikiwiki\[[[:digit:]]+\]: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ ikiwiki: \[Fripost wiki\] (invalid page|unknown do) parameter$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ unbound: \[[0-9]+:[0-9]+\] info: generate keytag query _ta-[[:xdigit:]]+\. NULL IN$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ rrdcached\[[[:digit:]]+\]: (flushing old values|rotating journals|started new journal /\S+$|removing old journal /\S+$) ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ rrdcached\[[[:digit:]]+\]: queue_thread_main: rrd_update_r \(([^)]+)\) failed with status -1. \(opening '\1': No such file or directory\) ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ auditd\[[[:digit:]]+\]: Audit daemon rotating log files$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ stunnel(:|4\[[[:digit:]]+\]: [0-9]{4}\.[0-9]{2}\.[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}) LOG3\[[[:digit:]]+\]: SSL_accept: (Peer suddenly disconnected|[[:xdigit:]]+: error:[[:xdigit:]]+:SSL routines:SSL2?3_GET_CLIENT_HELLO:(unknown protocol|http request|no shared cipher))$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dhclient\[[[:digit:]]+\]: DHCPREQUEST for [[:digit:].]{3,15} on [[:alnum:]]+ to [[:digit:].]{3,15} port 67$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ bacula-sd\[[[:digit:]]+\]: [._[:alnum:]-]+: askdir\.c:[0-9]+-[0-9]+ Discard: JobMedia Vol=[._[:alnum:]-]+ wrote=[0-9]+ MediaId=[0-9]+ FI=[0-9]+ LI=[0-9]+ StartAddr=[0-9]+ EndAddr=[0-9]+$ +### +^\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 66c8101..532a2a0 100644 --- a/roles/common/files/etc/logcheck/ignore.d.server/dovecot-local +++ b/roles/common/files/etc/logcheck/ignore.d.server/dovecot-local @@ -1,17 +1,23 @@ # Ansible Managed # Do NOT edit this file directly! # -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: imap\([-_.@[:alnum:]]+\): (Logged out|Disconnected for inactivity) in=[[:digit:]]+ out=[[:digit:]]+$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: imap\([-_.@[:alnum:]]+\): Connection closed( \(IDLE running for .*\))? in=[[:digit:]]+ out=[[:digit:]]+$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: imap-hibernate\([-_.@[:alnum:]]+\): Connection closed in=[[:digit:]]+ out=[[:digit:]]+$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (pop3|imap|managesieve)-login: Login: user=<[^>]*>, method=[[:alnum:]-]+, rip=[.:[:xdigit:]]+, lip=[.:[:xdigit:]]+, mpid=[0-9]+, (TLS|secured), session=<[^>]+>$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (pop3|imap)-login: (Aborted login|Disconnected) \(auth failed, [[:digit:]]+ attempts in [[:digit:]]+ secs\): user=<[^>]*>, method=[[:alnum:]-]+, rip=[.:[:xdigit:]]+, lip=[.:[:xdigit:]]+, (TLS(: Disconnected)?|secured), session=<[^>]+>$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (pop3|imap)-login: (Aborted login|Disconnected(: Inactivity)?) \(no auth attempts in [[:digit:]]+ secs\): user=<>, rip=[.:[:xdigit:]]+, lip=[.:[:xdigit:]]+, TLS( handshaking|: Disconnected)?(: SSL_(accept|read)\(\) syscall failed: (Connection reset by peer|Success))?, session=<[^>]+>$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (pop3|imap)-login: Disconnected(: Inactivity during authentication)? \(client didn't finish SASL auth, waited [[:digit:]]+ secs\): user=<>, method=[[:alnum:]-]+, rip=[.:[:xdigit:]]+, lip=[.:[:xdigit:]]+, TLS(: SSL_read\(\) syscall failed: Connection reset by peer)?, session=<[^>]+>$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: lmtp\([-_.@[:alnum:]]+\): [+/[:alnum:]]{22}: msgid=((\? )?<[^>]*>|unspecified): saved mail to\s -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: lmtp\([-_.@[:alnum:]]+\): [+/[:alnum:]]{22}(:[0-9]+)?: sieve: msgid=((\? )?<[^>]*>|unspecified): (stored mail into mailbox '|(forwarded|discarded duplicate forward) to <[^[:space:]]+>$|marked message to be discarded if not explicitly delivered \(discard action\)$) -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: lmtp\([^@]+@[^@]+\): [+/[:alnum:]]{22}:[0-9]+: sieve: Execution of script \S+ failed, but implicit keep was successful \(user logfile \S+ may reveal additional details\)$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (pop3|imap|managesieve)-login: Maximum number of connections from user\+IP exceeded \(mail_max_userip_connections=[[:digit:]]+\): user=<[^>]*>, method=[[:alnum:]-]+, rip=[.:[:xdigit:]]+, lip=[.:[:xdigit:]]+(, TLS, session=<[^>]+>)?$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: lmtp\([-_.@[:alnum:]]+\): Connect from local$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: lmtp\([0-9]+\): Disconnect from local: Successful quit$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: imap\([-_.@[:alnum:]]+\)<[0-9]+><[+/[:alnum:]]+>: Connection closed(: read\(size=[0-9]+\) failed: Connection reset by peer)? \((((UID )?[[:alpha:]\-]* finished [0-9.]+ secs ago|IDLE running for [^\)]+, state=wait-input|No commands sent)\))?( in=[0-9]+ out=[0-9]+ deleted=[0-9]+ expunged=[0-9]+ trashed=[0-9]+ hdr_count=[0-9]+ hdr_bytes=[0-9]+ body_count=[0-9]+ body_bytes=[0-9]+)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: imap\(.+\)<[0-9]+><[+/[:alnum:]]+>(: Disconnected)?(: Logged out| for inactivity( in reading our output)?|: Disconnected in [[:upper:]]+ \([0-9]+ msgs, [0-9]+ secs, [0-9]+/[0-9]+ bytes\)|: Too many invalid IMAP commands\.)?( in=[0-9]+ out=[0-9]+ deleted=[0-9]+ expunged=[0-9]+ trashed=[0-9]+ hdr_count=[0-9]+ hdr_bytes=[0-9]+ body_count=[0-9]+ body_bytes=[0-9]+)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: imap: Logged out in=[0-9]+ out=[0-9]+ deleted=0 expunged=0 trashed=0 hdr_count=0 hdr_bytes=0 body_count=0 body_bytes=0$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: imap\([-_.@[:alnum:]]+\)<[0-9]+><[+/[:alnum:]]+>: Connection closed(: (read\(size=[0-9]+\) failed: )?Connection reset by peer)?( \((LOGOUT,)?(UID )?[[:alpha:]\-]+ (running for|finished) [^\)]+\))? in=[0-9]+ out=[0-9]+ deleted=[0-9]+ expunged=[0-9]+ trashed=[0-9]+ hdr_count=[0-9]+ hdr_bytes=[0-9]+ body_count=[0-9]+ body_bytes=[0-9]+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: imap-hibernate\([-_.@[:alnum:]]+\)<[0-9]+><[+/[:alnum:]]+>: Connection closed in=[0-9]+ out=[0-9]+ deleted=[0-9]+ expunged=[0-9]+ trashed=[0-9]+ hdr_count=[0-9]+ hdr_bytes=[0-9]+ body_count=[0-9]+ body_bytes=[0-9]+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (pop3|imap|managesieve)-login: Login: user=<[^>]*>, method=[[:alnum:]-]+, rip=[[:xdigit:].:]{3,39}, lip=[[:xdigit:].:]{3,39}, mpid=[0-9]+, (TLS|secured)(: (read\(size=[0-9]+\) failed: )?Connection (closed|reset by peer))?, session=<[^>]+>$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: managesieve\([-_.@[:alnum:]]+\)<[0-9]+><[+/[:alnum:]]+>: Disconnected: Logged out bytes=[[:digit:]]+/[[:digit:]]+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (imap|managesieve)-login: (Disconnected(: Inactivity)?|Aborted login) \(auth failed, [[:digit:]]+ attempts in [[:digit:]]+ secs\): user=<[^>]*>, method=[A-Z\-]+, rip=[[:xdigit:].:]{3,39}, lip=[[:xdigit:].:]{3,39}, (TLS|SSL|secured)[:,] +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (imap|managesieve)-login: Disconnected \((no auth attempts in|disconnected before auth was ready, waited) [[:digit:]]+ secs\):( user=<>,)? rip=[[:xdigit:].:]{3,39}, lip=[[:xdigit:].:]{3,39}, (TLS|SSL)( handshaking)?: (SSL_accept\(\)( syscall)? failed:|(read\(size=[0-9]+\) failed: )?Connection (closed|reset by peer), session=<[+/[:alnum:]]+>$|SSL_read failed: error:[[:xdigit:]]+:SSL routines:(ssl3_get_record:decryption failed or bad record mac|ssl3_read_bytes:unexpected record), session=<[+/[:alnum:]]+>$) +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (imap|managesieve)-login: (Disconnected(: (Inactivity|Too many invalid commands\.?))?|Aborted login) \(no auth attempts in [[:digit:]]+ secs\):( user=<>,)? rip=[[:xdigit:].:]{3,39}, lip=[[:xdigit:].:]{3,39}(, (TLS|SSL)( handshaking)?)?, session=<[+/[:alnum:]]+>$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (pop3|imap)-login: Disconnected(: Inactivity during authentication)? \(client didn't finish SASL auth, waited [[:digit:]]+ secs\): user=<>, method=[[:alnum:]-]+, rip=[[:xdigit:].:]{3,39}, lip=[[:xdigit:].:]{3,39}, TLS(: (read\(size=[0-9]+\) failed: Connection reset by peer|Disconnected|Connection closed))?, session=<[^>]+>$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: lmtp\([-_.@[:alnum:]]+\)<[0-9]+><[+/[:alnum:]]{22}(:[0-9]+)?>: msgid=(\? )?(<[^>]*>|[^[:blank:]]*|[^,()]+@[.[:alnum:]-]+)( \(added by \S+@[.[:alnum:]-]+\))?: saved mail to\s +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: lmtp\([-_.@[:alnum:]]+\)<[0-9]+><[+/[:alnum:]]{22}(:[0-9]+)?>: sieve: msgid=(\? )?(<[^>]*>\s*|[^[:blank:]]*|[^,()]+@[.[:alnum:]-]+)( \(added by \S+@[.[:alnum:]-]+\)| [[: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:]]+\)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: auth: Warning: auth client [0-9]+ disconnected with [0-9]+ pending requests: (Connection reset by peer|EOF)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: stats: Warning: UPDATE-CMD: Already expired$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: Start(ing|ed) Dovecot authentication proxy\.(\.\.)?$ diff --git a/roles/common/files/etc/logcheck/ignore.d.server/postfix-local b/roles/common/files/etc/logcheck/ignore.d.server/postfix-local index f539c3a..dcc1198 100644 --- a/roles/common/files/etc/logcheck/ignore.d.server/postfix-local +++ b/roles/common/files/etc/logcheck/ignore.d.server/postfix-local @@ -13,37 +13,43 @@ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/scache\[[[:digit:]]+\]: statistics: (domain|address) lookup hits=[[:digit:]]+ miss=[[:digit:]]+ success=[[:digit:]]+%$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/scache\[[[:digit:]]+\]: statistics: max simultaneous domains=[[:digit:]]+ addresses=[[:digit:]]+ connection=[[:digit:]]+$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/smtpd\[[[:digit:]]+\]: [[:xdigit:]]+: client=[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/cleanup\[[[:digit:]]+\]: [[:xdigit:]]+: (resent-)?message-id=([^[:blank:]]*|(mid:)?[[:alnum:]_/+.$@-]+)( \(added by [^[:space:]]+\))?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/cleanup\[[[:digit:]]+\]: [[:xdigit:]]+: (resent-)?message-id=([^[:blank:]]*|(mid:)?[[:alnum:]_/+.$@-]+|[^,()]+@[.[:alnum:]-]+)( \(added by [^[:space:]]+\))?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/cleanup\[[[:digit:]]+\]: warning: unix_trigger_event: read timeout for service public/qmgr$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/cleanup\[[[:digit:]]+\]: warning: milter unix:public/opendmarc: can't read SMFIC_BODYEOB reply packet header: Success$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/qmgr\[[[:digit:]]+\]: [[:xdigit:]]+: from=<[^>]*>, size=[[:digit:]]+, nrcpt=[[:digit:]]+ \(queue active\)$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/n?qmgr\[[[:digit:]]+\]: [[:xdigit:]]+: from=<[^>]*>, status=expired, returned to sender$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/n?qmgr\[[[:digit:]]+\]: [[:xdigit:]]+: message-id=(<[^>]*>|[[:alnum:]_/+.$@-]+)( \(added by [^[:space:]]+\))? ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/n?qmgr\[[[:digit:]]+\]: [[:xdigit:]]+: removed$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/n?qmgr\[[[:digit:]]+\]: [[:xdigit:]]+: skipped, still being delivered$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/verify\[[[:digit:]]+\]: cache [a-z]+:\S+ (partial|full) cleanup: retained=[[:digit:]]+ dropped=[[:digit:]]+ entries$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/smtpd\[[[:digit:]]+\]: disconnect from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]( (ehlo|helo|xforward|starttls|auth|mail|rcpt|data|noop|rset|quit|commands|unknown)=[0-9]+(/[0-9]+)?)+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/smtpd\[[[:digit:]]+\]: disconnect from [._[:alnum:]-]+\[([[:xdigit:].:]{3,39}|unknown)\]( (ehlo|helo|xforward|starttls|auth|mail|rcpt|data|bdat|noop|rset|quit|commands|unknown)=[0-9]+(/[0-9]+)?)+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: warning: non-SMTP command from [-._[:alnum:]]+\[[[:xdigit:].:]{3,39}\]:\s ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/pickup\[[[:digit:]]+\]: [[:xdigit:]]+: uid=[[:digit:]]+ from=<[^>]*>$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/cleanup\[[[:digit:]]+\]: [[:xdigit:]]+: replace: header\s ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: [[:xdigit:]]+: client=[^[:space:]]+, sasl_method=[-[:alnum:]]+, sasl_username=[-_.@[:alnum:]]+(, sasl_sender=[-_.@[:alnum:]]+)?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: warning: [-._[:alnum:]]+\[[[:xdigit:].:]{3,39}\]: SASL (PLAIN|LOGIN) authentication (failed|aborted)(:[ [:alnum:]]*)?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: improper command pipelining after (EHLO|HELO|MAIL|QUIT) from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: warning: [-._[:alnum:]]+\[[[:xdigit:].:]{3,39}\]: SASL [[:alpha:]]+ authentication (failed|aborted)(:|$) +^\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;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^>]+>)?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 5[[:digit:]]{2} 5(\.[[:digit:]]){2} Service unavailable; (Unverified Client host|Sender address) \[\S+\] blocked using [._[:alnum:]-]+; https?://[^[:blank:];]+; from=<[^>]*> to=<[^>]+> proto=E?SMTP( helo=<[^>]+>)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 5[[:digit:]]{2} 5(\.[[:digit:]]+){2} <[^>]+>: Helo command rejected: need fully-qualified hostname;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^>]+>)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 4[[:digit:]]{2} 4(\.[[:digit:]]+){2} <[^>]+>: Sender address rejected: (Domain not found|Malformed DNS server reply);( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^>]+>)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 5[[:digit:]]{2} 5(\.[[:digit:]]+){2} <[^>]+>: Sender address rejected: Domain [.[:alnum:]-]+ does not accept mail \(nullMX\);( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^>]+>)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 5[[:digit:]]{2} 5(\.[[:digit:]]+){2} Service unavailable; (Unverified Client host|Sender address) \[\S+\] blocked using [._[:alnum:]-]+(; 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)$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: [[:upper:]]+ from [^[:space:]]+: 450( 4\.1\.2)? <[^>]*>: Recipient address rejected: Domain not found;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: [[:upper:]]+ from [^[:space:]]+: 450( 4\.1\.8)? <[^>]*>: Sender address rejected: Domain not found;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: [[:upper:]]+ from [^[:space:]]+: 554( 5\.7\.1)? <>: Sender address rejected: Null sender not allowed; from=<> to=<[^>]+> proto=E?SMTP( helo=<[^[:space:]]+>)?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: [[:upper:]]+ from [^[:space:]]+: 5[[:digit:]]{2} 5(\.[[:digit:]]){2} <[^>]*>: (Recipient|Sender) address rejected: need fully-qualified address;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: [[:upper:]]+ from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 550( 5\.7\.23)? <[^>]+>: Sender address rejected: Message rejected due to: (domain owner discourages use of this host|SPF fail - not authorized)\. Please see https?://www\.openspf\.net/Why\?\S+; from=<[^>]+> to=<[^>]+> proto=E?SMTP( helo=<[^[:space:]]+>)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ policyd-spf\[[[:digit:]]+\]: 550( 5\.7\.23)? Message rejected due to: (domain owner discourages use of this host|SPF fail - not authorized)\. Please see https?://www\.openspf\.net/Why\?\S+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: [[:upper:]]+ from [^[:space:]]+: 5[[:digit:]]{2} 5(\.[[:digit:]]+){2} <[^>]*>: (Recipient|Sender) address rejected: need fully-qualified address;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 554 5\.7\.1 <[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]>: Client host rejected: Access denied;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mda/lmtp\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^>]+>,( orig_to=<[^>]+>,)? relay=[._[:alnum:]-]+\[private/dovecot-lmtpd\],( conn_use=[[:digit:]]+,)? delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=2(\.[[:digit:]]+){2})?, status=sent \(2[[:digit:]][[:digit:]] .+\)$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-\w+/(error|n?qmgr|smtp)\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^>]+>,( orig_to=<[^>]+>,)? relay=(none|[^[:space:]]+\[[[:xdigit:].:]{3,39}\]:[[:digit:]]+),( conn_use=[[:digit:]]+,)? delay=[[:digit:].]+,( delays=[[:digit:]./]+,)?( dsn=[45]\.[[:digit:]]\.[[:digit:]],)? status=(deferred|undeliverable|bounced) \((delivery temporarily suspended: )?((lost connection with [^[:space:]]+|conversation with [^[:space:]]+ timed out) while (sending [[:alnum:]]+( [[:alnum:]]+)?|performing the (HELO|EHLO) handshake|receiving the initial server greeting|sending [[:alnum:]]+( [/[:alnum:]]+)?|sending end of data -- message may be sent more than once)|connect to [^[:space:]]+: (Connection timed out|read timeout|Connection refused|Network is unreachable|No route to host)|host [^[:space:]]+ refused to talk to me: [45][[:digit:]][[:digit:]].*|Host or domain name not found. Name service error for name=[^[:space:]]+ type=(MX|A|AAAA): Host (not found, try again|found but no data record of requested type)|User unknown in virtual alias table|host [^[:space:]]+\[[[:xdigit:].:]{3,39}\] said: [45][[:digit:]][[:digit:]] [45](\.[[:digit:]]+){2} <[^>]+>: (Temporarily rejected\. Try again later\.|Recipient address rejected: ((undeliverable|unverified) address:|Domain not found)) .*)\)$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^>]+>,( orig_to=<[^>]+>,)? relay=[^[:space:]]+\[[[:xdigit:].:]{3,39}\]:[[:digit:]]+,( conn_use=[[:digit:]]+,)? delay=[[:digit:].]+,( delays=[[:digit:]./]+,)?( dsn=[45]\.[[:digit:]]\.[[:digit:]],)? status=undeliverable \(host -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: host [^[:space:]]+\[[[:xdigit:].:]{3,39}\]( said: 45[01] .* \(in reply to RCPT TO command\)| refused to talk to me: 421 ) -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: lost connection with [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\] while (receiving the initial server greeting|sending [[:upper:] ]+|performing the HELO handshake|sending end of data -- message may be sent more than once)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: host [^[:space:]]+\[[[:xdigit:].:]{3,39}\]( said: 45[01][ -].* \(in reply to (MAIL FROM|RCPT TO) command\)| refused to talk to me: (421|450) ) +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(out|msa)/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: lost connection with [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\] while (receiving the initial server greeting|sending [[:upper:] ]+|performing the HELO handshake|sending end of data -- message may be sent more than once)$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: conversation with [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\] timed out while (sending message body|receiving the initial server greeting)$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^>]+>(, orig_to=<[^>]+>)?, relay=[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\](:[[:digit:]]{1,5})?,( conn_use=[[:digit:]]+,)? delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=[45](\.[[:digit:]]+){2})?, status=(deferred|bounced|undeliverable|SOFTBOUNCE) \(host [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\] said: [45][[:digit:]][[:digit:]][- ]+.* \(in reply to (HELO|EHLO|MAIL FROM|RCPT TO|DATA|end of DATA) command\)\)$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: connect to [^[:space:]]+: (read timeout|Connection (refused|timed out)|Network is unreachable|No route to host)( \(port [[:digit:]]+\))?$ @@ -52,10 +58,11 @@ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mda|out|lists)/smtpd\[[[:digit:]]+\]: [[:xdigit:]]+: client=[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\], orig_queue_id=[[:xdigit:]]+, orig_client=[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [A-Z[:digit:]]+: to=<[^>]+>,( orig_to=<[^>]+>,) relay=[^[:space:]]+, delay=[[:digit:]]+, status=deferred \(host [^[:space:]]+ said: [45][[:digit:]]{2} <[^[:space:]]*>: Recipient address rejected: Greylisted for [[:digit:]]+ (seconds|minutes)(\(see http://isg.ee.ethz.ch/tools/postgrey/help/[.[:alnum:]-]+.html\))? \(in reply to (HELO|EHLO|MAIL FROM|RCPT TO|DATA|end of DATA) command\)\)$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: to=<.*>,( orig_to=<[^>]+>,)? relay=[^[:space:]]+\](:[[:digit:]]+)?,( conn_use=[[:digit:]]+,)? delay=[[:digit:].]+,( delays=[[:digit:]./]+,)?( dsn=4\.[[:digit:]]\.[[:digit:]],)? status=deferred \(host [^[:space:]]+\] said: .*$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mda|out)/smtpd?\[[[:digit:]]+\]: warning: numeric domain name in resource data of MX record for [._[:alnum:]-]+: [[:xdigit:].:]{3,39}$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mda|out|mx)/smtpd?\[[[:digit:]]+\]: warning: valid_hostname: numeric hostname: [0-9]+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mda|out|mx)/smtpd?\[[[:digit:]]+\]: warning: (malformed|numeric) domain name in resource data of MX record for [._[:alnum:]-]+:\s ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: warning: no MX host for [._[:alnum:]-]+ has a valid address record$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/smtpd\[[[:digit:]]+\]: SSL_accept error from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: (lost connection|Connection reset by peer|-?[[:digit:]]+|Connection timed out)$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:SSL3_READ_BYTES:(sslv3|tlsv1) alert (unknown ca|certificate unknown):s3_pkt.c:[0-9]+:SSL alert number [[:digit:]]+:$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/smtpd\[[[:digit:]]+\]: SSL_accept error from [._[:alnum:]-]+\[([[:xdigit:].:]{3,39}|unknown)\]: (lost connection|Connection reset by peer|-?[[:digit:]]+|Connection timed out|Broken pipe)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:SSL3_READ_BYTES:(sslv3|tlsv1) alert (unknown ca|certificate unknown):s3_pkt\.c:[0-9]+:SSL alert number [[:digit:]]+:$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(out|mx)/bounce\[[[:digit:]]+\]: [[:xdigit:]]+: sender (delay|non-delivery|delivery status) notification: [[:xdigit:]]+$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: host [^[:space:]]+ refused to talk to me: [45][[:digit:]][[:digit:]].*$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: enabling PIX <CRLF>\.<CRLF> workaround for [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\](:[[:digit:]]{1,5})?$ @@ -64,20 +71,23 @@ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: SSL_connect error to [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]:[[:digit:]]+: -?[[:digit:]]+$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:SSL2?3_CHECK_CERT_AND_ALGORITHM:dh key too small:s2?3_clnt\.c:[0-9]+:$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: Cannot start TLS: handshake failure$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/tlsproxy\[[[:digit:]]+\]: TLS handshake failed for service=smtpd peer=\[[[:xdigit:].:]{3,39}\]:[0-9]+$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: Host offered STARTTLS: \[[._[:alnum:]-]+\]$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: [[:xdigit:]]+: reject: RCPT from [^[:space:]]+: 4[[:digit:]][[:digit:]]( 4(\.[[:digit:]]){2}) <[^[:space:]]*>: Recipient address rejected: Greylisted( for [[:digit:]]+ (second|minute)s)?, see https?://[-_.:/[:alnum:]]+\.html?; from=<[^>]*> to=<[^>]+> proto=E?SMTP helo=<[^[:space:]]+>$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: [[:xdigit:]]+: reject: RCPT from [^[:space:]]+: 4[[:digit:]][[:digit:]]( 4(\.[[:digit:]]+){2}) <[^[:space:]]*>: Recipient address rejected: Greylisted( for [[:digit:]]+ (second|minute)s)?, see https?://[-_.:/[:alnum:]]+\.html?; from=<[^>]*> to=<[^>]+> proto=E?SMTP helo=<[^[:space:]]+>$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-\w+/smtpd\[[[:digit:]]+\]: lost connection after [[:upper:]]+( \([[:digit:]]+ bytes\))? from [._[:alnum:]-]+\[(unknown|[[:xdigit:].:]{3,39})\]$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: [[:xdigit:]]+: reject: (CONNECT|RCPT) from [^[:space:]]+: [45][[:digit:]][[:digit:]]( [45](\.[[:digit:]]){2})? Service unavailable; Client host \[([[:xdigit:].:]{3,39}|[-._[:alnum:]]+)\] blocked using [._[:alnum:]-]+;( .+;)? (from=<[^>]*> to=<[^>]+> )?proto=E?SMTP( helo=<[^[:space:]]+>)?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: RCPT from [^[:space:]]+: [[:digit:]]{3}( [45](\.[[:digit:]]){2})? <[^[:space:]]*>: Relay access denied; from=<[^>]*> to=<[^>]+> proto=E?SMTP helo=<[^[:space:]]+>$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: [[:xdigit:]]+: reject: (CONNECT|RCPT) from [^[:space:]]+: [45][[:digit:]][[:digit:]]( [45](\.[[:digit:]]+){2})? Service unavailable; Client host \[([[:xdigit:].:]{3,39}|[-._[:alnum:]]+)\] blocked using [._[:alnum:]-]+;( .+;)? (from=<[^>]*> to=<[^>]+> )?proto=E?SMTP( helo=<[^[:space:]]+>)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: RCPT from [^[:space:]]+: [[:digit:]]{3}( [45](\.[[:digit:]]+){2})? <[^[:space:]]*>: Relay access denied; from=<[^>]*> to=<[^>]+> proto=E?SMTP helo=<[^[:space:]]+>$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: warning: ([-._[:alnum:]]+): RBL lookup error: Host or domain name not found\. Name service error for name=\1 type=A(AAA)?: Host not found, try again$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mx|msa)/(smtpd|tlsproxy)\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:SSL2?3_(GET_RECORD:(decryption failed or bad record mac|wrong version number):s3_pkt\.c:[0-9]+:|READ_BYTES:(reason\([[:digit:]]+\)|sslv3 alert (unexpected message|bad certificate)):s3_pkt\.c:[[:digit:]]+:SSL alert number (0|10|42):|GET_CLIENT_HELLO:(unsupported protocol|no shared cipher|unknown protocol|wrong version number):s2?3_srvr\.c:[0-9]+:)$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/tlsproxy\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:tls_post_process_client_hello:no shared cipher:\.\./ssl/statem/statem_srvr\.c:[0-9]+:$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:tls_process_client_hello:(no shared cipher|unknown protocol|version too low):\.\./ssl/statem/statem_srvr\.c:[0-9]+:$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: [[:upper:]]+ from [^[:space:]]+: 554( 5\.1\.[01])? <[^[:space:]]*>: Recipient address rejected: User unknown in virtual alias table;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: [[:xdigit:]]+: reject: RCPT from [^[:space:]]+: [45][[:digit:]][[:digit:]]( [45](\.[[:digit:]]){2})? <[^[:space:]]*>: Helo command rejected: .+; from=<[^>]*> to=<[^>]+> proto=E?SMTP helo=<[^[:space:]]+>$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mx|msa)/(smtpd|tlsproxy)\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:(ssl3_get_record:(wrong version number|http request|packet length too long|bad record type)|tls_post_process_client_hello:no shared cipher): +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mx|msa)/(smtpd|tlsproxy)\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:ssl3_read_bytes:(sslv3 alert bad certificate|unexpected record|tlsv1 alert user cancelled): +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mx|msa)/(smtpd|tlsproxy)\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:tls_parse_ctos_key_share:bad key share: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/(smtpd|tlsproxy)\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:tls_((early_)?post_)?process_client_hello:(no shared cipher|unknown protocol|unsupported protocol|version too low):\.\./ssl/statem/statem_srvr\.c:[0-9]+:$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: [[:upper:]]+ from [^[:space:]]+: 55[0-9]( 5\.1\.[01])? <[^[:space:]]*>: Recipient address rejected: User unknown in virtual alias table;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: [[:xdigit:]]+: reject: RCPT from [^[:space:]]+: [45][[:digit:]][[:digit:]]( [45](\.[[:digit:]]+){2})? <[^[:space:]]*>: Helo command rejected: .+; from=<[^>]*> to=<[^>]+> proto=E?SMTP helo=<[^[:space:]]+>$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: too many errors after ([[:upper:]]{4}|END-OF-MESSAGE|UNKNOWN|DATA \(0 bytes\)) from [._[:alnum:]-]+\[[.[:digit:]]+\]$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mx|msa)/smtpd\[[[:digit:]]+\]: warning: hostname [^[:space:]]+ does not resolve to address [[:xdigit:].:]{3,39}: (No address associated with hostname|Temporary failure in name resolution)$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: warning: (numeric hostname: [[:xdigit:].:]{3,39}|valid_hostname: misplaced delimiter: \S)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mx|msa)/smtpd\[[[:digit:]]+\]: warning: (numeric hostname: [[:xdigit:].:]{3,39}|valid_hostname: misplaced delimiter: \S)$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mx|lists)/pipe\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^>]+>,( orig_to=<[^>]+>,)* relay=([-_.[:alnum:]]+), delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=2(\.[[:digit:]]+){2})?, status=sent \(delivered via \3 service\)$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/discard\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^>]+>,( orig_to=<[^>]+>,)* relay=none, delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=2(\.[[:digit:]]+){2})?, status=sent \(discard\.fripost\.org\)$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mx|msa)/smtpd\[[[:digit:]]+\]: warning: Illegal address syntax from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\] in (MAIL|RCPT) command:\s @@ -90,10 +100,11 @@ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: NON-SMTP COMMAND from \[[[:xdigit:].:]{3,39}\]:[[:digit:]]+\s ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: COMMAND PIPELINING from \[[[:xdigit:].:]{3,39}\]:[[:digit:]]+ after\s ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: DNSBL rank [[:digit:]]+ for \[[[:xdigit:].:]{3,39}\]:[[:digit:]]+$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from (\[[[:xdigit:].:]{3,39}\]):[[:digit:]]+: [45][[:digit:]][[:digit:]]( [45](\.[[:digit:]]){2})? (Service unavailable; client \1 blocked using [._[:alnum:]-]+|Protocol error|Service currently unavailable);( .+;)? (from=<[^>]*>, to=<[^>]+>, )?proto=E?SMTP(, helo=<[^[:space:]]+>)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: [[:upper:]]+ without valid RCPT from \[[[:xdigit:].:]{3,39}\]:[[:digit:]]+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from (\[[[:xdigit:].:]{3,39}\]):[[:digit:]]+: [45][[:digit:]][[:digit:]]( [45](\.[[:digit:]]+){2})? (Service unavailable; client \1 blocked using [._[:alnum:]-]+|Protocol error|Service currently unavailable);( .+;)? (from=<[^>]*>, to=<[^>]+>, )?proto=E?SMTP(, helo=<[^[:space:]]+>)?$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: NOQUEUE: reject: CONNECT from \[[[:xdigit:].:]{3,39}\]:[[:digit:]]+: too many connections$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: COMMAND (COUNT|TIME) LIMIT from \[[[:xdigit:].:]{3,39}\]:[[:digit:]]+( after [[:upper:]]+)?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: cache [a-z]+:\S+ full cleanup: retained=[[:digit:]]+ dropped=[[:digit:]]+ entries$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: cache [a-z]+:\S+ (partial|full) cleanup: retained=[[:digit:]]+ dropped=[[:digit:]]+ entries$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: warning: getpeername: Transport endpoint is not connected -- dropping this connection$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: warning: psc_cache_update: lmdb:/var/lib/postfix-mx/postscreen_cache update average delay is [[:digit:]]+ ms$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: warning: dnsblog reply timeout [[:digit:]]+s for [._[:alnum:]-]+$ @@ -104,8 +115,19 @@ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: Start(ing|ed) Postfix sender login socketmap\.(\.\.)?$ # # Amavis -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ amavis\[[[:digit:]]+\]: \([-[:digit:]]+\) Passed (CLEAN|SPAM|UNCHECKED(-[A-Z]+)?|BAD-HEADER-[28]) {Relayed(Tagged)?(Internal|Inbound|Outbound)}, (INCOMING|OUTGOING)( LOCAL)? \[(IPv6:)?[[:xdigit:].:]{3,39}\](:[[:digit:]]+)?( \[[[:xdigit:].:]{3,39}\])? <[^>]*> -> (<[^>]*>,)+( Queue-ID: [[:xdigit:]]+,)?( Message-ID: <[^>]+>,)?( Resent-Message-ID: <[^>]+>,)? mail_id: [_-+[:alnum:]]+, Hits: -?[[:digit:].]*, size: [[:digit:]]+, queued_as: [[:xdigit:]]+(, dkim_(new|sd)?=[-_.,:[:alnum:]]+)?, [[:digit:]]+ ms$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ amavis\[[[:digit:]]+\]: \([-[:digit:]]+\) Passed (CLEAN|SPAM|UNCHECKED(-[A-Z]+)?|BAD-HEADER-[28]) {Relayed(Tagged)?(Internal|Inbound|Outbound)}, (INCOMING|OUTGOING)( LOCAL)? \[(IPv6:)?[[:xdigit:].:]{3,39}\](:[[:digit:]]+)?( \[[[:xdigit:].:]{3,39}\])? <[^>]*> -> (<[^>]*>,)+( Queue-ID: [[:xdigit:]]+,)?( Message-ID: <[^>]+>,)?( Resent-Message-ID: <[^>]+>,)? mail_id: [-_+[:alnum:]]+, Hits: -?[[:digit:].]*, size: [[:digit:]]+, queued_as: [[:xdigit:]]+(, dkim_(new|sd)?=[-_.,:[:alnum:]]+)?, [[:digit:]]+ ms$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ amavis\[[[:digit:]]+\]: \([-[:digit:]]+\) Passed (CLEAN|SPAM|UNCHECKED(-[A-Z]+)?|BAD-HEADER-[28]) {Relayed(Tagged)?(Internal|Inbound|Outbound)}, (INCOMING|OUTGOING)( LOCAL)? \[(IPv6:)?[[:xdigit:].:]{3,39}\](:[[:digit:]]+)?( \[[[:xdigit:].:]{3,39}\])? <[^>]*> -> (<[^>]*>,)*(<[^>]*)?\.\.\.$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ amavis\[[[:digit:]]+\]: \([-[:digit:]]+\) \.\.\.([^>]*>)?(,<[^>]*>)*,( Queue-ID: [[:xdigit:]]+,)?( Message-ID: <[^>]+>,)?( Resent-Message-ID: <[^>]+>,)? mail_id: [_-+[:alnum:]]+, Hits: -?[[:digit:].]*, size: [[:digit:]]+, queued_as: [[:xdigit:]]+(, dkim_(new|sd)?=[-_.,:[:alnum:]]+)?, [[:digit:]]+ ms$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ amavis\[[[:digit:]]+\]: \([-[:digit:]]+\) \.\.\.([^>]*>)?(,<[^>]*>)*,( Queue-ID: [[:xdigit:]]+,)?( Message-ID: <[^>]+>,)?( Resent-Message-ID: <[^>]+>,)? mail_id: [-_+[:alnum:]]+, Hits: -?[[:digit:].]*, size: [[:digit:]]+, queued_as: [[:xdigit:]]+(, dkim_(new|sd)?=[-_.,:[:alnum:]]+)?, [[:digit:]]+ ms$ # SMTP client connection caching was introduced in 2.6.0; the SMTP session is held for the next task, and is terminated by Postfix if the next mail comes soon enough ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtpd\[[[:digit:]]+\]: timeout after END-OF-MESSAGE from [._[:alnum:]-]+\[(127.0.0.1|::1)\]$ +# +# OpenDMARC +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ opendmarc\[[0-9]+\]: implicit authentication service: [-_.[:alnum:]]+\.fripost\.org$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ opendmarc\[[0-9]+\]: [[:xdigit:]]+: RFC5322 requirement error: (not exactly one Date field|multiple Message-Id fields)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ opendmarc\[[0-9]+\]: [[:xdigit:]]+: unable to parse From header field$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ opendmarc\[[0-9]+\]: [[:xdigit:]]+:? ignoring Authentication-Results at\s +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ opendmarc\[[0-9]+\]: [[:xdigit:]]+: ignoring invalid ARC-Authentication-Results header ".*" +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ opendmarc\[[0-9]+\]: [[:xdigit:]]+: SPF\((mailfrom|helo)\): \S+ (none|tempfail|fail|pass)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ opendmarc\[[0-9]+\]: [[:xdigit:]]+: [-_.[:alnum:]]+ (none|fail|pass)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ opendmarc\[[0-9]+\]: [[:xdigit:]]+: opendmarc_policy_query_dmarc\([._[:alnum:]-]+\) returned status 4$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ opendmarc\[[0-9]+\]: opendmarc: opendmarc-arcares\.c:[0-9]+: opendmarc_arcares_strip_whitespace: Assertion `.*' failed\.$ diff --git a/roles/common/files/etc/logcheck/ignore.d.server/strongswan-local b/roles/common/files/etc/logcheck/ignore.d.server/strongswan-local index cebfaba..e78e9f0 100644 --- a/roles/common/files/etc/logcheck/ignore.d.server/strongswan-local +++ b/roles/common/files/etc/logcheck/ignore.d.server/strongswan-local @@ -3,17 +3,22 @@ # ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[KNL\] creating acquire job for policy [[:xdigit:].:]{3,39}/[[:digit:]]+(\[\w+(/[[:alnum:]-]+)?\])? === [[:xdigit:].:]{3,39}/[[:digit:]]+(\[\w+(/[[:alnum:]-]+)?\])? with reqid \{[[:digit:]]+\}$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[KNL\] creating rekey job for CHILD_SA ESP/0x[[:xdigit:]]{8}/[[:xdigit:].:]{3,39}$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[KNL\] creating delete job for CHILD_SA ESP/0x[[:xdigit:]]{8}/[[:xdigit:].:]{3,39}$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[JOB\] CHILD_SA ESP/0x[[:xdigit:]]{8}/[[:xdigit:].:]{3,39} not found for delete$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[KNL\] creating delete job for CHILD_SA ESP/0x[[:xdigit:]]{8}/([[:xdigit:].:]{3,39}|%any)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[JOB\] CHILD_SA ESP/0x[[:xdigit:]]{8}/([[:xdigit:].:]{3,39}|%any) not found for delete$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ ipsec\[[[:digit:]]+\]: [[:digit:]]+\[JOB\] spawning [0-9]+ worker threads$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] initiating IKE_SA [[:alnum:]._-]+\[[[:digit:]]+\] to [[:xdigit:].:]{3,39}$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] [[:xdigit:].:]{3,39} is initiating an IKE_SA$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] establishing CHILD_SA [[:alnum:]._-]+(\{[[:digit:]]+\})?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] establishing CHILD_SA [[:alnum:]._-]+(\{[[:digit:]]+\}( reqid [0-9]+)?)?$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] IKE_SA [[:alnum:]._-]+\[[[:digit:]]+\] established between [[:xdigit:].:]{3,39}\[[^]\"]+\]\.\.\.[[:xdigit:].:]{3,39}\[[^]]+\]$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] CHILD_SA [[:alnum:]._-]+\{[[:digit:]]+\} established with SPIs [[:xdigit:]]{8}_i [[:xdigit:]]{8}_o and TS [[:xdigit:].:]{3,39}/[[:digit:]]+ === [[:xdigit:].:]{3,39}/[[:digit:]]+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] ((in|out)bound )?CHILD_SA [[:alnum:]._-]+\{[[:digit:]]+\} established with SPIs [[:xdigit:]]{8}_i [[:xdigit:]]{8}_o and TS [[:xdigit:].:]{3,39}/[[:digit:]]+ === [[:xdigit:].:]{3,39}/[[:digit:]]+$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] closing CHILD_SA [[:alnum:]._-]+\{[[:digit:]]+\} with SPIs [[:xdigit:]]{8}_i \([[:digit:]]+ bytes\) [[:xdigit:]]{8}_o \([[:digit:]]+ bytes\) and TS [[:xdigit:].:]{3,39}/[[:digit:]]+ === [[:xdigit:].:]{3,39}/[[:digit:]]+$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] reauthenticating IKE_SA [[:alnum:]._-]+\[[[:digit:]]+\]$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[JOB\] deleting IKE_SA after [[:digit:]]+ seconds of CHILD_SA inactivity$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] deleting IKE_SA [[:alnum:]._-]+\[[[:digit:]]+\] between [[:xdigit:].:]{3,39}\[[^]\"]+\]\.\.\.[[:xdigit:].:]{3,39}\[[^]]+\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[JOB\] deleting CHILD_SA after [[:digit:]]+ seconds of inactivity$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[JOB\] CHILD_SA \{[[:digit:]]+\} not found for delete$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[JOB\] deleting half open IKE_SA with [[:xdigit:].:]{3,39} after timeout$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] IKE_SA deleted$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ vpn: [+-] .* [[:xdigit:].:]{3,39}/[[:digit:]]+ == [[:xdigit:].:]{3,39} -- [[:xdigit:].:]{3,39} == [[:xdigit:].:]{3,39}/[[:digit:]]+$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[MGR\] ignoring request with ID [[:digit:]]+, already processing$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[KNL\] flags changed for [[:xdigit:].:]{3,39} on e[nt][[:alnum:]]+ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[KNL\] [[:xdigit:].:]{3,39} appeared on e[nt][[:alnum:]]+$ diff --git a/roles/common/files/etc/logcheck/violations.ignore.d/logcheck-sudo b/roles/common/files/etc/logcheck/violations.ignore.d/logcheck-sudo index e474019..70673ae 100644 --- a/roles/common/files/etc/logcheck/violations.ignore.d/logcheck-sudo +++ b/roles/common/files/etc/logcheck/violations.ignore.d/logcheck-sudo @@ -1,7 +1,5 @@ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sudo: pam_krb5\(sudo:auth\): user [[:alnum:]-]+ authenticated as [[:alnum:]-]+@[.A-Z]+$ -# ignore sudo with custom ENV -#^\w{3} [ :0-9]{11} [._[:alnum:]-]+ sudo:[[:space:]]+[_[:alnum:].-]+ : TTY=(unknown|console|(pts/|tty|vc/)[[:digit:]]+) ; PWD=[^;]+ ; USER=[._[:alnum:]-]+ ; COMMAND=((/(usr|etc|bin|sbin)/|sudoedit ).*|list)$ -^\w{3} [ :0-9]{11} [._[:alnum:]-]+ sudo:[[:space:]]+[_[:alnum:].-]+ : TTY=(unknown|console|(pts/|tty|vc/)[[:digit:]]+) ; PWD=[^;]+ ; USER=[._[:alnum:]-]+ (; ENV=([_a-zA-Z]+=\S* )+)?; COMMAND=((/(usr|etc|bin|sbin)/|sudoedit ).*|list)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sudo: pam_krb5\(sudo:auth\): user [._[:alnum:]-]+ authenticated as [._[:alnum:]-]+@[.A-Z]+$ +^\w{3} [ :0-9]{11} [._[:alnum:]-]+ sudo:[[:space:]]+[_[:alnum:].-]+ : (TTY=(unknown|console|(pts/|tty|vc/)[[:digit:]]+) ; )?PWD=[^;]+ ; USER=[._[:alnum:]-]+( ; GROUP=[._[:alnum:]-]+)? ; COMMAND=((/(usr|etc|bin|sbin)/|sudoedit ).*|list)$ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ sudo:[[:space:]]+[_[:alnum:].-]+ : \(command continued\).*$ -^\w{3} [ :0-9]{11} [._[:alnum:]-]+ sudo: pam_[[:alnum:]]+\(sudo:session\): session opened for user [[:alnum:]-]+ by ([[:alnum:]-]+)?\(uid=[0-9]+\)$ -^\w{3} [ :0-9]{11} [._[:alnum:]-]+ sudo: pam_[[:alnum:]]+\(sudo:session\): session closed for user [[:alnum:]-]+$ +^\w{3} [ :0-9]{11} [._[:alnum:]-]+ sudo: pam_[[:alnum:]]+\(sudo:session\): session opened for user [._[:alnum:]-]+\(uid=[0-9]+\) by ([[:alnum:]-]+)?\(uid=[0-9]+\)$ +^\w{3} [ :0-9]{11} [._[:alnum:]-]+ sudo: pam_[[:alnum:]]+\(sudo:session\): session closed for user [._[:alnum:]-]+$ diff --git a/roles/common/files/etc/rkhunter.conf b/roles/common/files/etc/rkhunter.conf index ce3b2d6..c7358d0 100644 --- a/roles/common/files/etc/rkhunter.conf +++ b/roles/common/files/etc/rkhunter.conf @@ -353,7 +353,7 @@ ALLOW_SSH_PROT_V1=2 # program defaults. # ENABLE_TESTS=ALL -DISABLE_TESTS=suspscan hidden_procs deleted_files packet_cap_apps apps +DISABLE_TESTS=suspscan hidden_ports hidden_procs deleted_files packet_cap_apps apps # # The HASH_CMD option can be used to specify the command to use for the file @@ -562,6 +562,10 @@ HASH_CMD=SHA512 # #EXISTWHITELIST="" +# work around for usr-merge, cf. https://bugs.debian.org/932594 +EXISTWHITELIST=/usr/bin/egrep +EXISTWHITELIST=/usr/bin/fgrep + # # Whitelist various attributes of the specified file. The attributes are those # of the 'attributes' test. Specifying a file name here does not include it @@ -592,7 +596,9 @@ HASH_CMD=SHA512 # SCRIPTWHITELIST=/bin/egrep SCRIPTWHITELIST=/bin/fgrep -SCRIPTWHITELIST=/bin/which +SCRIPTWHITELIST=/usr/bin/egrep +SCRIPTWHITELIST=/usr/bin/fgrep +SCRIPTWHITELIST=/usr/bin/which SCRIPTWHITELIST=/usr/bin/ldd SCRIPTWHITELIST=/usr/bin/lwp-request SCRIPTWHITELIST=/usr/sbin/adduser diff --git a/roles/common/files/etc/rsyslog.conf b/roles/common/files/etc/rsyslog.conf index 6340537..42b01c5 100644 --- a/roles/common/files/etc/rsyslog.conf +++ b/roles/common/files/etc/rsyslog.conf @@ -90,11 +90,11 @@ user.* -/var/log/user.log # *.=debug;\ auth,authpriv.none;\ - news.none;mail.none -/var/log/debug + mail.none -/var/log/debug *.=info;*.=notice;*.=warn;\ auth,authpriv.none;\ cron,daemon.none;\ - mail,news.none -/var/log/messages + mail.none -/var/log/messages # # Emergencies are sent to everybody logged in. diff --git a/roles/common/files/etc/strongswan.d/charon.conf b/roles/common/files/etc/strongswan.d/charon.conf index 22479cf..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/bacula-fd.service b/roles/common/files/etc/systemd/system/bacula-fd.service.d/override.conf index 119b3a2..537bf1e 100644 --- a/roles/common/files/etc/systemd/system/bacula-fd.service +++ b/roles/common/files/etc/systemd/system/bacula-fd.service.d/override.conf @@ -1,18 +1,9 @@ -[Unit] -Description=Bacula File Daemon service -After=network.target - [Service] -Type=simple -StandardOutput=syslog -ExecStart=/usr/sbin/bacula-fd -f -c /etc/bacula/bacula-fd.conf - # Hardening NoNewPrivileges=yes ProtectHome=read-only ProtectSystem=strict ReadWriteDirectories=/var/lib/bacula -RuntimeDirectory=bacula PrivateTmp=yes PrivateDevices=yes ProtectControlGroups=yes @@ -20,6 +11,3 @@ ProtectKernelModules=yes ProtectKernelTunables=yes RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 CapabilityBoundingSet=CAP_DAC_READ_SEARCH - -[Install] -WantedBy=multi-user.target diff --git a/roles/common/files/etc/systemd/system/fail2ban.service.d/override.conf b/roles/common/files/etc/systemd/system/fail2ban.service.d/override.conf index e3e651f..b34d130 100644 --- a/roles/common/files/etc/systemd/system/fail2ban.service.d/override.conf +++ b/roles/common/files/etc/systemd/system/fail2ban.service.d/override.conf @@ -2,13 +2,16 @@ After=nftables.service [Service] +ExecStartPre= +ExecStart= +ExecStart=/usr/bin/fail2ban-server -xf --logtarget=sysout start + # Need explicit rights to read logs as we don't grant CAP_DAC_READ_SEARCH SupplementaryGroups=adm # Hardening NoNewPrivileges=yes ProtectSystem=strict -ReadWriteDirectories=/var/log/fail2ban RuntimeDirectory=fail2ban PrivateDevices=yes ProtectControlGroups=yes diff --git a/roles/common/files/etc/systemd/system/munin-node.service.d/override.conf b/roles/common/files/etc/systemd/system/munin-node.service.d/override.conf index 53747f6..fee16b3 100644 --- a/roles/common/files/etc/systemd/system/munin-node.service.d/override.conf +++ b/roles/common/files/etc/systemd/system/munin-node.service.d/override.conf @@ -1,4 +1,5 @@ [Service] +ExecStartPre= # Hardening NoNewPrivileges=yes diff --git a/roles/common/files/usr/local/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 2437653..18462cb 100644 --- a/roles/common/handlers/main.yml +++ b/roles/common/handlers/main.yml @@ -18,7 +18,7 @@ command: /usr/bin/rkhunter --propupd - name: Update firewall - command: /usr/local/sbin/update-firewall.sh -c + command: /usr/local/sbin/update-firewall -c - name: Restart fail2ban service: name=fail2ban state=restarted @@ -29,6 +29,12 @@ - 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 + - name: Restart ntp service: name=ntp state=restarted diff --git a/roles/common/tasks/bacula.yml b/roles/common/tasks/bacula.yml index fb37b5b..308e358 100644 --- a/roles/common/tasks/bacula.yml +++ b/roles/common/tasks/bacula.yml @@ -10,7 +10,7 @@ - name: Delete /etc/bacula/common_default_passwords file: path=/etc/bacula/common_default_passwords state=absent -# Create with: +# Populate with: # echo $director-dir $(pwgen -sn 64 1) | sudo tee -a /etc/bacula/passwords-fd - name: Ensure /etc/bacula/passwords-fd exists file: path=/etc/bacula/passwords-fd @@ -54,23 +54,21 @@ tags: - genkey -- name: Copy bacula-fd.service - copy: src=etc/systemd/system/bacula-fd.service - dest=/etc/systemd/system/bacula-fd.service +- name: Create /etc/systemd/system/bacula-fd.service.d + file: path=/etc/systemd/system/bacula-fd.service.d + state=directory + owner=root group=root + mode=0755 + +- name: Copy bacula-fd.service override + copy: src=etc/systemd/system/bacula-fd.service.d/override.conf + dest=/etc/systemd/system/bacula-fd.service.d/override.conf owner=root group=root mode=0644 notify: - systemctl daemon-reload - Restart bacula-fd -# We use RuntimeDirectory in our service unit to avoid permission issues -# caused by the restrictive Capability Bounding Set -- name: Mask /usr/lib/tmpfiles.d/bacula.conf - file: src=/dev/null - dest=/etc/tmpfiles.d/bacula.conf - owner=root group=root - state=link - - meta: flush_handlers - name: Enable bacula-fd diff --git a/roles/common/tasks/fail2ban.yml b/roles/common/tasks/fail2ban.yml index e56deaf..563075f 100644 --- a/roles/common/tasks/fail2ban.yml +++ b/roles/common/tasks/fail2ban.yml @@ -1,22 +1,6 @@ - name: Install fail2ban apt: pkg=fail2ban -# Log into a dedicate directory so we can use ReadWriteDirectories in -# the .service file -- name: Create directory /var/log/fail2ban - file: path=/var/log/fail2ban - state=directory - owner=root group=adm - mode=0750 - -- name: Fix fail2ban logrotate snippet - lineinfile: dest=/etc/logrotate.d/fail2ban - state=present - line="/var/log/fail2ban/*.log" - insertbefore="^[^#]*\\s{$" - tags: - - logrotate - - name: Configure fail2ban (fail2ban.local) copy: src=etc/fail2ban/fail2ban.local dest=/etc/fail2ban/fail2ban.local diff --git a/roles/common/tasks/ipsec.yml b/roles/common/tasks/ipsec.yml index 4fc2ef7..917c687 100644 --- a/roles/common/tasks/ipsec.yml +++ b/roles/common/tasks/ipsec.yml @@ -3,6 +3,7 @@ vars: packages: - strongswan-charon + - strongswan-starter # for the GCM and openssl plugins - libstrongswan-standard-plugins notify: diff --git a/roles/common/tasks/logging.yml b/roles/common/tasks/logging.yml index b602a49..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/munin-node.yml b/roles/common/tasks/munin-node.yml index a713f08..2411b59 100644 --- a/roles/common/tasks/munin-node.yml +++ b/roles/common/tasks/munin-node.yml @@ -62,10 +62,6 @@ - load - memory - netstat - - ntp_kernel_err - - ntp_kernel_pll_freq - - ntp_kernel_pll_off - - ntp_offset - open_files - open_inodes - processes @@ -78,6 +74,20 @@ notify: - Restart munin-node +- name: Install Munin plugins + file: src=/usr/share/munin/plugins/{{ item }} + dest=/etc/munin/plugins/{{ item }} + owner=root group=root + state=link force=yes + with_items: + - ntp_kernel_err + - ntp_kernel_pll_freq + - ntp_kernel_pll_off + - ntp_offset + when: "'NTP_master' in group_names" + notify: + - Restart munin-node + - name: Delete unnecessary Munin plugins file: path=/etc/munin/plugins/{{ item }} state=absent @@ -90,6 +100,18 @@ notify: - Restart munin-node +- name: Delete unnecessary Munin plugins + file: path=/etc/munin/plugins/{{ item }} + state=absent + with_items: + - ntp_kernel_err + - ntp_kernel_pll_freq + - ntp_kernel_pll_off + - ntp_offset + when: "'NTP_master' not in group_names" + notify: + - Restart munin-node + - name: Install 'if_' Munin wildcard plugin file: src=/usr/share/munin/plugins/{{ item.0 }}_ dest=/etc/munin/plugins/{{ item.0 }}_{{ item.1 }} diff --git a/roles/common/tasks/ntp.yml b/roles/common/tasks/ntp.yml index f9a01c8..2ff9e49 100644 --- a/roles/common/tasks/ntp.yml +++ b/roles/common/tasks/ntp.yml @@ -1,15 +1,33 @@ -- name: Install ntp - apt: pkg=ntp +- name: Remove ntp package + apt: pkg=ntp state={{ state }} purge=yes + vars: + state: "{{ ('NTP_master' in group_names) | ternary('present', 'absent') }}" + +- name: Install systemd-timesyncd package + apt: pkg=systemd-timesyncd state=present purge=yes + when: "'NTP_master' not in group_names" + +- name: Create /etc/systemd/timesyncd.conf.d + file: path=/etc/systemd/timesyncd.conf.d + state=directory + owner=root group=root + mode=0755 + when: "'NTP_master' not in group_names" - name: Configure ntp - template: src=etc/ntp.conf.j2 - dest=/etc/ntp.conf + template: src=etc/{{ conf }}.j2 + dest=/etc/{{ conf }} owner=root group=root mode=0644 + vars: + conf: "{{ ('NTP_master' in group_names) | ternary('ntp.conf', 'systemd/timesyncd.conf.d/fripost.conf') }}" + service: "{{ ('NTP_master' in group_names) | ternary('ntp', 'systemd-timesyncd') }}" notify: - - Restart ntp + - Restart {{ service }} - meta: flush_handlers -- name: Start ntp - service: name=ntp state=started +- name: Start and enable ntp + service: name={{ service }}.service state=started enabled=true + vars: + service: "{{ ('NTP_master' in group_names) | ternary('ntp', 'systemd-timesyncd') }}" diff --git a/roles/common/tasks/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 3bf3b4f..08a1b13 100644 --- a/roles/common/tasks/sysctl.yml +++ b/roles/common/tasks/sysctl.yml @@ -11,10 +11,14 @@ - { name: 'net.ipv4.conf.default.rp_filter', value: 1 } - { name: 'net.ipv4.conf.all.rp_filter', value: 1 } - # Enable TCP/IP SYN cookies to avoid TCP SYN flood attacks. We - # rate-limit not only the default ICMP types 3, 4, 11 and 12 + # Disable SYN cookies and improve SYN backlog handling, see tcp(7) and + # https://levelup.gitconnected.com/linux-kernel-tuning-for-high-performance-networking-high-volume-incoming-connections-196e863d458a + - { name: 'net.ipv4.tcp_syncookies', value: 0 } + - { name: 'net.ipv4.tcp_synack_retries', value: 1 } + - { name: 'net.ipv4.tcp_max_syn_backlog', value: 32768 } + + # We rate-limit not only the default ICMP types 3, 4, 11 and 12 # (0x1818), but also types 0 and 8. See icmp(7). - - { name: 'net.ipv4.tcp_syncookies', value: 1 } - { name: 'net.ipv4.icmp_ratemask', value: 6425 } - { name: 'net.ipv4.icmp_ratelimit', value: 1000 } diff --git a/roles/common/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 fc7691a..f603ed9 100755 --- a/roles/common/templates/etc/nftables.conf.j2 +++ b/roles/common/templates/etc/nftables.conf.j2 @@ -45,8 +45,107 @@ define out-tcp-ports = { flush ruleset +table netdev filter { +{% for if in ansible_interfaces %} +{% if if != "lo" and ansible_facts[if].active %} +{% set addr = (ansible_facts[if].ipv4 | default({'address': '0.0.0.0'})).address %} + chain INGRESS-{{ if }} { + type filter hook ingress device {{ if }} priority -499 + policy accept + + # IPsec traffic (refined later in the filter rule) + ip saddr {{ ipsec_subnet }} ip daddr {{ ipsec[inventory_hostname_short] }} meta secpath exists accept + + # rate-limiting is done directly by the kernel (net.ipv4.icmp_{ratelimit,ratemask} runtime options) + icmp type { echo-reply, echo-request, destination-unreachable, time-exceeded } counter accept + icmpv6 type { echo-reply, echo-request, destination-unreachable, + packet-too-big, time-exceeded, parameter-problem } counter accept + + # accept neighbour discovery for autoconfiguration, RFC 4890 sec. 4.4.1 + ip6 hoplimit 255 icmpv6 type { 133,134,135,136,141,142 } counter accept + + # accept link-local multicast receiver notification messages + ip6 saddr fe80::/10 ip6 daddr ff02::/16 ip6 hoplimit 1 icmpv6 type { 130,131,132,143 } counter accept + + # drop all remaining ICMP/ICMPv6 traffic + meta l4proto { icmp, icmpv6 } counter drop + + # bogon filter (cf. RFC 6890 for non-global ip addresses) + define bogon = { + 0.0.0.0/8 # this host, on this network (RFC 1122 sec. 3.2.1.3) +{% if not addr | ansible.utils.ipaddr('10.0.0.0/8') %} + , 10.0.0.0/8 # private-use (RFC 1918) +{% endif %} + , 100.64.0.0/10 # shared address space (RFC 6598) + , 127.0.0.0/8 # loopback (RFC 1122, sec. 3.2.1.3) + , 169.254.0.0/16 # link local (RFC 3927) + , 172.16.0.0/12 # private-use (RFC 1918) + , 192.0.0.0/24 # IETF protocol assignments (RFC 6890 sec. 2.1) + , 192.0.2.0/24 # documentation (RFC 5737) +{% if not addr | ansible.utils.ipaddr('192.168.0.0/16') %} + , 192.168.0.0/16 # private-use (RFC 1918) +{% endif %} + , 198.18.0.0/15 # benchmarking (RFC 2544) + , 198.51.100.0/24 # documentation (RFC 5737) + , 203.0.113.0/24 # documentation (RFC 5737) + , 224.0.0.0/3 # multicast - class D 224.0.0.0/4 + class E 240.0.0.0/4 (RFC 1112 sec. 4) + , 255.255.255.255/32 # limited broadcast (RFC 0919 sec. 7) + } + + ip saddr $bogon counter drop + ip daddr $bogon counter drop + + # See also https://www.team-cymru.org/Services/Bogons/fullbogons-ipv6.txt + define bogon6 = { + ::1/128 # loopback address (RFC 4291) + , ::/128 # unspecified (RFC 4291) + , ::ffff:0:0/96 # IPv4-mapped address (RFC 4291) + , 100::/64 # discard-only address block (RFC 6666) + , 2001::/23 # IETF protocol assignments (RFC 2928) + , 2001::/32 # TEREDO (RFC 4380) + , 2001:2::/48 # benchmarking (RFC 5180) + , 2001:db8::/32 # documentation (RFC 3849) + , 2001:10::/28 # ORCHID (RFC 4843) + , 2002::/16 # 6to4 (RFC 3056) + , fc00::/7 # unique-local (RFC 4193) + , fe80::/10 # linked-scoped unicast (RFC 4291) + } + + ip6 saddr $bogon6 counter drop + ip6 saddr $bogon6 counter drop + } +{% endif %} +{% endfor %} +} + +table inet raw { + chain PREROUTING-stateless { + # XXX can't add that to the ingress hook as that happens before IP defragmentation + # so we don't have the TCP header in later fragments (we don't want to drop IP + # fragments, see https://blog.cloudflare.com/ip-fragmentation-is-broken/ ) + type filter hook prerouting priority -399 # > NF_IP_PRI_CONNTRACK_DEFRAG (-400) + policy accept + + # stateless filter for bogus TCP packets + tcp flags & (fin|syn|rst|psh|ack|urg) == 0x0 counter drop # null packet + tcp flags & (fin|psh|urg) == fin|psh|urg counter drop # XMAS packet + tcp flags & (syn|rst) == syn|rst counter drop + tcp flags & (fin|rst) == fin|rst counter drop + tcp flags & (fin|syn) == fin|syn counter drop + tcp flags & (fin|psh|ack) == fin|psh counter drop + } + + chain PREROUTING { + type filter hook prerouting priority -199 # > NF_IP_PRI_CONNTRACK (-200) + policy accept + + # stateful filter + ct state invalid counter drop + } +} + table inet filter { - # blackholes + # blackholes (timeout must match /etc/fail2ban/jail.local) set fail2ban { type ipv4_addr; timeout 10m; } set fail2ban6 { type ipv6_addr; timeout 10m; } @@ -56,29 +155,15 @@ 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 - # rate-limiting is done directly by the kernel (net.ipv4.icmp_{ratelimit,ratemask} runtime options) - icmp type { echo-reply, echo-request, destination-unreachable } counter accept - icmpv6 type { echo-reply, echo-request, destination-unreachable, - packet-too-big, time-exceeded, parameter-problem } counter accept + # incoming ICMP/ICMPv6 traffic was filtered in the ingress chain already + meta l4proto { icmp, icmpv6 } counter accept - # accept neighbour discovery for autoconfiguration, RFC 4890 sec. 4.4.1 - icmpv6 type { 133,134,135,136,141,142 } ip6 hoplimit 255 counter accept - - jump martian - jump invalid + # NTP (ntpd uses sport 123 but systemd-timesyncd does not) + udp sport 123 ct state related,established accept - udp sport 123 udp dport 123 ct state related,established accept {% if groups.all | length > 1 %} udp sport 500 udp dport 500 ct state new,related,established accept {% if groups.NATed | length > 0 %} @@ -93,8 +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 @@ -107,19 +192,14 @@ 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 } accept + meta l4proto { icmp, icmpv6 } counter accept - jump martian - jump invalid + # NTP (ntpd uses sport 123 but systemd-timesyncd does not) + udp dport 123 ct state new,related,established accept - udp sport 123 udp dport 123 ct state new,related,established accept {% if groups.all | length > 1 %} udp sport 500 udp dport 500 ct state new,related,established accept {% if groups.NATed | length > 0 %} @@ -143,61 +223,16 @@ table inet filter { counter reject } - chain martian { - # bogon filter (cf. RFC 6890 for non-global ip addresses) - define invalid-ip = { - 0.0.0.0/8 # this host, on this network (RFC 1122 sec. 3.2.1.3) -{% if not ansible_default_ipv4.address | ipaddr('10.0.0.0/8') %} - , 10.0.0.0/8 # private-use (RFC 1918) -{% endif %} - , 100.64.0.0/10 # shared address space (RFC 6598) - , 127.0.0.0/8 # loopback (RFC 1122, sec. 3.2.1.3) - , 169.254.0.0/16 # link local (RFC 3927) -{% if not ansible_default_ipv4.address | ipaddr('172.16.0.0/12') %} - , 172.16.0.0/12 # private-use (RFC 1918) -{% endif %} - , 192.0.0.0/24 # IETF protocol assignments (RFC 6890 sec. 2.1) - , 192.0.2.0/24 # documentation (RFC 5737) -{% if not ansible_default_ipv4.address | ipaddr('192.168.0.0/16') %} - , 192.168.0.0/16 # private-use (RFC 1918) -{% endif %} - , 198.18.0.0/15 # benchmarking (RFC 2544) - , 198.51.100.0/24 # documentation (RFC 5737) - , 203.0.113.0/24 # documentation (RFC 5737) - , 240.0.0.0/4 # reserved (RFC 1112, sec. 4) - , 255.255.255.255/32 # limited broadcast (RFC 0919, section 7) - } - - define invalid-ip6 = { - ::1/128 # loopback address (RFC 4291) - , ::/128 # unspecified (RFC 4291) - , ::ffff:0:0/96 # IPv4-mapped address (RFC 4291) - , 100::/64 # discard-only address block (RFC 6666) - , 2001::/23 # IETF protocol assignments (RFC 2928) - , 2001::/32 # TEREDO (RFC 4380) - , 2001:2::/48 # benchmarking (RFC 5180) - , 2001:db8::/32 # documentation (RFC 3849) - , 2001:10::/28 # ORCHID (RFC 4843) - , 2002::/16 # 6to4 (RFC 3056) - , fc00::/7 # unique-local (RFC 4193) - , fe80::/10 # linked-scoped unicast (RFC 4291) - } - - ip saddr $invalid-ip counter drop - ip daddr $invalid-ip counter drop - - ip6 saddr $invalid-ip6 counter drop - ip6 daddr $invalid-ip6 counter drop + chain 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 invalid { - ct state invalid counter reject - - # drop bogus TCP packets - tcp flags & (fin|syn|rst|psh|ack|urg) == 0x0 counter drop # null packets - tcp flags != syn ct state new counter drop # SYN-flood attacks - tcp flags & (fin|syn|rst|psh|ack|urg) == fin|psh|urg counter drop # XMAS packets - tcp flags & (fin|syn) == fin|syn counter drop # bogus - tcp flags & (syn|rst) == syn|rst counter drop # bogus + 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/ntp.conf.j2 b/roles/common/templates/etc/ntp.conf.j2 index 1016d55..b76f0dd 100644 --- a/roles/common/templates/etc/ntp.conf.j2 +++ b/roles/common/templates/etc/ntp.conf.j2 @@ -15,7 +15,6 @@ filegen clockstats file clockstats type day enable # You do need to talk to an NTP server or two (or three). -{% if 'NTP_master' in group_names %} # Use Stratum One Time Servers: # http://support.ntp.org/bin/view/Servers/StratumOneTimeServers server sth1.ntp.se iburst @@ -24,17 +23,6 @@ server gbg1.ntp.se iburst server gbg2.ntp.se iburst server ntp1.sp.se iburst server ntp2.sp.se iburst -{% else %} -# Sychronize to our (stratum 2) NTP server, to ensure our network has a -# consistent time. -{% for host in groups['NTP_master'] | sort %} -server {{ ipsec[ hostvars[host].inventory_hostname_short ] }} prefer iburst -{% endfor %} -pool 0.{{ geoip | default('debian') }}.pool.ntp.org iburst -pool 1.{{ geoip | default('debian') }}.pool.ntp.org iburst -pool 2.{{ geoip | default('debian') }}.pool.ntp.org iburst -pool 3.{{ geoip | default('debian') }}.pool.ntp.org iburst -{% endif %} # Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for diff --git a/roles/common/templates/etc/postfix/main.cf.j2 b/roles/common/templates/etc/postfix/main.cf.j2 index b369d43..5ac7920 100644 --- a/roles/common/templates/etc/postfix/main.cf.j2 +++ b/roles/common/templates/etc/postfix/main.cf.j2 @@ -31,7 +31,7 @@ virtual_alias_maps = lmdb:/etc/aliases alias_database = $virtual_alias_maps # Forward everything to our internal outgoing proxy -relayhost = [{{ postfix_instance.out.addr | ipaddr }}]:{{ postfix_instance.out.port }} +relayhost = [{{ postfix_instance.out.addr | ansible.utils.ipaddr }}]:{{ postfix_instance.out.port }} relay_domains = smtp_tls_security_level = none diff --git a/roles/common/templates/etc/postfix/master.cf.j2 b/roles/common/templates/etc/postfix/master.cf.j2 index f199ed0..3954085 100644 --- a/roles/common/templates/etc/postfix/master.cf.j2 +++ b/roles/common/templates/etc/postfix/master.cf.j2 @@ -57,6 +57,8 @@ smtp_verify unix - - y - - smtp -o smtp_tls_protocols=!SSLv2,!SSLv3 -o smtp_tls_note_starttls_offer=yes -o smtp_tls_session_cache_database=lmdb:$data_directory/smtp_tls_session_cache + -o smtp_tls_fingerprint_digest=sha256 + -o smtp_tls_policy_maps=lmdb:$config_directory/smtp_tls_policy {% endif %} relay unix - - y - - smtp showq unix n - y - - showq diff --git a/roles/common/templates/etc/systemd/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/systemd/timesyncd.conf.d/fripost.conf.j2 b/roles/common/templates/etc/systemd/timesyncd.conf.d/fripost.conf.j2 new file mode 100644 index 0000000..f578cd9 --- /dev/null +++ b/roles/common/templates/etc/systemd/timesyncd.conf.d/fripost.conf.j2 @@ -0,0 +1,9 @@ +[Time] +# Sychronize to our (stratum 2) NTP server, to ensure our network has a +# consistent time. +{%- set ntp = [] -%} +{%- for host in groups['NTP_master'] -%} +{%- set _ = ntp.append(ipsec[ hostvars[host].inventory_hostname_short ]) -%} +{%- endfor %} + +NTP={{ ntp | join(' ') }} diff --git a/roles/common/templates/etc/unbound/unbound.conf.j2 b/roles/common/templates/etc/unbound/unbound.conf.j2 index 64f32bf..e75e66f 100644 --- a/roles/common/templates/etc/unbound/unbound.conf.j2 +++ b/roles/common/templates/etc/unbound/unbound.conf.j2 @@ -29,4 +29,4 @@ server: # # The following line includes additional configuration files from the # /etc/unbound/unbound.conf.d directory. -include: "/etc/unbound/unbound.conf.d/*.conf" +include-toplevel: "/etc/unbound/unbound.conf.d/*.conf" 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/munin-master/files/etc/nginx/sites-available/munin b/roles/munin-master/files/etc/nginx/sites-available/munin index 7b0b789..2f681fb 100644 --- a/roles/munin-master/files/etc/nginx/sites-available/munin +++ b/roles/munin-master/files/etc/nginx/sites-available/munin @@ -23,15 +23,15 @@ server { location /munin-cgi/munin-cgi-graph/ { fastcgi_split_path_info ^(/munin-cgi/munin-cgi-graph)(.*); + fastcgi_param PATH_INFO $fastcgi_path_info; include snippets/fastcgi.conf; fastcgi_pass unix:/run/munin/cgi-graph.socket; - gzip off; } location /munin/ { fastcgi_split_path_info ^(/munin)(.*); + fastcgi_param PATH_INFO $fastcgi_path_info; include snippets/fastcgi.conf; fastcgi_pass unix:/run/munin/cgi-html.socket; - gzip off; } } diff --git a/roles/munin-master/tasks/main.yml b/roles/munin-master/tasks/main.yml index aa22ac6..6dad93b 100644 --- a/roles/munin-master/tasks/main.yml +++ b/roles/munin-master/tasks/main.yml @@ -8,8 +8,15 @@ - name: Configure rrdcached lineinfile: "dest=/etc/default/rrdcached - regexp='^#?OPTS=' - line='OPTS=\"-s munin -m 660 -l unix:/run/rrdcached.sock -w 1800 -z 1800 -f 3600 -j /var/lib/rrdcached/journal -F -b /var/lib/munin -B\"'" + regexp='^#?{{ item.name }}=' + line='{{ item.name }}=\"{{ item.value }}\"'" + with_items: + - { name: 'BASE_OPTIONS', value: '-B -F' } + - { name: 'BASE_PATH', value: '/var/lib/munin' } + - { name: 'SOCKFILE', value: '/run/rrdcached.sock' } + - { name: 'SOCKGROUP', value: 'munin' } + - { name: 'SOCKMODE', value: '0660' } + - { name: 'WRITE_TIMEOUT', value: '1800' } register: r notify: - Restart rrdcached 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/out/tasks/main.yml b/roles/out/tasks/main.yml index 48c162a..7a297f1 100644 --- a/roles/out/tasks/main.yml +++ b/roles/out/tasks/main.yml @@ -28,6 +28,19 @@ owner=root group=root mode=0644 +- name: Copy the SMTP TLS policy maps + template: src=etc/postfix/smtp_tls_policy.j2 + dest=/etc/postfix-{{ postfix_instance[inst].name }}/smtp_tls_policy + owner=root group=root + mode=0644 + +- name: Compile the SMTP TLS policy maps + postmap: cmd=postmap src=/etc/postfix-{{ postfix_instance[inst].name }}/smtp_tls_policy db=lmdb + owner=root group=root + mode=0644 + notify: + - Reload Postfix + - meta: flush_handlers - name: Start Postfix diff --git a/roles/out/templates/etc/postfix/main.cf.j2 b/roles/out/templates/etc/postfix/main.cf.j2 index c05d9a5..f8aa55a 100644 --- a/roles/out/templates/etc/postfix/main.cf.j2 +++ b/roles/out/templates/etc/postfix/main.cf.j2 @@ -56,7 +56,10 @@ smtp_tls_protocols = !SSLv2, !SSLv3 smtp_tls_note_starttls_offer = yes smtp_tls_session_cache_database = lmdb:$data_directory/smtp_tls_session_cache -smtpd_tls_security_level = none +smtp_tls_fingerprint_digest = sha256 +smtp_tls_policy_maps = lmdb:$config_directory/smtp_tls_policy + +smtpd_tls_security_level = none strict_rfc821_envelopes = yes smtpd_delay_reject = yes diff --git a/roles/out/templates/etc/postfix/smtp_tls_policy.j2 b/roles/out/templates/etc/postfix/smtp_tls_policy.j2 new file mode 100644 index 0000000..7722dc8 --- /dev/null +++ b/roles/out/templates/etc/postfix/smtp_tls_policy.j2 @@ -0,0 +1,12 @@ +# Lookup table matching next-hop destinations to TLS security policies; +# this allows pining the key material for chosen recipient domains. +# +# {{ ansible_managed }} +# Do NOT edit this file directly! +{% for nexthop in ['fripost.org','.fripost.org'] %} + +{{ nexthop }} fingerprint ciphers=high protocols=!SSLv2:!SSLv3:!TLSv1:!TLSv1.1 +{% for h in groups.MX | sort %} + match={{ lookup('pipe', 'openssl pkey -pubin -outform DER <"certs/public/mx'+(hostvars[h].mxno | default('') | string)+'.fripost.org.pub" | openssl dgst -sha256 -c | sed "s/[^=]*=\s*//"') }} +{% endfor %} +{% endfor %} diff --git a/roles/webmail/files/etc/nginx/sites-available/roundcube b/roles/webmail/files/etc/nginx/sites-available/roundcube index 9cc20ad..602668f 100644 --- a/roles/webmail/files/etc/nginx/sites-available/roundcube +++ b/roles/webmail/files/etc/nginx/sites-available/roundcube @@ -24,7 +24,7 @@ server { server_name mail.fripost.org; server_name webmail.fripost.org; - root /var/lib/roundcube; + root /var/lib/roundcube/public_html; include snippets/headers.conf; add_header Content-Security-Policy @@ -36,12 +36,13 @@ server { include snippets/mail.fripost.org.hpkp-hdr; gzip on; + gzip_static on; gzip_vary on; gzip_min_length 256; gzip_types application/font-woff application/font-woff2 application/javascript application/json application/xml image/svg+xml image/x-icon text/css text/plain text/vcard; location = /favicon.ico { - root /usr/share/roundcube/skins/default/images; + root /usr/share/roundcube/skins/elastic/images; log_not_found off; access_log off; } @@ -64,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/files/etc/roundcube/plugins/thunderbird_labels/config.inc.php b/roles/webmail/files/etc/roundcube/plugins/thunderbird_labels/config.inc.php new file mode 100644 index 0000000..2abb423 --- /dev/null +++ b/roles/webmail/files/etc/roundcube/plugins/thunderbird_labels/config.inc.php @@ -0,0 +1,5 @@ +<?php + +$rcmail_config['tb_label_enable'] = true; + +?> 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 afe20bf..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" } @@ -148,7 +150,7 @@ - { var: hide_blockquote_limit, value: "8" } - { var: attachment_reminder, value: "true" } # Don't allow overriding these settings - - { var: dont_override, value: "array('use_fallback_verifier', 'trusted_mtas');" } + - { var: dont_override, value: "array('use_fallback_verifier', 'trusted_mtas')" } - name: Make the logo a hyperlink to the website lineinfile: dest=/usr/share/roundcube/skins/{{ item }}/templates/login.html @@ -172,6 +174,7 @@ - authres_status - password - html5_notifier + - thunderbird_labels - name: Configure Roundcube plugins (2) template: src=etc/roundcube/plugins/{{ item }}/config.inc.php.j2 @@ -181,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; diff --git a/roles/wiki/tasks/main.yml b/roles/wiki/tasks/main.yml index 9d436a9..74c11f8 100644 --- a/roles/wiki/tasks/main.yml +++ b/roles/wiki/tasks/main.yml @@ -11,6 +11,10 @@ - libnet-dns-sec-perl - fcgiwrap - pandoc + ### + - fonts-font-awesome + - libjs-bootstrap4 + - libjs-jquery - name: Stop and disable fcgiwrap socket service: name=fcgiwrap.socket state=stopped enabled=false |