diff --git a/.github/workflows/contributors.yml b/.github/workflows/contributors.yml index 9028a60b..e784ae0e 100644 --- a/.github/workflows/contributors.yml +++ b/.github/workflows/contributors.yml @@ -10,12 +10,6 @@ permissions: pull-requests: write statuses: write -env: - # Assign commit authorship to official Github Actions bot: - GIT_USER: github-actions[bot] - GIT_EMAIL: 41898282+github-actions[bot]@users.noreply.github.com - BRANCH_NAME: contributors-update - jobs: add-contributors: name: 'Add Contributors' @@ -24,64 +18,15 @@ jobs: - name: 'Checkout' uses: actions/checkout@v4 - - name: 'Checkout New Branch and Push It' - run: | - git checkout -b ${{ env.BRANCH_NAME }} - git push --force https://${GITHUB_ACTOR}:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git HEAD:${{ env.BRANCH_NAME }} - git checkout master - - # See https://github.com/marketplace/actions/auto-add-contributors for reference of the action. - # - # This action is not well documented, but it does the job for now. We pin the version in order - # to not have any issues in the future. - name: 'Update CONTRIBUTORS.md' - uses: BobAnkh/add-contributors@v0.2.2 + uses: akhilmhdh/contributors-readme-action@v2.3.6 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - ACCESS_TOKEN: ${{secrets.GITHUB_TOKEN}} - BRANCH: ${{ env.BRANCH_NAME }} - COMMIT_MESSAGE: 'docs: update `CONTRIBUTORS.md`' - PATH: /CONTRIBUTORS.md - CONTRIBUTOR: '## Contributors' - COLUMN_PER_ROW: 6 - IMG_WIDTH: 100 - FONT_SIZE: 14 - AVATAR_SHAPE: round - - # See https://github.com/marketplace/actions/create-pull-request for reference of the action. - - name: 'Create Pull Request' - uses: peter-evans/create-pull-request@v5.0.2 - id: create-pr - with: - token: ${{ secrets.GITHUB_TOKEN }} - base: master - branch: ${{ env.BRANCH_NAME }} - title: 'docs: update `CONTRIBUTORS.md`' - commit-message: 'docs: update `CONTRIBUTORS.md`' - delete-branch: true - committer: ${{ env.GIT_USER }} <${{ env.GIT_EMAIL }}> - author: ${{ env.GIT_USER }} <${{ env.GIT_EMAIL }}> - signoff: true - body: | - Updated `CONTRIBUTORS.md` via the CI workflow: [`contributors.yml`][workflow]. - - [workflow]: https://github.com/docker-mailserver/docker-mailserver/blob/master/.github/workflows/contributors.yml - - # See https://github.com/marketplace/actions/set-commit-status for reference of the action. - # - # GH Actions are limited when it comes to actions triggering other actions. Hence, - # this whole workflow will not trigger a `pull_request` event without a PAT. The lint - # workflow, which is required due to branch protection, is not important for this type - # of PR, so we skip it and pretend it was successful. - - name: 'Set Status for Linting Actions to Success (Skipped)' - uses: myrotvorets/set-commit-status-action@v2.0.0 - continue-on-error: true - with: - token: ${{ secrets.GITHUB_TOKEN }} - # Skipped workflows are still assigned a "success" status: - status: success - # This should be the correct commit SHA on ${{ env.BRANCH_NAME }}: - sha: ${{ steps.create-pr.outputs.pull-request-head-sha }} - # Name of status check to add/update: - context: lint - # Optional message/note we can inline to the right of the context name in the UI: - description: Lint skipped. Not relevant. + readme_path: CONTRIBUTORS.md + collaborators: all + commit_message: 'docs: updated `CONTRIBUTORS.md`' + committer_username: github-actions[bot] + committer_email: 41898282+github-actions[bot]@users.noreply.github.com + pr_title_on_protected: 'docs: update `CONTRIBUTORS.md' + auto_detect_branch_protection: true diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ce7b6fb..0b875e2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,19 @@ All notable changes to this project will be documented in this file. The format ### Breaking - The environment variable `ENABLE_LDAP=1` has been changed to `ACCOUNT_PROVISIONER=LDAP`. +- Postfix now defaults to supporting DSNs (_[Delivery Status Notifications](https://github.com/docker-mailserver/docker-mailserver/pull/3572#issuecomment-1751880574)_) only for authenticated users. This is a security measure to reduce spammer abuse of your DMS instance as a backscatter source. + - If you need to modify this change, please let us know by opening an issue / discussion. + - You can [opt-out (_enable DSNs_) via the `postfix-main.cf` override support](https://docker-mailserver.github.io/docker-mailserver/v12.1/config/advanced/override-defaults/postfix/) using the contents: `smtpd_discard_ehlo_keywords =`. + - Likewise for authenticated users, the submission(s) ports (465 + 587) are configured internally via `master.cf` to keep DSNs enabled (_since authentication protects from abuse_). + + If necessary, DSNs for authenticated users can be disabled via the `postfix-master.cf` override with the following contents: + + ```cf + submission/inet/smtpd_discard_ehlo_keywords=silent-discard,dsn + submissions/inet/smtpd_discard_ehlo_keywords=silent-discard,dsn + ``` + +- using the old path for the Rspamd custom commands file (`/tmp/docker-mailserver/rspamd-modules.conf`), which was deprecated, will now prevent startup; use `/tmp/docker-mailserver/rspamd/custom-commands.conf` instead ### Added diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index cbd2653b..615cc80e 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -1,1880 +1,1954 @@ +# Contributors + Thanks goes to these wonderful people ✨ -## Contributors - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - + - - - - + + + + + + + + + + + + + + + + + + +
- - Thomas + + + casperklein
- Thomas VIAL + Casper
- - Georg + + + fbartels
- Georg Lauterbach + Felix Bartels
- - Casper/ + + + NorseGaud
- Casper + Nathan Pierce
- - Erik + + + williamdes
- Erik Wramner + William Desportes
- - Brennan + + + wernerfred
- Brennan Kinney + Frederic Werner
- - Jean-Denis + + + georglauterbach
- Jean-Denis Vauguet + Georg Lauterbach
-
- - Martin + + + tomav
- Martin Schulze + Thomas VIAL
- - Frederic + + + erik-wramner
- Frederic Werner + Erik Wramner
- - Josef + + + polarathene
- Josef Friedrich + Brennan Kinney
- - Johan + + + chikamichi
- Johan Smits + Jean-Denis Vauguet
- - youtous/ + + + martin-schulze-vireso
- youtous + Martin Schulze
- - 17Halbe/ + + + Josef-Friedrich
- 17Halbe + Josef Friedrich
-
- - Nathan + + + johansmitsnl
- Nathan Pierce + Johan Smits
- - Thorsten + + + youtous
- Thorsten von Eicken + Null
- - Germain + + + 17Halbe
- Germain Masse + Null
- - 00angus/ + + + tve
- 00angus + Thorsten Von Eicken
- - Paul + + + gmasse
- Paul Steinlechner + Germain Masse
- - Dominik + + + 00angus
- Dominik Winter + Null
-
- - Paul + + + alinmear
- Paul Adams + Paul Steinlechner
- - Felix + + + ap-wtioit
- Felix Bartels + Andreas Perhab
- - Sebastian + + + dominikwinter
- Sebastian Wiesendahl + Dominik Winter
- - Steve + + + crazystick
- Steve Johnson + Paul Adams
- - André + + + swiesend
- André Stein + Sebastian Wiesendahl
- - William + + + svenyonson
- William Desportes + Steve Johnson
-
- - omarc1492/ + + + stonemaster
- omarc1492 + André Stein
- - Christian + + + omarc1492
- Christian Glahn + Null
- - Marek + + + phish108
- Marek Walczak + Christian Glahn
- - Kai + + + mwlczk
- Kai Ren + Marek Walczak
- - Kyle + + + tyranron
- Kyle Ondy + Kai Ren
- - Michael/ + + + KyleOndy
- Michael + Kyle Ondy
-
- - lukas/ + + + MichaelSp
- lukas + Michael
- - Sascha + + + mindrunner
- Sascha Scandella + Lukas
- - Lukáš + + + m-a-v
- Lukáš Vasek + Sascha Scandella
- - Andreas + + + bilak
- Andreas Perhab + Lukáš Vasek
- - vortex852456/ + + + vortex852456
- vortex852456 + Null
- - Christian + + + chris54721
- Christian Grasso + Christian Grasso
-
- - Hans-Cees + + + hanscees
- Hans-Cees Speel + Hans-Cees Speel
- - Jack + + + jrpear
- Jack Pearson + Jack Pearson
- - Dashamir + + + dashohoxha
- Dashamir Hoxha + Dashamir Hoxha
- - GAVARD + + + egavard
- GAVARD Ewann + GAVARD Ewann
- - Jack + + + mathuin
- Jack Twilley + Jack Twilley
- - Luke + + + jamebus
- Luke Cyca + James
-
- - Oleg + + + lukecyca
- Oleg Kainov + Luke Cyca
- - Robert + + + okainov
- Robert Dolca + Oleg Kainov
- - Thomas + + + robertdolca
- Thomas Kilian + Robert Dolca
- - Tobias + + + kiliant
- Tobias Rittig + Thomas Kilian
- - akmet/ + + + diiigle
- akmet + Tobias Rittig
- - Arne + + + akmet
- Arne Kepp + Akmet
-
- - Dennis + + + arneke
- Dennis Stumm + Arne Kepp
- - Moritz + + + dennis95stumm
- Moritz Marquardt + Dennis Stumm
- - pyy/ + + + moqmar
- pyy + Moritz Marquardt
- - Anne/ + + + pyy
- Anne + Null
- - Birkenstab/ + + + voordev
- Birkenstab + Anne
- - Brandon + + + Birkenstab
- Brandon Schmitt + Null
-
- - Cédric + + + BrandonSchmitt
- Cédric Laubacher + Brandon Schmitt
- - GrupoCITEC/ + + + Starbix
- GrupoCITEC + Cédric Laubacher
- - Jairo + + + citec
- Jairo Llopis + GrupoCITEC
- - James/ + + + yajo
- James + Jairo Llopis
- - Jarrod + + + MakerMatrix
- Jarrod Smith + Jarrod Smith
- - Patrizio + + + pbek
- Patrizio Bekerle + Patrizio Bekerle
-
- - Rubytastic2/ + + + Rubytastic2
- Rubytastic2 + Null
- - Semir + + + analogue
- Semir Patel + Semir Patel
- - Wolfgang + + + weo
- Wolfgang Ocker + Wolfgang Ocker
- - Zehir/ + + + Zehir
- Zehir + Zehir
- - guardiande/ + + + guardiande
- guardiande + Null
- - kamuri/ + + + kamuri
- kamuri + Null
-
- - davidszp/ + + + davidszp
- davidszp + Null
- - Andreas + + + andreasgerstmayr
- Andreas Gerstmayr + Andreas Gerstmayr
- - Marko + + + mjung
- Marko J + Marko J
- - Michael + + + m-schmoock
- Michael Schmoock + Michael Schmoock
- - VanVan/ + + + VanVan
- VanVan + Null
- - Alexander + + + elbracht
- Alexander Elbracht + Alexander Elbracht
-
- - Amin + + + aminvakil
- Amin Vakil + Amin Vakil
- - Andrew + + + andrewlow
- Andrew Low + Andrew Low
- - Ask + + + abh
- Ask Bjørn Hansen + Ask Bjørn Hansen
- - Ben/ + + + ubenmackin
- Ben + Ben
- - Christian + + + craue
- Christian Raue + Christian Raue
- - Daniel + + + danielpanteleit
- Daniel Panteleit + Daniel Panteleit
-
- - Darren + + + dmcgrandle
- Darren McGrandle + Darren McGrandle
- - Dominik + + + theomega
- Dominik Bruhn + Dominik Bruhn
- - DuncanvR/ + + + DuncanvR
- DuncanvR + Null
- - Emanuele + + + emazzotta
- Emanuele Mazzotta + Emanuele Mazzotta
- - FL42/ + + + fl42
- FL42 + FL42
- - Guillaume + + + ipernet
- Guillaume Simon + Guillaume Simon
-
- - Ikko + + + H4R0
- Ikko Eltociear Ashimine + Null
- - James + + + eltociear
- James Fryer + Ikko Eltociear Ashimine
- - Millaguie/ + + + jamesfryer
- Millaguie + James Fryer
- - Jeremy + + + millaguie
- Jeremy Shipman + Millaguie
- - Jonas + + + jedateach
- Jonas Kalderstam + Jeremy Shipman
- - Louis/ + + + spacecowboy
- Louis + Jonas Kalderstam
-
- - martinwepner/ + + + artonge
- martinwepner + Louis
- - Michael + + + martinwepner
- Michael Als + Null
- - Morgan + + + nueaf
- Morgan Kesler + Michael Als
- - Pablo + + + keslerm
- Pablo Castorino + Morgan Kesler
- - Philipp + + + castorinop
- Philipp Fruck + Pablo Castorino
- - Rainer + + + p-fruck
- Rainer Rillke + Philipp Fruck
-
- - Bob + + + Rillke
- Bob Gregor + Rainer Rillke
- - r-pufky/ + + + reneploetz
- r-pufky + René Plötz
- - andymel/ + + + bobbravo2
- andymel + Bob Gregor
- - bigpigeon/ + + + r-pufky
- bigpigeon + Robert Pufky
- - engelant/ + + + vincentDcmps
- engelant + Vincent Ducamps
- - j-marz/ + + + andymel123
- j-marz + Andymel
-
- - lokipo/ + + + bigpigeon
- lokipo + Bigpigeon
- - msheakoski/ + + + engelant
- msheakoski + Null
- - Felix/ + + + j-marz
- Felix + Null
- - Leon + + + lokipo
- Leon Busch-George + Null
- - Marius + + + msheakoski
- Marius Panneck + Null
- - Thomas + + + GoliathLabs
- Thomas Willems + Felix
-
- - 0xflotus/ + + + yogo1212
- 0xflotus + Leon Busch-George
- - Ivan + + + mpanneck
- Ivan Fokeev + Marius Panneck
- - 20th/ + + + willtho89
- 20th + Thomas Willems
- - 2b/ + + + tbutter
- 2b + Thomas Butter
- - Max:/ + + + 0xflotus
- Max: + 0xflotus
- - Achim + + + ifokeev
- Achim Christ + Johan Fokeev
-
- - Adrian + + + 20th
- Adrian Pistol + Null
- - Alexander + + + 2b
- Alexander Kachkaev + Null
- - Alexander + + + askz
- Alexander Neu + Max:
- - Bedniakov + + + acch
- Bedniakov Aleksei + Achim Christ
- - Andreas + + + vifino
- Andreas Egli + Adrian Pistol
- - Andrew + + + kachkaev
- Andrew Cornford + Alexander Kachkaev
-
- - Andrey + + + alexanderneu
- Andrey Likhodievskiy + Alexander Neu
- - Arash + + + ch3sh1r
- Arash Fatahzade + Bedniakov Aleksei
- - Arthur + + + eglia
- Arthur Outhenin-Chalandre + Andreas Egli
- - Astro/ + + + groupmsl
- Astro + Andrew Cornford
- - Benedict + + + green-anger
- Benedict Endemann + Andrey Likhodievskiy
- - Bogdan/ + + + iRhonin
- Bogdan + Arash Fatahzade
-
- - Charles + + + MrFreezeex
- Charles Harris + Arthur Outhenin-Chalandre
- - Christian + + + arunvc
- Christian Musa + Arun
- - Christoph/ + + + astrocket
- Christoph + Astro
- - Claus + + + baxerus
- Claus Beerta + Benedict Endemann
- - Damian + + + spock
- Damian Moore + Bogdan
- - espitall/ + + + erdos4d
- espitall + Charles Harris
-
- - Daniel + + + crash7
- Daniel Karski + Christian Musa
- - Daniele + + + auchri
- Daniele Bellavista + Christoph
- - Daniël + + + arkanovicz
- Daniël van den Berg + Claude Brisson
- - Dingoz/ + + + CBeerta
- Dingoz + Claus Beerta
- - Dmitry + + + damianmoore
- Dmitry R. + Damian Moore
- - Dorian + + + espitall
- Dorian Ayllón + Null
-
- - Edmond + + + dkarski
- Edmond Varga + Daniel Karski
- - Eduard + + + dbellavista
- Eduard Knysh + Daniele Bellavista
- - Elisei + + + danielvandenberg95
- Elisei Roca + Daniël Van Den Berg
- - Erick + + + mlatorre31
- Erick Calder + Dingoz
- - Erik + + + mazzz1y
- Erik Brakkee + Dmitry R.
- - Huncode/ + + + aydodo
- Huncode + Dorian Ayllón
-
- - Florian/ + + + vedtam
- Florian + Edmond Varga
- - Florian + + + edvorg
- Florian Roks + Eduard Knyshov
- - Franz + + + eliroca
- Franz Keferböck + Elisei Roca
- - Frugan/ + + + ekkis
- Frugan + Erick Calder
- - Gabriel + + + ErikEngerd
- Gabriel Euzet + Erik Brakkee
- - Gabriel + + + huncode
- Gabriel Landais + Huncode
-
- - GiovanH/ + + + felixn
- GiovanH + Felix N
- - H4R0/ + + + flole
- H4R0 + Florian
- - Harry + + + froks
- Harry Youd + Florian Roks
- - Hugues + + + fkefer
- Hugues Granger + Franz Keferböck
- - Ian + + + frugan-it
- Ian Andrews + Frugan
- - Influencer/ + + + Marsu31
- Influencer + Gabriel Euzet
-
- - jcalfee/ + + + glandais
- jcalfee + Gabriel Landais
- - JS + + + GiovanH
- JS Légaré + GiovanH
- - Jeidnx/ + + + harryyoud
- Jeidnx + Harry Youd
- - JiLleON/ + + + HeySora
- JiLleON + HeySora
- - Jiří + + + sirgantrithon
- Jiří Kozlovský + Ian Andrews
- - jmccl/ + + + Influencer
- jmccl + Influencer
-
- - Jurek + + + jcalfee
- Jurek Barth + Null
- - JOnathan + + + init-js
- JOnathan duMonT + JS Légaré
- - Kaan/ + + + Jeidnx
- Kaan + Jeidnx
- - Karthik + + + JiLleON
- Karthik K + Null
- - KCrawley/ + + + jirislav
- KCrawley + Jiří Kozlovský
- - Khue + + + jsonn
- Khue Doan + Joerg Sonnenberger
-
- - Lars + + + jmccl
- Lars Pötter + Null
- - Leo + + + jurekbarth
- Leo Winter + Jurek Barth
- - Lin + + + JOduMonT
- Lin Han + JOnathan DuMonT
- - MadsRC/ + + + Kaan88
- MadsRC + Kaan
- - Mathieu + + + akkumar
- Mathieu Brunot + Karthik K
- - Maximilian + + + KCrawley
- Maximilian Hippler + Null
-
- - Michael + + + khuedoan
- Michael G. + Khue Doan
- - Michael + + + JustAnother1
- Michael Jensen + Lars Pötter
- - Michel + + + LeoWinterDE
- Michel Albert + Leo Winter
- - Mohammed + + + linhandev
- Mohammed Chotia + Lin Han
- - Mohammed + + + luke-
- Mohammed Noureldin + Lucas Bartholemy
- - Moritz + + + LucidityCrash
- Moritz Poldrack + Null
-
- - Naveen/ + + + MadsRC
- Naveen + MadsRC
- - Nicholas + + + madmath03
- Nicholas Pepper + Mathieu Brunot
- - Nick + + + maxemann96
- Nick Pappas + Maximilian Hippler
- - Nils + + + dragetd
- Nils Knappmeier + Michael G.
- - Olivier + + + michaeljensen
- Olivier Picquenot + Michael Jensen
- - Orville + + + exhuma
- Orville Q. Song + Michel Albert
-
- - Ovidiu + + + milas
- Ovidiu Predescu + Milas Bowman
- - Petar + + + mcchots
- Petar Šegina + Mohammed Chotia
- - Peter + + + MohammedNoureldin
- Peter Hartmann + Mohammed Noureldin
- - Pierre-Yves + + + mpldr
- Pierre-Yves Rofes + Moritz Poldrack
- - Remo + + + naveensrinivasan
- Remo E + Naveen
- - René + + + neuralp
- René Plötz + Nicholas Pepper
-
- - Roman + + + radicand
- Roman Seyffarth + Nick Pappas
- - Sam + + + nilshoell
- Sam Collins + Nils Höll
- - Scott + + + nknapp
- Scott Weldon + Nils Knappmeier
- - Sebastian + + + pcqnt
- Sebastian Straub + Olivier Picquenot
- - Serge + + + OrvilleQ
- Serge van den Boom + Orville Q. Song
- - Sergey + + + ovidiucp
- Sergey Nazaryev + Ovidiu Predescu
-
- - Shyim/ + + + mrPjer
- Shyim + Petar Šegina
- - Simon + + + peter-hartmann
- Simon J Mudd + Peter Hartmann
- - Simon + + + piwai
- Simon Schröter + Pierre-Yves Rofes
- - Stephan/ + + + remoe
- Stephan + Remo E
- - Stig + + + romansey
- Stig Otnes Kolstad + Roman Seyffarth
- - Sven + + + MightySCollins
- Sven Kauber + Sam Collins
-
- - Sylvain + + + 501st-alpha1
- Sylvain Benner + Scott Weldon
- - Sylvain + + + klamann
- Sylvain Dumont + Sebastian Straub
- - TechnicLab/ + + + svdb0
- TechnicLab + Serge Van Den Boom
- - Thomas + + + 3ap
- Thomas Schmit + Sergey Nazaryev
- - Tin/ + + + shyim
- Tin + Shyim
- - Torben + + + sjmudd
- Torben Weibert + Simon J Mudd
-
- - Toru + + + simonsystem
- Toru Hisai + Simon Schröter
- - Trangar/ + + + stephan-devop
- Trangar + Stephan
- - Twist235/ + + + stigok
- Twist235 + Stig Otnes Kolstad
- - Vasiliy + + + 5ven
- Vasiliy Gokoyev + Sven Kauber
- - Victoria + + + syl20bnr
- Victoria Brekenfeld + Sylvain Benner
- - Vilius/ + + + sylvaindumont
- Vilius + Sylvain Dumont
-
- - Wim/ + + + TechnicLab
- Wim + Null
- - Y.C.Huang/ + + + thomasschmit
- Y.C.Huang + Thomas Schmit
- - arcaine2/ + + + Thiritin
- arcaine2 + Tin
- - awb99/ + + + tweibert
- awb99 + Torben Weibert
- - brainkiller/ + + + torus
- brainkiller + Toru Hisai
- - cternes/ + + + VictorKoenders
- cternes + Trangar
-
- - dborowy/ + + + Twist235
- dborowy + Null
- - dimalo/ + + + k3it
- dimalo + Vasiliy Gokoyev
- - eleith/ + + + Drakulix
- eleith + Victoria Brekenfeld
- - helmutundarnold/ + + + vilisas
- helmutundarnold + Vilius
- - hnws/ + + + 42wim
- hnws + Wim
- - i-C-o-d-e-r/ + + + ShiriNmi1520
- i-C-o-d-e-r + Y.C.Huang
-
- - idaadi/ + + + allddd
- idaadi + Allddd
- - ixeft/ + + + arcaine2
- ixeft + Null
- - jjtt/ + + + awb99
- jjtt + Awb99
- - jose + + + brainkiller
- jose nazario + Null
- - landergate/ + + + cternes
- landergate + Null
- - magnus + + + dborowy
- magnus anderssen + Null
-
- - marios88/ + + + dimalo
- marios88 + Null
- - matrixes/ + + + eleith
- matrixes + Eleith
- - mchamplain/ + + + ghnp5
- mchamplain + Null
- - Jason + + + helmutundarnold
- Jason Miller + Null
- - mplx/ + + + hnws
- mplx + Null
- - odinis/ + + + i-C-o-d-e-r
- odinis + Null
-
- - okami/ + + + idaadi
- okami + Null
- - olaf-mandel/ + + + ixeft
- olaf-mandel + Null
- - ontheair81/ + + + jjtt
- ontheair81 + Null
- - pravynandas/ + + + paralax
- pravynandas + Jose Nazario
- - presocratics/ + + + jpduyx
- presocratics + Null
- - rhyst/ + + + landergate
- rhyst + Null
-
- - schnippl0r/ + + + callmemagnus
- schnippl0r + Magnus Anderssen
- - smargold476/ + + + marios88
- smargold476 + Null
- - sportshead/ + + + matrixes
- sportshead + Null
- - squash/ + + + mchamplain
- squash + Mchamplain
- - strarsis/ + + + millerjason
- strarsis + Jason Miller
- - tamueller/ + + + mplx
- tamueller + Null
-
- - vivacarvajalito/ + + + odinis
- vivacarvajalito + Null
- - wolkenschieber/ + + + okamidash
- wolkenschieber + Okami
- - worldworm/ + + + olaf-mandel
- worldworm + Null
+ + ontheair81 +
+ Null +
+
+ + pravynandas +
+ Null +
+
+ + presocratics +
+ Null +
+
+ + rhyst +
+ Null +
+
+ + rmlhuk +
+ Null +
+
+ + rriski +
+ Null +
+
+ + schnippl0r +
+ Null +
+
+ + smargold476 +
+ Null +
+
+ + sportshead +
+ Null +
+
+ + squash +
+ Null +
+
+ + strarsis +
+ Null +
+
+ + tamueller +
+ Null +
+
+ + vivacarvajalito +
+ Null +
+
+ + wligtenberg +
+ Null +
+
+ + wolkenschieber +
+ Null +
+
+ + worldworm +
+ Null +
+
+ ## Further Contributors @@ -1898,8 +1972,4 @@ Also thanks goes to these wonderful people, that have contributed in various oth This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! -____ - -Note: - -We started using [all-contributors](https://github.com/all-contributors/all-contributors) in July 2021. We will add contributors with their future PRs or Issues. Code contributions are added automatically. If you are [one of the 200+](https://github.com/docker-mailserver/docker-mailserver/graphs/contributors) that contributed to the project in the past and would like to see your name here too, please reach out! +Note: We started using [all-contributors](https://github.com/all-contributors/all-contributors) in July 2021. We will add contributors with their future PRs or Issues. Code contributions are added automatically. If you are [one of the 200+](https://github.com/docker-mailserver/docker-mailserver/graphs/contributors) that contributed to the project in the past and would like to see your name here too, please reach out! diff --git a/docs/content/config/security/rspamd.md b/docs/content/config/security/rspamd.md index 94be2db9..5867b1e8 100644 --- a/docs/content/config/security/rspamd.md +++ b/docs/content/config/security/rspamd.md @@ -107,11 +107,11 @@ DMS brings sane default settings for Rspamd. They are located at `/etc/rspamd/lo !!! question "What is [`docker-data/dms/config/`][docs-dms-config-volume]?" -If you want to overwrite the default settings and / or provide your own settings, you can place files at `docker-data/dms/config/rspamd/override.d/` (a directory that is linked to `/etc/rspamd/override.d/`, if it exists) to override Rspamd and DMS default settings. This directory will not do a complete file override, but a [forced override of the specific settings in that file][rspamd-docs-override-dir]. +If you want to overwrite the default settings and / or provide your own settings, you can place files at `docker-data/dms/config/rspamd/override.d/`. Files from this directory are copied to `/etc/rspamd/override.d/` during startup. These files [forcibly override][rspamd-docs-override-dir] Rspamd and DMS default settings. !!! warning "Clashing Overrides" - Note that when also [using the `rspamd-commands` file](#with-the-help-of-a-custom-file), files in `override.d` may be overwritten in case you adjust them manually and with the help of the file. + Note that when also [using the `custom-commands.conf` file](#with-the-help-of-a-custom-file), files in `override.d` may be overwritten in case you adjust them manually and with the help of the file. [rspamd-docs-override-dir]: https://www.rspamd.com/doc/faq.html#what-are-the-locald-and-overrided-directories [docs-dms-config-volume]: ../../faq.md#what-about-the-docker-datadmsconfig-directory diff --git a/target/bin/addalias b/target/bin/addalias index 60f8aa03..9bcb6cec 100755 --- a/target/bin/addalias +++ b/target/bin/addalias @@ -33,6 +33,9 @@ ${ORANGE}EXAMPLES${RESET} ${LWHITE}./setup.sh alias add alias@example.com recipient@example.com${RESET} Add the alias 'alias@example.com' for the mail account 'recipient@example.com'. + ${LWHITE}./setup.sh alias add alias@example.com 'recipient@example.com, another-recipient@example.com'${RESET} + Multiple recipients are separated by comma. + ${ORANGE}EXIT STATUS${RESET} Exit status is 0 if command was successful. If wrong arguments are provided or arguments contain errors, the script will exit early with exit status 1. diff --git a/target/bin/rspamd-dkim b/target/bin/rspamd-dkim index de7129de..357c2a9c 100755 --- a/target/bin/rspamd-dkim +++ b/target/bin/rspamd-dkim @@ -27,9 +27,10 @@ ${ORANGE}DESCRIPTION${RESET} ${ORANGE}OPTIONS${RESET} ${BLUE}Generic Program Information${RESET} - -v Enable verbose logging (setting the log level to 'debug'). - -vv Enable very verbose logging (setting the log level to 'trace'). - help Print the usage information. + -f | --force Overwrite existing files if there are any + -v Enable verbose logging (setting the log level to 'debug'). + -vv Enable very verbose logging (setting the log level to 'trace'). + help Print the usage information. ${BLUE}Configuration adjustments${RESET} keytype Set the type of key you want to use. @@ -69,6 +70,7 @@ function __do_as_rspamd_user() { } function _parse_arguments() { + FORCE=0 KEYTYPE='rsa' KEYSIZE='2048' SELECTOR='mail' @@ -112,6 +114,12 @@ function _parse_arguments() { exit 0 ;; + ( '-f' | '--force' ) + FORCE=1 + shift 1 + continue + ;; + ( '-vv' ) # shellcheck disable=SC2034 LOG_LEVEL='trace' @@ -132,30 +140,36 @@ function _parse_arguments() { __usage _exit_with_error "Unknown option(s) '${1}' ${2:+"and '${2}'"}" ;; - esac shift 2 done + return 0 +} + +function _preflight_checks() { if [[ ${KEYTYPE} == 'ed25519' ]] && [[ ${KEYSIZE} -ne 2048 ]]; then _exit_with_error "Chosen keytype does not accept the 'keysize' argument" fi - return 0 + if [[ ! -d /tmp/docker-mailserver ]]; then + _log 'warn' "The directory '/tmp/docker-mailserver' does not seem to be mounted by a volume - the Rspamd (DKIM) configuration will not be persisted" + fi + + _rspamd_get_envs + + mkdir -p "${RSPAMD_DMS_DKIM_D}" "${RSPAMD_DMS_OVERRIDE_D}" + chown _rspamd:_rspamd "${RSPAMD_DMS_DKIM_D}" } function _create_keys() { - # Note: Variables not marked with `local` are used - # in other functions (after this function was called). - BASE_DIR='/tmp/docker-mailserver/rspamd/dkim' - if [[ ${KEYTYPE} == 'rsa' ]]; then - local BASE_FILE_NAME="${BASE_DIR}/${KEYTYPE}-${KEYSIZE}-${SELECTOR}-${DOMAIN}" + local BASE_FILE_NAME="${RSPAMD_DMS_DKIM_D}/${KEYTYPE}-${KEYSIZE}-${SELECTOR}-${DOMAIN}" KEYTYPE_OPTIONS=('-b' "${KEYSIZE}") _log 'info' "Creating DKIM keys of type '${KEYTYPE}' and length '${KEYSIZE}' with selector '${SELECTOR}' for domain '${DOMAIN}'" else - local BASE_FILE_NAME="${BASE_DIR}/${KEYTYPE}-${SELECTOR}-${DOMAIN}" + local BASE_FILE_NAME="${RSPAMD_DMS_DKIM_D}/${KEYTYPE}-${SELECTOR}-${DOMAIN}" KEYTYPE_OPTIONS=('-t' "${KEYTYPE}") _log 'info' "Creating DKIM keys of type '${KEYTYPE}' with selector '${SELECTOR}' for domain '${DOMAIN}'" fi @@ -164,8 +178,15 @@ function _create_keys() { PUBLIC_KEY_DNS_FILE="${BASE_FILE_NAME}.public.dns.txt" PRIVATE_KEY_FILE="${BASE_FILE_NAME}.private.txt" - mkdir -p "${BASE_DIR}" - chown _rspamd:_rspamd "${BASE_DIR}" + if [[ -f ${PUBLIC_KEY_FILE} ]] || [[ -f ${PUBLIC_KEY_DNS_FILE} ]] || [[ -f ${PRIVATE_KEY_FILE} ]]; then + if [[ ${FORCE} -eq 0 ]]; then + _log 'error' "Not overwriting existing files (use '--force' to overwrite existing files)" + exit 1 + else + _log 'info' "Overwriting existing files as the '--force' option was supplied" + rm "${PUBLIC_KEY_FILE}" "${PUBLIC_KEY_DNS_FILE}" "${PRIVATE_KEY_FILE}" + fi + fi # shellcheck disable=SC2310 if __do_as_rspamd_user rspamadm \ @@ -186,8 +207,8 @@ function _create_keys() { function _check_permissions() { # shellcheck disable=SC2310 - if ! __do_as_rspamd_user ls "${BASE_DIR}" >/dev/null; then - _log 'warn' "The Rspamd user ('_rspamd') seems to be unable to list files in the keys directory ('${BASE_DIR}') - Rspamd may experience permission errors later" + if ! __do_as_rspamd_user ls "${RSPAMD_DMS_DKIM_D}" >/dev/null; then + _log 'warn' "The Rspamd user ('_rspamd') seems to be unable to list files in the keys directory ('${RSPAMD_DMS_DKIM_D}') - Rspamd may experience permission errors later" elif ! __do_as_rspamd_user cat "${PRIVATE_KEY_FILE}" >/dev/null; then _log 'warn' "The Rspamd user ('_rspamd') seems to be unable to read the private key file - Rspamd may experience permission errors later" else @@ -196,11 +217,11 @@ function _check_permissions() { } function _setup_default_signing_conf() { - local DEFAULT_CONFIG_FILE='/etc/rspamd/override.d/dkim_signing.conf' + local DEFAULT_CONFIG_FILE="${RSPAMD_DMS_OVERRIDE_D}/dkim_signing.conf" if [[ -f ${DEFAULT_CONFIG_FILE} ]]; then - _log 'debug' "'${DEFAULT_CONFIG_FILE}' exists, not supplying a default" + _log 'info' "'${DEFAULT_CONFIG_FILE}' exists, not supplying a default ('--force' does not overwrite this file, manual adjustment required)" else - _log 'info' "Supplying a default configuration ('${DEFAULT_CONFIG_FILE}')" + _log 'info' "Supplying a default configuration (to '${DEFAULT_CONFIG_FILE}')" cat >"${DEFAULT_CONFIG_FILE}" << EOF # documentation: https://rspamd.com/doc/modules/dkim_signing.html @@ -225,7 +246,15 @@ domain { } EOF - chown _rspamd:_rspamd "${DEFAULT_CONFIG_FILE}" + + # We copy here immediately in order to not rely on the changedetector - this way, users + # can immediately use the new keys. The file should not already exist in ${RSPAMD_OVERRIDE_D} + # since it would have been copied already. + cp "${DEFAULT_CONFIG_FILE}" "${RSPAMD_OVERRIDE_D}/dkim_signing.conf" + chown _rspamd:_rspamd "${DEFAULT_CONFIG_FILE}" "${RSPAMD_OVERRIDE_D}/dkim_signing.conf" + + _log 'debug' 'Restarting Rspamd as initial DKIM configuration was suppplied' + supervisorctl restart rspamd fi } @@ -254,6 +283,7 @@ function _final_steps() { _obtain_hostname_and_domainname _require_n_parameters_or_print_usage 0 "${@}" _parse_arguments "${@}" +_preflight_checks _create_keys _check_permissions _setup_default_signing_conf diff --git a/target/postfix/main.cf b/target/postfix/main.cf index 518ad326..405dc0fb 100644 --- a/target/postfix/main.cf +++ b/target/postfix/main.cf @@ -54,6 +54,7 @@ smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_una smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination, reject_unauth_pipelining, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, reject_unknown_recipient_domain smtpd_client_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, reject_unauth_pipelining smtpd_sender_restrictions = $dms_smtpd_sender_restrictions +smtpd_discard_ehlo_keywords = silent-discard, dsn disable_vrfy_command = yes # Custom defined parameters for DMS: diff --git a/target/postfix/master.cf b/target/postfix/master.cf index 6f8877f6..e5b955a4 100644 --- a/target/postfix/master.cf +++ b/target/postfix/master.cf @@ -24,6 +24,7 @@ submission inet n - n - - smtpd -o smtpd_client_restrictions=permit_sasl_authenticated,reject -o smtpd_relay_restrictions=permit_sasl_authenticated,reject -o smtpd_sender_restrictions=$mua_sender_restrictions + -o smtpd_discard_ehlo_keywords= -o milter_macro_daemon_name=ORIGINATING -o cleanup_service_name=sender-cleanup @@ -37,6 +38,7 @@ submissions inet n - n - - smtpd -o smtpd_client_restrictions=permit_sasl_authenticated,reject -o smtpd_relay_restrictions=permit_sasl_authenticated,reject -o smtpd_sender_restrictions=$mua_sender_restrictions + -o smtpd_discard_ehlo_keywords= -o milter_macro_daemon_name=ORIGINATING -o cleanup_service_name=sender-cleanup diff --git a/target/scripts/check-for-changes.sh b/target/scripts/check-for-changes.sh index a8cdeb68..66417c09 100755 --- a/target/scripts/check-for-changes.sh +++ b/target/scripts/check-for-changes.sh @@ -21,6 +21,10 @@ source /etc/dms-settings # usage with DMS_HOSTNAME, which should remove the need to call this: _obtain_hostname_and_domainname +# This is a helper to properly set all Rspamd-related environment variables +# correctly and in one place. +_rspamd_get_envs + # verify checksum file exists; must be prepared by start-mailserver.sh if [[ ! -f ${CHKSUM_FILE} ]]; then _exit_with_error "'${CHKSUM_FILE}' is missing" 0 @@ -49,6 +53,7 @@ function _check_for_changes() { # Handle any changes _ssl_changes _postfix_dovecot_changes + _rspamd_changes _log_with_date 'debug' 'Reloading services due to detected changes' @@ -174,6 +179,33 @@ function _ssl_changes() { # They presently have no special handling other than to trigger a change that will restart Postfix/Dovecot. } +function _rspamd_changes() { + # RSPAMD_DMS_D='/tmp/docker-mailserver/rspamd' + if [[ ${CHANGED} =~ ${RSPAMD_DMS_D}/.* ]]; then + + # "${RSPAMD_DMS_D}/override.d" + if [[ ${CHANGED} =~ ${RSPAMD_DMS_OVERRIDE_D}/.* ]]; then + _log_with_date 'trace' 'Rspamd - Copying configuration overrides' + rm "${RSPAMD_OVERRIDE_D}"/* + cp "${RSPAMD_DMS_OVERRIDE_D}"/* "${RSPAMD_OVERRIDE_D}" + fi + + # "${RSPAMD_DMS_D}/custom-commands.conf" + if [[ ${CHANGED} =~ ${RSPAMD_DMS_CUSTOM_COMMANDS_F} ]]; then + _log_with_date 'trace' 'Rspamd - Generating new configuration from custom commands' + _rspamd_handle_user_modules_adjustments + fi + + # "${RSPAMD_DMS_D}/dkim" + if [[ ${CHANGED} =~ ${RSPAMD_DMS_DKIM_D} ]]; then + _log_with_date 'trace' 'Rspamd - DKIM files updated' + fi + + _log_with_date 'debug' 'Rspamd configuration has changed - restarting service' + supervisorctl restart rspamd + fi +} + while true; do _check_for_changes sleep 2 diff --git a/target/scripts/helpers/change-detection.sh b/target/scripts/helpers/change-detection.sh index e396bfe2..08f6906c 100644 --- a/target/scripts/helpers/change-detection.sh +++ b/target/scripts/helpers/change-detection.sh @@ -40,6 +40,12 @@ function _monitored_files_checksums() { "${DMS_DIR}/dovecot-quotas.cf" "${DMS_DIR}/dovecot-masters.cf" ) + + # Check whether Rspamd is used and if so, monitor it's changes as well + if [[ ${ENABLE_RSPAMD} -eq 1 ]] && [[ -d ${RSPAMD_DMS_D} ]]; then + readarray -d '' STAGING_FILES_RSPAMD < <(find "${RSPAMD_DMS_D}" -type f -name "*.sh" -print0) + STAGING_FILES+=("${STAGING_FILES_RSPAMD[@]}") + fi fi # SSL certs: diff --git a/target/scripts/helpers/index.sh b/target/scripts/helpers/index.sh index 8d876739..0d77c9c4 100644 --- a/target/scripts/helpers/index.sh +++ b/target/scripts/helpers/index.sh @@ -16,6 +16,7 @@ function _import_scripts() { source "${PATH_TO_SCRIPTS}/network.sh" source "${PATH_TO_SCRIPTS}/postfix.sh" source "${PATH_TO_SCRIPTS}/relay.sh" + source "${PATH_TO_SCRIPTS}/rspamd.sh" source "${PATH_TO_SCRIPTS}/ssl.sh" source "${PATH_TO_SCRIPTS}/utils.sh" diff --git a/target/scripts/helpers/rspamd.sh b/target/scripts/helpers/rspamd.sh new file mode 100644 index 00000000..868e3d3a --- /dev/null +++ b/target/scripts/helpers/rspamd.sh @@ -0,0 +1,105 @@ +#! /bin/bash + +# shellcheck disable=SC2034 # VAR appears unused. + +function _rspamd_get_envs() { + readonly RSPAMD_LOCAL_D='/etc/rspamd/local.d' + readonly RSPAMD_OVERRIDE_D='/etc/rspamd/override.d' + + readonly RSPAMD_DMS_D='/tmp/docker-mailserver/rspamd' + readonly RSPAMD_DMS_DKIM_D="${RSPAMD_DMS_D}/dkim" + readonly RSPAMD_DMS_OVERRIDE_D="${RSPAMD_DMS_D}/override.d" + + readonly RSPAMD_DMS_CUSTOM_COMMANDS_F="${RSPAMD_DMS_D}/custom-commands.conf" +} + +# Parses `RSPAMD_DMS_CUSTOM_COMMANDS_F` and executed the directives given by the file. +# To get a detailed explanation of the commands and how the file works, visit +# https://docker-mailserver.github.io/docker-mailserver/latest/config/security/rspamd/#with-the-help-of-a-custom-file +function _rspamd_handle_user_modules_adjustments() { + # Adds an option with a corresponding value to a module, or, in case the option + # is already present, overwrites it. + # + # @param ${1} = file name in ${RSPAMD_OVERRIDE_D}/ + # @param ${2} = module name as it should appear in the log + # @param ${3} = option name in the module + # @param ${4} = value of the option + # + # ## Note + # + # While this function is currently bound to the scope of `_rspamd_handle_user_modules_adjustments`, + # it is written in a versatile way (taking 4 arguments instead of assuming `ARGUMENT2` / `ARGUMENT3` + # are set) so that it may be used elsewhere if needed. + function __add_or_replace() { + local MODULE_FILE=${1:?Module file name must be provided} + local MODULE_LOG_NAME=${2:?Module log name must be provided} + local OPTION=${3:?Option name must be provided} + local VALUE=${4:?Value belonging to an option must be provided} + # remove possible whitespace at the end (e.g., in case ${ARGUMENT3} is empty) + VALUE=${VALUE% } + local FILE="${RSPAMD_OVERRIDE_D}/${MODULE_FILE}" + + readonly MODULE_FILE MODULE_LOG_NAME OPTION VALUE FILE + + [[ -f ${FILE} ]] || touch "${FILE}" + + if grep -q -E "${OPTION}.*=.*" "${FILE}"; then + __rspamd__log 'trace' "Overwriting option '${OPTION}' with value '${VALUE}' for ${MODULE_LOG_NAME}" + sed -i -E "s|([[:space:]]*${OPTION}).*|\1 = ${VALUE};|g" "${FILE}" + else + __rspamd__log 'trace' "Setting option '${OPTION}' for ${MODULE_LOG_NAME} to '${VALUE}'" + echo "${OPTION} = ${VALUE};" >>"${FILE}" + fi + } + + # We check for usage of the previous location of the commands file. + # TODO This can be removed after the release of v14.0.0. + local RSPAMD_DMS_CUSTOM_COMMANDS_F_OLD="${RSPAMD_DMS_D}-modules.conf" + readonly RSPAMD_DMS_CUSTOM_COMMANDS_F_OLD + if [[ -f ${RSPAMD_DMS_CUSTOM_COMMANDS_F_OLD} ]]; then + _dms_panic__general "Old custom command file location '${RSPAMD_DMS_CUSTOM_COMMANDS_F_OLD}' is deprecated (use '${RSPAMD_DMS_CUSTOM_COMMANDS_F}' now)" 'Rspamd setup' + fi + + if [[ -f "${RSPAMD_DMS_CUSTOM_COMMANDS_F}" ]]; then + __rspamd__log 'debug' "Found file '${RSPAMD_DMS_CUSTOM_COMMANDS_F}' - parsing and applying it" + + local COMMAND ARGUMENT1 ARGUMENT2 ARGUMENT3 + while read -r COMMAND ARGUMENT1 ARGUMENT2 ARGUMENT3; do + case "${COMMAND}" in + ('disable-module') + __rspamd__helper__enable_disable_module "${ARGUMENT1}" 'false' 'override' + ;; + + ('enable-module') + __rspamd__helper__enable_disable_module "${ARGUMENT1}" 'true' 'override' + ;; + + ('set-option-for-module') + __add_or_replace "${ARGUMENT1}.conf" "module '${ARGUMENT1}'" "${ARGUMENT2}" "${ARGUMENT3}" + ;; + + ('set-option-for-controller') + __add_or_replace 'worker-controller.inc' 'controller worker' "${ARGUMENT1}" "${ARGUMENT2} ${ARGUMENT3}" + ;; + + ('set-option-for-proxy') + __add_or_replace 'worker-proxy.inc' 'proxy worker' "${ARGUMENT1}" "${ARGUMENT2} ${ARGUMENT3}" + ;; + + ('set-common-option') + __add_or_replace 'options.inc' 'common options' "${ARGUMENT1}" "${ARGUMENT2} ${ARGUMENT3}" + ;; + + ('add-line') + __rspamd__log 'trace' "Adding complete line to '${ARGUMENT1}'" + echo "${ARGUMENT2}${ARGUMENT3+ ${ARGUMENT3}}" >>"${RSPAMD_OVERRIDE_D}/${ARGUMENT1}" + ;; + + (*) + __rspamd__log 'warn' "Command '${COMMAND}' is invalid" + continue + ;; + esac + done < <(_get_valid_lines_from_file "${RSPAMD_DMS_CUSTOM_COMMANDS_F}") + fi +} diff --git a/target/scripts/startup/setup.d/security/rspamd.sh b/target/scripts/startup/setup.d/security/rspamd.sh index 4199b077..19ce75dc 100644 --- a/target/scripts/startup/setup.d/security/rspamd.sh +++ b/target/scripts/startup/setup.d/security/rspamd.sh @@ -1,12 +1,17 @@ #!/bin/bash -# Function called during global setup to handle the complete setup of Rspamd. +# This file is executed during startup of DMS. Hence, the `index.sh` helper has already +# been sourced, and thus, all helper functions from `rspamd.sh` are available. + +# Function called during global setup to handle the complete setup of Rspamd. Functions +# with a single `_` prefix are sourced from the `rspamd.sh` helper. function _setup_rspamd() { if _env_var_expect_zero_or_one 'ENABLE_RSPAMD' && [[ ${ENABLE_RSPAMD} -eq 1 ]]; then _log 'debug' 'Enabling and configuring Rspamd' __rspamd__log 'trace' '---------- Setup started ----------' - __rspamd__run_early_setup_and_checks # must run first + _rspamd_get_envs # must run first + __rspamd__run_early_setup_and_checks # must run second __rspamd__setup_logfile __rspamd__setup_redis __rspamd__setup_postfix @@ -16,7 +21,7 @@ function _setup_rspamd() { __rspamd__setup_greylisting __rspamd__setup_hfilter_group __rspamd__setup_check_authenticated - __rspamd__handle_user_modules_adjustments # must run last + _rspamd_handle_user_modules_adjustments # must run last __rspamd__log 'trace' '---------- Setup finished ----------' else @@ -64,25 +69,11 @@ EOF # Run miscellaneous early setup tasks and checks, such as creating files needed at runtime # or checking for other anti-spam/anti-virus software. function __rspamd__run_early_setup_and_checks() { - # Note: Variables not marked with `local` are - # used in other functions as well. - readonly RSPAMD_LOCAL_D='/etc/rspamd/local.d' - readonly RSPAMD_OVERRIDE_D='/etc/rspamd/override.d' - readonly RSPAMD_DMS_D='/tmp/docker-mailserver/rspamd' - - local RSPAMD_DMS_OVERRIDE_D="${RSPAMD_DMS_D}/override.d/" - readonly RSPAMD_DMS_OVERRIDE_D - mkdir -p /var/lib/rspamd/ : >/var/lib/rspamd/stats.ucl if [[ -d ${RSPAMD_DMS_OVERRIDE_D} ]]; then - __rspamd__log 'debug' "Found directory '${RSPAMD_DMS_OVERRIDE_D}' - linking it to '${RSPAMD_OVERRIDE_D}'" - if rmdir "${RSPAMD_OVERRIDE_D}" 2>/dev/null; then - ln -s "${RSPAMD_DMS_OVERRIDE_D}" "${RSPAMD_OVERRIDE_D}" - else - __rspamd__log 'warn' "Could not remove '${RSPAMD_OVERRIDE_D}' (not empty?; not a directory?; did you restart properly?) - not linking '${RSPAMD_DMS_OVERRIDE_D}'" - fi + cp "${RSPAMD_DMS_OVERRIDE_D}"/* "${RSPAMD_OVERRIDE_D}" fi if [[ ${ENABLE_AMAVIS} -eq 1 ]] || [[ ${ENABLE_SPAMASSASSIN} -eq 1 ]]; then @@ -303,98 +294,3 @@ function __rspamd__setup_check_authenticated() { "${MODULE_FILE}" fi } - -# Parses `RSPAMD_CUSTOM_COMMANDS_FILE` and executed the directives given by the file. -# To get a detailed explanation of the commands and how the file works, visit -# https://docker-mailserver.github.io/docker-mailserver/edge/config/security/rspamd/#with-the-help-of-a-custom-file -function __rspamd__handle_user_modules_adjustments() { - # Adds an option with a corresponding value to a module, or, in case the option - # is already present, overwrites it. - # - # @param ${1} = file name in ${RSPAMD_OVERRIDE_D}/ - # @param ${2} = module name as it should appear in the log - # @param ${3} = option name in the module - # @param ${4} = value of the option - # - # ## Note - # - # While this function is currently bound to the scope of `__rspamd__handle_user_modules_adjustments`, - # it is written in a versatile way (taking 4 arguments instead of assuming `ARGUMENT2` / `ARGUMENT3` - # are set) so that it may be used elsewhere if needed. - function __add_or_replace() { - local MODULE_FILE=${1:?Module file name must be provided} - local MODULE_LOG_NAME=${2:?Module log name must be provided} - local OPTION=${3:?Option name must be provided} - local VALUE=${4:?Value belonging to an option must be provided} - # remove possible whitespace at the end (e.g., in case ${ARGUMENT3} is empty) - VALUE=${VALUE% } - local FILE="${RSPAMD_OVERRIDE_D}/${MODULE_FILE}" - - readonly MODULE_FILE MODULE_LOG_NAME OPTION VALUE FILE - - [[ -f ${FILE} ]] || touch "${FILE}" - - if grep -q -E "${OPTION}.*=.*" "${FILE}"; then - __rspamd__log 'trace' "Overwriting option '${OPTION}' with value '${VALUE}' for ${MODULE_LOG_NAME}" - sed -i -E "s|([[:space:]]*${OPTION}).*|\1 = ${VALUE};|g" "${FILE}" - else - __rspamd__log 'trace' "Setting option '${OPTION}' for ${MODULE_LOG_NAME} to '${VALUE}'" - echo "${OPTION} = ${VALUE};" >>"${FILE}" - fi - } - - local RSPAMD_CUSTOM_COMMANDS_FILE="${RSPAMD_DMS_D}/custom-commands.conf" - local RSPAMD_CUSTOM_COMMANDS_FILE_OLD="${RSPAMD_DMS_D}-modules.conf" - readonly RSPAMD_CUSTOM_COMMANDS_FILE RSPAMD_CUSTOM_COMMANDS_FILE_OLD - - # We check for usage of the previous location of the commands file. - # This can be removed after the release of v14.0.0. - if [[ -f ${RSPAMD_CUSTOM_COMMANDS_FILE_OLD} ]]; then - __rspamd__log 'warn' "Detected usage of old file location for modules adjustment ('${RSPAMD_CUSTOM_COMMANDS_FILE_OLD}') - please use the new location ('${RSPAMD_CUSTOM_COMMANDS_FILE}')" - __rspamd__log 'warn' "Using old file location now (deprecated) - this will prevent startup in v13.0.0" - RSPAMD_CUSTOM_COMMANDS_FILE=${RSPAMD_CUSTOM_COMMANDS_FILE_OLD} - fi - - if [[ -f "${RSPAMD_CUSTOM_COMMANDS_FILE}" ]]; then - __rspamd__log 'debug' "Found file '${RSPAMD_CUSTOM_COMMANDS_FILE}' - parsing and applying it" - - local COMMAND ARGUMENT1 ARGUMENT2 ARGUMENT3 - while read -r COMMAND ARGUMENT1 ARGUMENT2 ARGUMENT3; do - case "${COMMAND}" in - ('disable-module') - __rspamd__helper__enable_disable_module "${ARGUMENT1}" 'false' 'override' - ;; - - ('enable-module') - __rspamd__helper__enable_disable_module "${ARGUMENT1}" 'true' 'override' - ;; - - ('set-option-for-module') - __add_or_replace "${ARGUMENT1}.conf" "module '${ARGUMENT1}'" "${ARGUMENT2}" "${ARGUMENT3}" - ;; - - ('set-option-for-controller') - __add_or_replace 'worker-controller.inc' 'controller worker' "${ARGUMENT1}" "${ARGUMENT2} ${ARGUMENT3}" - ;; - - ('set-option-for-proxy') - __add_or_replace 'worker-proxy.inc' 'proxy worker' "${ARGUMENT1}" "${ARGUMENT2} ${ARGUMENT3}" - ;; - - ('set-common-option') - __add_or_replace 'options.inc' 'common options' "${ARGUMENT1}" "${ARGUMENT2} ${ARGUMENT3}" - ;; - - ('add-line') - __rspamd__log 'trace' "Adding complete line to '${ARGUMENT1}'" - echo "${ARGUMENT2}${ARGUMENT3+ ${ARGUMENT3}}" >>"${RSPAMD_OVERRIDE_D}/${ARGUMENT1}" - ;; - - (*) - __rspamd__log 'warn' "Command '${COMMAND}' is invalid" - continue - ;; - esac - done < <(_get_valid_lines_from_file "${RSPAMD_CUSTOM_COMMANDS_FILE}") - fi -} diff --git a/test/config/dsn/postfix-main.cf b/test/config/dsn/postfix-main.cf new file mode 100644 index 00000000..1cb0db1e --- /dev/null +++ b/test/config/dsn/postfix-main.cf @@ -0,0 +1 @@ +smtpd_discard_ehlo_keywords = diff --git a/test/config/dsn/postfix-master.cf b/test/config/dsn/postfix-master.cf new file mode 100644 index 00000000..bb6aad15 --- /dev/null +++ b/test/config/dsn/postfix-master.cf @@ -0,0 +1,2 @@ +submission/inet/smtpd_discard_ehlo_keywords=silent-discard,dsn +submissions/inet/smtpd_discard_ehlo_keywords=silent-discard,dsn diff --git a/test/test-files/email-templates/dsn-authenticated.txt b/test/test-files/email-templates/dsn-authenticated.txt new file mode 100644 index 00000000..c187bd67 --- /dev/null +++ b/test/test-files/email-templates/dsn-authenticated.txt @@ -0,0 +1,14 @@ +EHLO mail +AUTH LOGIN dXNlcjFAbG9jYWxob3N0LmxvY2FsZG9tYWlu +bXlwYXNzd29yZA== +MAIL FROM: user1@localhost.localdomain +RCPT TO: user1@localhost.localdomain NOTIFY=success,failure +DATA +From: Existing Local User +To: Existing Local User +Date: Sat, 22 May 2010 07:43:25 -0400 +Subject: Test Message +This is a test mail. + +. +QUIT diff --git a/test/test-files/email-templates/dsn-unauthenticated.txt b/test/test-files/email-templates/dsn-unauthenticated.txt new file mode 100644 index 00000000..8232ea68 --- /dev/null +++ b/test/test-files/email-templates/dsn-unauthenticated.txt @@ -0,0 +1,12 @@ +HELO mail.external.tld +MAIL FROM: user@external.tld +RCPT TO: user1@localhost.localdomain NOTIFY=success,failure +DATA +From: Docker Mail Server +To: Existing Local User +Date: Sat, 22 May 2010 07:43:25 -0400 +Subject: Test Message +This is a test mail. + +. +QUIT diff --git a/test/tests/parallel/set1/spam_virus/rspamd_dkim.bats b/test/tests/parallel/set1/spam_virus/rspamd_dkim.bats index cd880e52..215b334d 100644 --- a/test/tests/parallel/set1/spam_virus/rspamd_dkim.bats +++ b/test/tests/parallel/set1/spam_virus/rspamd_dkim.bats @@ -4,8 +4,8 @@ load "${REPOSITORY_ROOT}/test/helper/setup" BATS_TEST_NAME_PREFIX='[Rspamd] (DKIM) ' CONTAINER_NAME='dms-test_rspamd-dkim' -DOMAIN_NAME='fixed.com' -SIGNING_CONF_FILE='/etc/rspamd/override.d/dkim_signing.conf' +DOMAIN_NAME='example.test' +SIGNING_CONF_FILE='/tmp/docker-mailserver/rspamd/override.d/dkim_signing.conf' function setup_file() { _init_with_defaults @@ -59,7 +59,7 @@ function teardown_file() { _default_teardown ; } __create_key assert_success __log_is_free_of_warnings_and_errors - assert_output --partial "Supplying a default configuration ('${SIGNING_CONF_FILE}')" + assert_output --partial "Supplying a default configuration (to '${SIGNING_CONF_FILE}')" refute_output --partial "'${SIGNING_CONF_FILE}' exists, not supplying a default" assert_output --partial "Finished DKIM key creation" _run_in_container_bash "[[ -f ${SIGNING_CONF_FILE} ]]" @@ -68,8 +68,14 @@ function teardown_file() { _default_teardown ; } local INITIAL_SHA512_SUM=$(_exec_in_container sha512sum "${SIGNING_CONF_FILE}") __create_key + assert_failure + assert_output --partial "Not overwriting existing files (use '--force' to overwrite existing files)" + + # the same as before, but with the '--force' option + __create_key 'rsa' 'mail' "${DOMAIN_NAME}" '2048' '--force' __log_is_free_of_warnings_and_errors refute_output --partial "Supplying a default configuration ('${SIGNING_CONF_FILE}')" + assert_output --partial "Overwriting existing files as the '--force' option was supplied" assert_output --partial "'${SIGNING_CONF_FILE}' exists, not supplying a default" assert_output --partial "Finished DKIM key creation" local SECOND_SHA512_SUM=$(_exec_in_container sha512sum "${SIGNING_CONF_FILE}") @@ -188,11 +194,15 @@ function __create_key() { local SELECTOR=${2:-mail} local DOMAIN=${3:-${DOMAIN_NAME}} local KEYSIZE=${4:-2048} + local FORCE=${5:-} - _run_in_container setup config dkim \ - keytype "${KEYTYPE}" \ - keysize "${KEYSIZE}" \ - selector "${SELECTOR}" \ + # Not quoting is intended here as we would othewise provide + # the argument "''" (empty string), which would cause errors + # shellcheck disable=SC2086 + _run_in_container setup config dkim ${FORCE} \ + keytype "${KEYTYPE}" \ + keysize "${KEYSIZE}" \ + selector "${SELECTOR}" \ domain "${DOMAIN}" } diff --git a/test/tests/parallel/set1/spam_virus/rspamd_full.bats b/test/tests/parallel/set1/spam_virus/rspamd_full.bats index 3fbf59d2..09d42d46 100644 --- a/test/tests/parallel/set1/spam_virus/rspamd_full.bats +++ b/test/tests/parallel/set1/spam_virus/rspamd_full.bats @@ -66,12 +66,9 @@ function teardown_file() { _default_teardown ; } assert_output 'rspamd_milter = inet:localhost:11332' } -@test "'/etc/rspamd/override.d/' is linked correctly" { +@test "contents of '/etc/rspamd/override.d/' are copied" { local OVERRIDE_D='/etc/rspamd/override.d' - _run_in_container_bash "[[ -h ${OVERRIDE_D} ]]" - assert_success - _run_in_container_bash "[[ -f ${OVERRIDE_D}/testmodule_complicated.conf ]]" assert_success } diff --git a/test/tests/parallel/set3/mta/dsn.bats b/test/tests/parallel/set3/mta/dsn.bats new file mode 100644 index 00000000..dcbb79b6 --- /dev/null +++ b/test/tests/parallel/set3/mta/dsn.bats @@ -0,0 +1,95 @@ +load "${REPOSITORY_ROOT}/test/helper/setup" +load "${REPOSITORY_ROOT}/test/helper/common" + +BATS_TEST_NAME_PREFIX='[DSN] ' +CONTAINER1_NAME='dms-test_dsn_send_always' +CONTAINER2_NAME='dms-test_dsn_send_auth' +CONTAINER3_NAME='dms-test_dsn_send_none' +# A similar line is added to the log when a DSN (Delivery Status Notification) is sent: +# +# postfix/bounce[1023]: C943BA6B46: sender delivery status notification: DBF86A6B4CO +# +LOG_DSN='delivery status notification' + +function setup_file() { + local CUSTOM_SETUP_ARGUMENTS=( + # Required only for delivery via nc (_send_email) + --env PERMIT_DOCKER=container + ) + + export CONTAINER_NAME=${CONTAINER1_NAME} + _init_with_defaults + # Unset `smtpd_discard_ehlo_keywords` to allow DSNs by default on any `smtpd` service: + cp "${TEST_TMP_CONFIG}/dsn/postfix-main.cf" "${TEST_TMP_CONFIG}/postfix-main.cf" + _common_container_setup 'CUSTOM_SETUP_ARGUMENTS' + _wait_for_service postfix + _wait_for_smtp_port_in_container + + export CONTAINER_NAME=${CONTAINER2_NAME} + _init_with_defaults + _common_container_setup 'CUSTOM_SETUP_ARGUMENTS' + _wait_for_service postfix + _wait_for_smtp_port_in_container + + export CONTAINER_NAME=${CONTAINER3_NAME} + _init_with_defaults + # Mirror default main.cf (disable DSN on ports 465 + 587 too): + cp "${TEST_TMP_CONFIG}/dsn/postfix-master.cf" "${TEST_TMP_CONFIG}/postfix-master.cf" + _common_container_setup 'CUSTOM_SETUP_ARGUMENTS' + _wait_for_service postfix + _wait_for_smtp_port_in_container +} + +function teardown_file() { + docker rm -f "${CONTAINER1_NAME}" "${CONTAINER2_NAME}" "${CONTAINER3_NAME}" +} + +@test "should always send a DSN when requested" { + export CONTAINER_NAME=${CONTAINER1_NAME} + + _send_email 'email-templates/dsn-unauthenticated' + _send_email 'email-templates/dsn-authenticated' '0.0.0.0 465' + _send_email 'email-templates/dsn-authenticated' '0.0.0.0 587' + _wait_for_empty_mail_queue_in_container + + _run_in_container grep "${LOG_DSN}" /var/log/mail/mail.log + _should_output_number_of_lines 3 +} + +# Defaults test case +@test "should only send a DSN when requested from ports 465/587" { + export CONTAINER_NAME=${CONTAINER2_NAME} + + _send_email 'email-templates/dsn-unauthenticated' + _wait_for_empty_mail_queue_in_container + + # DSN requests can now only be made on ports 465 and 587, + # so grep should not find anything. + # + # Although external requests are discarded, anyone who has requested a DSN + # will still receive it, but it will come from the sending mail server, not this one. + _run_in_container grep "${LOG_DSN}" /var/log/mail/mail.log + assert_failure + + # These ports are excluded via master.cf. + _send_email 'email-templates/dsn-authenticated' '0.0.0.0 465' + _send_email 'email-templates/dsn-authenticated' '0.0.0.0 587' + _wait_for_empty_mail_queue_in_container + + _run_in_container grep "${LOG_DSN}" /var/log/mail/mail.log + _should_output_number_of_lines 2 +} + +@test "should never send a DSN" { + export CONTAINER_NAME=${CONTAINER3_NAME} + + _send_email 'email-templates/dsn-unauthenticated' + _send_email 'email-templates/dsn-authenticated' '0.0.0.0 465' + _send_email 'email-templates/dsn-authenticated' '0.0.0.0 587' + _wait_for_empty_mail_queue_in_container + + # DSN requests are rejected regardless of origin. + # This is usually a bad idea, as you won't get them either. + _run_in_container grep "${LOG_DSN}" /var/log/mail/mail.log + assert_failure +}