From eacc379cf12661a1795b382a667da39650154334 Mon Sep 17 00:00:00 2001 From: allddd <117767298+allddd@users.noreply.github.com> Date: Sun, 22 Oct 2023 15:16:41 +0200 Subject: [PATCH 1/7] feat: Postfix permit DSN (Delivery Status Notification) only on authenticated ports (465 + 587) (#3572) * add POSTFIX_DSN * add tests for POSTFIX_DSN * Revert "add POSTFIX_DSN" This reverts commit d5bd0e911737eb8b9efa9566caac6e95c6570af2. * discard DSN requests on unauthenticated ports * make tests work with overrides instead of ENV * Apply suggestions from code review * fix test inconsistencies --------- Co-authored-by: allddd Co-authored-by: Brennan Kinney <5098581+polarathene@users.noreply.github.com> --- CHANGELOG.md | 11 +++ target/postfix/main.cf | 1 + target/postfix/master.cf | 2 + test/config/dsn/postfix-main.cf | 1 + test/config/dsn/postfix-master.cf | 2 + .../email-templates/dsn-authenticated.txt | 14 +++ .../email-templates/dsn-unauthenticated.txt | 12 +++ test/tests/parallel/set3/mta/dsn.bats | 95 +++++++++++++++++++ 8 files changed, 138 insertions(+) create mode 100644 test/config/dsn/postfix-main.cf create mode 100644 test/config/dsn/postfix-master.cf create mode 100644 test/test-files/email-templates/dsn-authenticated.txt create mode 100644 test/test-files/email-templates/dsn-unauthenticated.txt create mode 100644 test/tests/parallel/set3/mta/dsn.bats diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ce7b6fb..a2e15c77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,17 @@ 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: + + ``` + submission/inet/smtpd_discard_ehlo_keywords=silent-discard,dsn + submissions/inet/smtpd_discard_ehlo_keywords=silent-discard,dsn + ``` ### Added 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/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/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 +} From eb7b1882e16b1c2076f2d5b77b3696fe17b27453 Mon Sep 17 00:00:00 2001 From: georglauterbach <44545919+georglauterbach@users.noreply.github.com> Date: Sun, 22 Oct 2023 17:42:01 +0200 Subject: [PATCH 2/7] update `contributors.yml` action --- .github/workflows/contributors.yml | 75 +- CONTRIBUTORS.md | 1885 +--------------------------- 2 files changed, 15 insertions(+), 1945 deletions(-) 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/CONTRIBUTORS.md b/CONTRIBUTORS.md index cbd2653b..08412f24 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -1,1880 +1,9 @@ +# Contributors + Thanks goes to these wonderful people ✨ -## Contributors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Thomas -
- Thomas VIAL -
-
- - Georg -
- Georg Lauterbach -
-
- - Casper/ -
- Casper -
-
- - Erik -
- Erik Wramner -
-
- - Brennan -
- Brennan Kinney -
-
- - Jean-Denis -
- Jean-Denis Vauguet -
-
- - Martin -
- Martin Schulze -
-
- - Frederic -
- Frederic Werner -
-
- - Josef -
- Josef Friedrich -
-
- - Johan -
- Johan Smits -
-
- - youtous/ -
- youtous -
-
- - 17Halbe/ -
- 17Halbe -
-
- - Nathan -
- Nathan Pierce -
-
- - Thorsten -
- Thorsten von Eicken -
-
- - Germain -
- Germain Masse -
-
- - 00angus/ -
- 00angus -
-
- - Paul -
- Paul Steinlechner -
-
- - Dominik -
- Dominik Winter -
-
- - Paul -
- Paul Adams -
-
- - Felix -
- Felix Bartels -
-
- - Sebastian -
- Sebastian Wiesendahl -
-
- - Steve -
- Steve Johnson -
-
- - André -
- André Stein -
-
- - William -
- William Desportes -
-
- - omarc1492/ -
- omarc1492 -
-
- - Christian -
- Christian Glahn -
-
- - Marek -
- Marek Walczak -
-
- - Kai -
- Kai Ren -
-
- - Kyle -
- Kyle Ondy -
-
- - Michael/ -
- Michael -
-
- - lukas/ -
- lukas -
-
- - Sascha -
- Sascha Scandella -
-
- - Lukáš -
- Lukáš Vasek -
-
- - Andreas -
- Andreas Perhab -
-
- - vortex852456/ -
- vortex852456 -
-
- - Christian -
- Christian Grasso -
-
- - Hans-Cees -
- Hans-Cees Speel -
-
- - Jack -
- Jack Pearson -
-
- - Dashamir -
- Dashamir Hoxha -
-
- - GAVARD -
- GAVARD Ewann -
-
- - Jack -
- Jack Twilley -
-
- - Luke -
- Luke Cyca -
-
- - Oleg -
- Oleg Kainov -
-
- - Robert -
- Robert Dolca -
-
- - Thomas -
- Thomas Kilian -
-
- - Tobias -
- Tobias Rittig -
-
- - akmet/ -
- akmet -
-
- - Arne -
- Arne Kepp -
-
- - Dennis -
- Dennis Stumm -
-
- - Moritz -
- Moritz Marquardt -
-
- - pyy/ -
- pyy -
-
- - Anne/ -
- Anne -
-
- - Birkenstab/ -
- Birkenstab -
-
- - Brandon -
- Brandon Schmitt -
-
- - Cédric -
- Cédric Laubacher -
-
- - GrupoCITEC/ -
- GrupoCITEC -
-
- - Jairo -
- Jairo Llopis -
-
- - James/ -
- James -
-
- - Jarrod -
- Jarrod Smith -
-
- - Patrizio -
- Patrizio Bekerle -
-
- - Rubytastic2/ -
- Rubytastic2 -
-
- - Semir -
- Semir Patel -
-
- - Wolfgang -
- Wolfgang Ocker -
-
- - Zehir/ -
- Zehir -
-
- - guardiande/ -
- guardiande -
-
- - kamuri/ -
- kamuri -
-
- - davidszp/ -
- davidszp -
-
- - Andreas -
- Andreas Gerstmayr -
-
- - Marko -
- Marko J -
-
- - Michael -
- Michael Schmoock -
-
- - VanVan/ -
- VanVan -
-
- - Alexander -
- Alexander Elbracht -
-
- - Amin -
- Amin Vakil -
-
- - Andrew -
- Andrew Low -
-
- - Ask -
- Ask Bjørn Hansen -
-
- - Ben/ -
- Ben -
-
- - Christian -
- Christian Raue -
-
- - Daniel -
- Daniel Panteleit -
-
- - Darren -
- Darren McGrandle -
-
- - Dominik -
- Dominik Bruhn -
-
- - DuncanvR/ -
- DuncanvR -
-
- - Emanuele -
- Emanuele Mazzotta -
-
- - FL42/ -
- FL42 -
-
- - Guillaume -
- Guillaume Simon -
-
- - Ikko -
- Ikko Eltociear Ashimine -
-
- - James -
- James Fryer -
-
- - Millaguie/ -
- Millaguie -
-
- - Jeremy -
- Jeremy Shipman -
-
- - Jonas -
- Jonas Kalderstam -
-
- - Louis/ -
- Louis -
-
- - martinwepner/ -
- martinwepner -
-
- - Michael -
- Michael Als -
-
- - Morgan -
- Morgan Kesler -
-
- - Pablo -
- Pablo Castorino -
-
- - Philipp -
- Philipp Fruck -
-
- - Rainer -
- Rainer Rillke -
-
- - Bob -
- Bob Gregor -
-
- - r-pufky/ -
- r-pufky -
-
- - andymel/ -
- andymel -
-
- - bigpigeon/ -
- bigpigeon -
-
- - engelant/ -
- engelant -
-
- - j-marz/ -
- j-marz -
-
- - lokipo/ -
- lokipo -
-
- - msheakoski/ -
- msheakoski -
-
- - Felix/ -
- Felix -
-
- - Leon -
- Leon Busch-George -
-
- - Marius -
- Marius Panneck -
-
- - Thomas -
- Thomas Willems -
-
- - 0xflotus/ -
- 0xflotus -
-
- - Ivan -
- Ivan Fokeev -
-
- - 20th/ -
- 20th -
-
- - 2b/ -
- 2b -
-
- - Max:/ -
- Max: -
-
- - Achim -
- Achim Christ -
-
- - Adrian -
- Adrian Pistol -
-
- - Alexander -
- Alexander Kachkaev -
-
- - Alexander -
- Alexander Neu -
-
- - Bedniakov -
- Bedniakov Aleksei -
-
- - Andreas -
- Andreas Egli -
-
- - Andrew -
- Andrew Cornford -
-
- - Andrey -
- Andrey Likhodievskiy -
-
- - Arash -
- Arash Fatahzade -
-
- - Arthur -
- Arthur Outhenin-Chalandre -
-
- - Astro/ -
- Astro -
-
- - Benedict -
- Benedict Endemann -
-
- - Bogdan/ -
- Bogdan -
-
- - Charles -
- Charles Harris -
-
- - Christian -
- Christian Musa -
-
- - Christoph/ -
- Christoph -
-
- - Claus -
- Claus Beerta -
-
- - Damian -
- Damian Moore -
-
- - espitall/ -
- espitall -
-
- - Daniel -
- Daniel Karski -
-
- - Daniele -
- Daniele Bellavista -
-
- - Daniël -
- Daniël van den Berg -
-
- - Dingoz/ -
- Dingoz -
-
- - Dmitry -
- Dmitry R. -
-
- - Dorian -
- Dorian Ayllón -
-
- - Edmond -
- Edmond Varga -
-
- - Eduard -
- Eduard Knysh -
-
- - Elisei -
- Elisei Roca -
-
- - Erick -
- Erick Calder -
-
- - Erik -
- Erik Brakkee -
-
- - Huncode/ -
- Huncode -
-
- - Florian/ -
- Florian -
-
- - Florian -
- Florian Roks -
-
- - Franz -
- Franz Keferböck -
-
- - Frugan/ -
- Frugan -
-
- - Gabriel -
- Gabriel Euzet -
-
- - Gabriel -
- Gabriel Landais -
-
- - GiovanH/ -
- GiovanH -
-
- - H4R0/ -
- H4R0 -
-
- - Harry -
- Harry Youd -
-
- - Hugues -
- Hugues Granger -
-
- - Ian -
- Ian Andrews -
-
- - Influencer/ -
- Influencer -
-
- - jcalfee/ -
- jcalfee -
-
- - JS -
- JS Légaré -
-
- - Jeidnx/ -
- Jeidnx -
-
- - JiLleON/ -
- JiLleON -
-
- - Jiří -
- Jiří Kozlovský -
-
- - jmccl/ -
- jmccl -
-
- - Jurek -
- Jurek Barth -
-
- - JOnathan -
- JOnathan duMonT -
-
- - Kaan/ -
- Kaan -
-
- - Karthik -
- Karthik K -
-
- - KCrawley/ -
- KCrawley -
-
- - Khue -
- Khue Doan -
-
- - Lars -
- Lars Pötter -
-
- - Leo -
- Leo Winter -
-
- - Lin -
- Lin Han -
-
- - MadsRC/ -
- MadsRC -
-
- - Mathieu -
- Mathieu Brunot -
-
- - Maximilian -
- Maximilian Hippler -
-
- - Michael -
- Michael G. -
-
- - Michael -
- Michael Jensen -
-
- - Michel -
- Michel Albert -
-
- - Mohammed -
- Mohammed Chotia -
-
- - Mohammed -
- Mohammed Noureldin -
-
- - Moritz -
- Moritz Poldrack -
-
- - Naveen/ -
- Naveen -
-
- - Nicholas -
- Nicholas Pepper -
-
- - Nick -
- Nick Pappas -
-
- - Nils -
- Nils Knappmeier -
-
- - Olivier -
- Olivier Picquenot -
-
- - Orville -
- Orville Q. Song -
-
- - Ovidiu -
- Ovidiu Predescu -
-
- - Petar -
- Petar Šegina -
-
- - Peter -
- Peter Hartmann -
-
- - Pierre-Yves -
- Pierre-Yves Rofes -
-
- - Remo -
- Remo E -
-
- - René -
- René Plötz -
-
- - Roman -
- Roman Seyffarth -
-
- - Sam -
- Sam Collins -
-
- - Scott -
- Scott Weldon -
-
- - Sebastian -
- Sebastian Straub -
-
- - Serge -
- Serge van den Boom -
-
- - Sergey -
- Sergey Nazaryev -
-
- - Shyim/ -
- Shyim -
-
- - Simon -
- Simon J Mudd -
-
- - Simon -
- Simon Schröter -
-
- - Stephan/ -
- Stephan -
-
- - Stig -
- Stig Otnes Kolstad -
-
- - Sven -
- Sven Kauber -
-
- - Sylvain -
- Sylvain Benner -
-
- - Sylvain -
- Sylvain Dumont -
-
- - TechnicLab/ -
- TechnicLab -
-
- - Thomas -
- Thomas Schmit -
-
- - Tin/ -
- Tin -
-
- - Torben -
- Torben Weibert -
-
- - Toru -
- Toru Hisai -
-
- - Trangar/ -
- Trangar -
-
- - Twist235/ -
- Twist235 -
-
- - Vasiliy -
- Vasiliy Gokoyev -
-
- - Victoria -
- Victoria Brekenfeld -
-
- - Vilius/ -
- Vilius -
-
- - Wim/ -
- Wim -
-
- - Y.C.Huang/ -
- Y.C.Huang -
-
- - arcaine2/ -
- arcaine2 -
-
- - awb99/ -
- awb99 -
-
- - brainkiller/ -
- brainkiller -
-
- - cternes/ -
- cternes -
-
- - dborowy/ -
- dborowy -
-
- - dimalo/ -
- dimalo -
-
- - eleith/ -
- eleith -
-
- - helmutundarnold/ -
- helmutundarnold -
-
- - hnws/ -
- hnws -
-
- - i-C-o-d-e-r/ -
- i-C-o-d-e-r -
-
- - idaadi/ -
- idaadi -
-
- - ixeft/ -
- ixeft -
-
- - jjtt/ -
- jjtt -
-
- - jose -
- jose nazario -
-
- - landergate/ -
- landergate -
-
- - magnus -
- magnus anderssen -
-
- - marios88/ -
- marios88 -
-
- - matrixes/ -
- matrixes -
-
- - mchamplain/ -
- mchamplain -
-
- - Jason -
- Jason Miller -
-
- - mplx/ -
- mplx -
-
- - odinis/ -
- odinis -
-
- - okami/ -
- okami -
-
- - olaf-mandel/ -
- olaf-mandel -
-
- - ontheair81/ -
- ontheair81 -
-
- - pravynandas/ -
- pravynandas -
-
- - presocratics/ -
- presocratics -
-
- - rhyst/ -
- rhyst -
-
- - schnippl0r/ -
- schnippl0r -
-
- - smargold476/ -
- smargold476 -
-
- - sportshead/ -
- sportshead -
-
- - squash/ -
- squash -
-
- - strarsis/ -
- strarsis -
-
- - tamueller/ -
- tamueller -
-
- - vivacarvajalito/ -
- vivacarvajalito -
-
- - wolkenschieber/ -
- wolkenschieber -
-
- - worldworm/ -
- worldworm -
-
+ + ## Further Contributors @@ -1898,8 +27,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! From d988d8a8d1be8bd07c271eaa9911f15f5cd033c7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 22 Oct 2023 18:11:16 +0200 Subject: [PATCH 3/7] docs: updated `CONTRIBUTORS.md` (#3596) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- CONTRIBUTORS.md | 1937 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1937 insertions(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 08412f24..538f3740 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -3,6 +3,1943 @@ Thanks goes to these wonderful people ✨ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + casperklein +
+ Casper +
+
+ + fbartels +
+ Felix Bartels +
+
+ + NorseGaud +
+ Nathan Pierce +
+
+ + williamdes +
+ William Desportes +
+
+ + wernerfred +
+ Frederic Werner +
+
+ + georglauterbach +
+ Georg Lauterbach +
+
+ + tomav +
+ Thomas VIAL +
+
+ + erik-wramner +
+ Erik Wramner +
+
+ + polarathene +
+ Brennan Kinney +
+
+ + chikamichi +
+ Jean-Denis Vauguet +
+
+ + martin-schulze-vireso +
+ Martin Schulze +
+
+ + Josef-Friedrich +
+ Josef Friedrich +
+
+ + johansmitsnl +
+ Johan Smits +
+
+ + youtous +
+ Null +
+
+ + 17Halbe +
+ Null +
+
+ + tve +
+ Thorsten Von Eicken +
+
+ + gmasse +
+ Germain Masse +
+
+ + 00angus +
+ Null +
+
+ + alinmear +
+ Paul Steinlechner +
+
+ + ap-wtioit +
+ Andreas Perhab +
+
+ + dominikwinter +
+ Dominik Winter +
+
+ + crazystick +
+ Paul Adams +
+
+ + swiesend +
+ Sebastian Wiesendahl +
+
+ + svenyonson +
+ Steve Johnson +
+
+ + stonemaster +
+ André Stein +
+
+ + omarc1492 +
+ Null +
+
+ + phish108 +
+ Christian Glahn +
+
+ + mwlczk +
+ Marek Walczak +
+
+ + tyranron +
+ Kai Ren +
+
+ + KyleOndy +
+ Kyle Ondy +
+
+ + MichaelSp +
+ Michael +
+
+ + mindrunner +
+ Lukas +
+
+ + m-a-v +
+ Sascha Scandella +
+
+ + bilak +
+ Lukáš Vasek +
+
+ + vortex852456 +
+ Null +
+
+ + chris54721 +
+ Christian Grasso +
+
+ + hanscees +
+ Hans-Cees Speel +
+
+ + jrpear +
+ Jack Pearson +
+
+ + dashohoxha +
+ Dashamir Hoxha +
+
+ + egavard +
+ GAVARD Ewann +
+
+ + mathuin +
+ Jack Twilley +
+
+ + jamebus +
+ James +
+
+ + lukecyca +
+ Luke Cyca +
+
+ + okainov +
+ Oleg Kainov +
+
+ + robertdolca +
+ Robert Dolca +
+
+ + kiliant +
+ Thomas Kilian +
+
+ + diiigle +
+ Tobias Rittig +
+
+ + akmet +
+ Akmet +
+
+ + arneke +
+ Arne Kepp +
+
+ + dennis95stumm +
+ Dennis Stumm +
+
+ + moqmar +
+ Moritz Marquardt +
+
+ + pyy +
+ Null +
+
+ + voordev +
+ Anne +
+
+ + Birkenstab +
+ Null +
+
+ + BrandonSchmitt +
+ Brandon Schmitt +
+
+ + Starbix +
+ Cédric Laubacher +
+
+ + citec +
+ GrupoCITEC +
+
+ + yajo +
+ Jairo Llopis +
+
+ + MakerMatrix +
+ Jarrod Smith +
+
+ + pbek +
+ Patrizio Bekerle +
+
+ + Rubytastic2 +
+ Null +
+
+ + analogue +
+ Semir Patel +
+
+ + weo +
+ Wolfgang Ocker +
+
+ + Zehir +
+ Zehir +
+
+ + guardiande +
+ Null +
+
+ + kamuri +
+ Null +
+
+ + davidszp +
+ Null +
+
+ + andreasgerstmayr +
+ Andreas Gerstmayr +
+
+ + mjung +
+ Marko J +
+
+ + m-schmoock +
+ Michael Schmoock +
+
+ + VanVan +
+ Null +
+
+ + elbracht +
+ Alexander Elbracht +
+
+ + aminvakil +
+ Amin Vakil +
+
+ + andrewlow +
+ Andrew Low +
+
+ + abh +
+ Ask Bjørn Hansen +
+
+ + ubenmackin +
+ Ben +
+
+ + craue +
+ Christian Raue +
+
+ + danielpanteleit +
+ Daniel Panteleit +
+
+ + dmcgrandle +
+ Darren McGrandle +
+
+ + theomega +
+ Dominik Bruhn +
+
+ + DuncanvR +
+ Null +
+
+ + emazzotta +
+ Emanuele Mazzotta +
+
+ + fl42 +
+ FL42 +
+
+ + ipernet +
+ Guillaume Simon +
+
+ + H4R0 +
+ Null +
+
+ + eltociear +
+ Ikko Eltociear Ashimine +
+
+ + jamesfryer +
+ James Fryer +
+
+ + millaguie +
+ Millaguie +
+
+ + jedateach +
+ Jeremy Shipman +
+
+ + spacecowboy +
+ Jonas Kalderstam +
+
+ + artonge +
+ Louis +
+
+ + martinwepner +
+ Null +
+
+ + nueaf +
+ Michael Als +
+
+ + keslerm +
+ Morgan Kesler +
+
+ + castorinop +
+ Pablo Castorino +
+
+ + p-fruck +
+ Philipp Fruck +
+
+ + Rillke +
+ Rainer Rillke +
+
+ + reneploetz +
+ René Plötz +
+
+ + bobbravo2 +
+ Bob Gregor +
+
+ + r-pufky +
+ Robert Pufky +
+
+ + vincentDcmps +
+ Vincent Ducamps +
+
+ + andymel123 +
+ Andymel +
+
+ + bigpigeon +
+ Bigpigeon +
+
+ + engelant +
+ Null +
+
+ + j-marz +
+ Null +
+
+ + lokipo +
+ Null +
+
+ + msheakoski +
+ Null +
+
+ + GoliathLabs +
+ Felix +
+
+ + yogo1212 +
+ Leon Busch-George +
+
+ + mpanneck +
+ Marius Panneck +
+
+ + willtho89 +
+ Thomas Willems +
+
+ + tbutter +
+ Thomas Butter +
+
+ + 0xflotus +
+ 0xflotus +
+
+ + ifokeev +
+ Johan Fokeev +
+
+ + 20th +
+ Null +
+
+ + 2b +
+ Null +
+
+ + askz +
+ Max: +
+
+ + acch +
+ Achim Christ +
+
+ + vifino +
+ Adrian Pistol +
+
+ + kachkaev +
+ Alexander Kachkaev +
+
+ + alexanderneu +
+ Alexander Neu +
+
+ + ch3sh1r +
+ Bedniakov Aleksei +
+
+ + eglia +
+ Andreas Egli +
+
+ + groupmsl +
+ Andrew Cornford +
+
+ + green-anger +
+ Andrey Likhodievskiy +
+
+ + iRhonin +
+ Arash Fatahzade +
+
+ + MrFreezeex +
+ Arthur Outhenin-Chalandre +
+
+ + arunvc +
+ Arun +
+
+ + astrocket +
+ Astro +
+
+ + baxerus +
+ Benedict Endemann +
+
+ + spock +
+ Bogdan +
+
+ + erdos4d +
+ Charles Harris +
+
+ + crash7 +
+ Christian Musa +
+
+ + auchri +
+ Christoph +
+
+ + arkanovicz +
+ Claude Brisson +
+
+ + CBeerta +
+ Claus Beerta +
+
+ + damianmoore +
+ Damian Moore +
+
+ + espitall +
+ Null +
+
+ + dkarski +
+ Daniel Karski +
+
+ + dbellavista +
+ Daniele Bellavista +
+
+ + danielvandenberg95 +
+ Daniël Van Den Berg +
+
+ + mlatorre31 +
+ Dingoz +
+
+ + mazzz1y +
+ Dmitry R. +
+
+ + aydodo +
+ Dorian Ayllón +
+
+ + vedtam +
+ Edmond Varga +
+
+ + edvorg +
+ Eduard Knyshov +
+
+ + eliroca +
+ Elisei Roca +
+
+ + ekkis +
+ Erick Calder +
+
+ + ErikEngerd +
+ Erik Brakkee +
+
+ + huncode +
+ Huncode +
+
+ + felixn +
+ Felix N +
+
+ + flole +
+ Florian +
+
+ + froks +
+ Florian Roks +
+
+ + fkefer +
+ Franz Keferböck +
+
+ + frugan-it +
+ Frugan +
+
+ + Marsu31 +
+ Gabriel Euzet +
+
+ + glandais +
+ Gabriel Landais +
+
+ + GiovanH +
+ GiovanH +
+
+ + harryyoud +
+ Harry Youd +
+
+ + HeySora +
+ HeySora +
+
+ + sirgantrithon +
+ Ian Andrews +
+
+ + Influencer +
+ Influencer +
+
+ + jcalfee +
+ Null +
+
+ + init-js +
+ JS Légaré +
+
+ + Jeidnx +
+ Jeidnx +
+
+ + JiLleON +
+ Null +
+
+ + jirislav +
+ Jiří Kozlovský +
+
+ + jmccl +
+ Null +
+
+ + jurekbarth +
+ Jurek Barth +
+
+ + JOduMonT +
+ JOnathan DuMonT +
+
+ + Kaan88 +
+ Kaan +
+
+ + akkumar +
+ Karthik K +
+
+ + KCrawley +
+ Null +
+
+ + khuedoan +
+ Khue Doan +
+
+ + JustAnother1 +
+ Lars Pötter +
+
+ + LeoWinterDE +
+ Leo Winter +
+
+ + linhandev +
+ Lin Han +
+
+ + luke- +
+ Lucas Bartholemy +
+
+ + LucidityCrash +
+ Null +
+
+ + MadsRC +
+ MadsRC +
+
+ + madmath03 +
+ Mathieu Brunot +
+
+ + maxemann96 +
+ Maximilian Hippler +
+
+ + dragetd +
+ Michael G. +
+
+ + michaeljensen +
+ Michael Jensen +
+
+ + exhuma +
+ Michel Albert +
+
+ + milas +
+ Milas Bowman +
+
+ + mcchots +
+ Mohammed Chotia +
+
+ + MohammedNoureldin +
+ Mohammed Noureldin +
+
+ + mpldr +
+ Moritz Poldrack +
+
+ + naveensrinivasan +
+ Naveen +
+
+ + neuralp +
+ Nicholas Pepper +
+
+ + radicand +
+ Nick Pappas +
+
+ + nilshoell +
+ Nils Höll +
+
+ + nknapp +
+ Nils Knappmeier +
+
+ + pcqnt +
+ Olivier Picquenot +
+
+ + OrvilleQ +
+ Orville Q. Song +
+
+ + ovidiucp +
+ Ovidiu Predescu +
+
+ + mrPjer +
+ Petar Šegina +
+
+ + peter-hartmann +
+ Peter Hartmann +
+
+ + piwai +
+ Pierre-Yves Rofes +
+
+ + remoe +
+ Remo E +
+
+ + romansey +
+ Roman Seyffarth +
+
+ + MightySCollins +
+ Sam Collins +
+
+ + 501st-alpha1 +
+ Scott Weldon +
+
+ + klamann +
+ Sebastian Straub +
+
+ + svdb0 +
+ Serge Van Den Boom +
+
+ + 3ap +
+ Sergey Nazaryev +
+
+ + shyim +
+ Shyim +
+
+ + sjmudd +
+ Simon J Mudd +
+
+ + simonsystem +
+ Simon Schröter +
+
+ + stephan-devop +
+ Stephan +
+
+ + stigok +
+ Stig Otnes Kolstad +
+
+ + 5ven +
+ Sven Kauber +
+
+ + syl20bnr +
+ Sylvain Benner +
+
+ + sylvaindumont +
+ Sylvain Dumont +
+
+ + TechnicLab +
+ Null +
+
+ + thomasschmit +
+ Thomas Schmit +
+
+ + Thiritin +
+ Tin +
+
+ + tweibert +
+ Torben Weibert +
+
+ + torus +
+ Toru Hisai +
+
+ + VictorKoenders +
+ Trangar +
+
+ + Twist235 +
+ Null +
+
+ + k3it +
+ Vasiliy Gokoyev +
+
+ + Drakulix +
+ Victoria Brekenfeld +
+
+ + vilisas +
+ Vilius +
+
+ + 42wim +
+ Wim +
+
+ + ShiriNmi1520 +
+ Y.C.Huang +
+
+ + allddd +
+ Allddd +
+
+ + arcaine2 +
+ Null +
+
+ + awb99 +
+ Awb99 +
+
+ + brainkiller +
+ Null +
+
+ + cternes +
+ Null +
+
+ + dborowy +
+ Null +
+
+ + dimalo +
+ Null +
+
+ + eleith +
+ Eleith +
+
+ + ghnp5 +
+ Null +
+
+ + helmutundarnold +
+ Null +
+
+ + hnws +
+ Null +
+
+ + i-C-o-d-e-r +
+ Null +
+
+ + idaadi +
+ Null +
+
+ + ixeft +
+ Null +
+
+ + jjtt +
+ Null +
+
+ + paralax +
+ Jose Nazario +
+
+ + jpduyx +
+ Null +
+
+ + landergate +
+ Null +
+
+ + callmemagnus +
+ Magnus Anderssen +
+
+ + marios88 +
+ Null +
+
+ + matrixes +
+ Null +
+
+ + mchamplain +
+ Mchamplain +
+
+ + millerjason +
+ Jason Miller +
+
+ + mplx +
+ Null +
+
+ + odinis +
+ Null +
+
+ + okamidash +
+ Okami +
+
+ + olaf-mandel +
+ 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 From cb62ce20e6f49d211a8f264b11feaed65582a338 Mon Sep 17 00:00:00 2001 From: Georg Lauterbach <44545919+georglauterbach@users.noreply.github.com> Date: Tue, 24 Oct 2023 10:31:22 +0200 Subject: [PATCH 4/7] bugfix: change Rspamd DKIM default config location (#3597) Instead of using `etc/rspamd/override.d/dkim_signing.conf`, we will now be using `/tmp/docker-mailserver/rspamd/override.d/dkim_signing.conf`. The new location is persisted (and linked again during startup) and hence better suited. --- target/bin/rspamd-dkim | 57 ++++++++++++++----- .../startup/setup.d/security/rspamd.sh | 3 +- .../parallel/set1/spam_virus/rspamd_dkim.bats | 6 +- 3 files changed, 48 insertions(+), 18 deletions(-) diff --git a/target/bin/rspamd-dkim b/target/bin/rspamd-dkim index de7129de..576c55ab 100755 --- a/target/bin/rspamd-dkim +++ b/target/bin/rspamd-dkim @@ -138,24 +138,55 @@ function _parse_arguments() { 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 + + # Note: Variables not marked with `local` are used + # in other functions (after this function was called). + # Also keep in sync with: target/scripts/startup/setup.d/security/rspamd.sh:__rspamd__run_early_setup_and_checks + local RSPAMD_DMS_D='/tmp/docker-mailserver/rspamd' + local RSPAMD_OVERRIDE_D='/etc/rspamd/override.d' + readonly RSPAMD_DMS_DKIM_D="${RSPAMD_DMS_D}/dkim" + readonly RSPAMD_DMS_OVERRIDE_D="${RSPAMD_DMS_D}/override.d" + + mkdir -p "${RSPAMD_DMS_DKIM_D}" "${RSPAMD_DMS_OVERRIDE_D}" + chown _rspamd:_rspamd "${RSPAMD_DMS_DKIM_D}" + + # Mimmick target/scripts/startup/setup.d/security/rspamd.sh:__rspamd__run_early_setup_and_checks where + # ${RSPAMD_OVERRIDE_D} is linked to ${RSPAMD_DMS_OVERRIDE_D}, but not if + # + # 1. ${RSPAMD_OVERRIDE_D} has already been linked to ${RSPAMD_DMS_OVERRIDE_D} + # 2. ${RSPAMD_OVERRIDE_D} has contents already + # + # If 1. is true, then we're good since DMS' default setup linked the directory already and we will save + # a persisted location in every case. If 1. is false, 2. should be false as well since by default, + # ${RSPAMD_OVERRIDE_D} has no contents - we're good as well. What should logically never happen is + # that 1. is false but 2. is true; this case is caught nevertheless and a warning is emitted. + if [[ ! -h "${RSPAMD_OVERRIDE_D}" ]]; then + if rmdir "${RSPAMD_OVERRIDE_D}" &>/dev/null; then + ln -s "${RSPAMD_DMS_OVERRIDE_D}" "${RSPAMD_OVERRIDE_D}" + else + _log 'warn' "Could not link '${RSPAMD_OVERRIDE_D}' to '${RSPAMD_DMS_OVERRIDE_D}' (as '${RSPAMD_OVERRIDE_D}' does not appear to be empty, which is unexpected) - you will need to restart DMS for changes to take effect" + fi + fi } 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,9 +195,6 @@ 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}" - # shellcheck disable=SC2310 if __do_as_rspamd_user rspamadm \ dkim_keygen \ @@ -186,8 +214,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 +224,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" 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 @@ -254,6 +282,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/scripts/startup/setup.d/security/rspamd.sh b/target/scripts/startup/setup.d/security/rspamd.sh index 4199b077..38b83444 100644 --- a/target/scripts/startup/setup.d/security/rspamd.sh +++ b/target/scripts/startup/setup.d/security/rspamd.sh @@ -70,7 +70,7 @@ function __rspamd__run_early_setup_and_checks() { 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/" + local RSPAMD_DMS_OVERRIDE_D="${RSPAMD_DMS_D}/override.d" readonly RSPAMD_DMS_OVERRIDE_D mkdir -p /var/lib/rspamd/ @@ -82,6 +82,7 @@ function __rspamd__run_early_setup_and_checks() { 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}'" + __rspamd__log 'warn' "Note that using '${RSPAMD_DMS_OVERRIDE_D}' and placing files manually in '${RSPAMD_OVERRIDE_D}' is not supported" fi fi diff --git a/test/tests/parallel/set1/spam_virus/rspamd_dkim.bats b/test/tests/parallel/set1/spam_virus/rspamd_dkim.bats index cd880e52..76c301ea 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} ]]" From 097dc6c9a4b48d5955c4d9c40c191bfb4e0ca29d Mon Sep 17 00:00:00 2001 From: Joerg Sonnenberger Date: Thu, 26 Oct 2023 02:22:36 +0200 Subject: [PATCH 5/7] docs(bin/setup): Add an example for an alias with multiple recipients (#3600) Co-authored-by: Brennan Kinney <5098581+polarathene@users.noreply.github.com> --- target/bin/addalias | 3 +++ 1 file changed, 3 insertions(+) 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. From 5efd2497864ab9bcf185b7901503786054b4a791 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 29 Oct 2023 17:04:07 +0100 Subject: [PATCH 6/7] docs: updated `CONTRIBUTORS.md` (#3606) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- CONTRIBUTORS.md | 110 ++++++++++++++++++++++++++---------------------- 1 file changed, 59 insertions(+), 51 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 538f3740..615cc80e 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -1201,14 +1201,21 @@ Thanks goes to these wonderful people ✨ Jiří Kozlovský + + + jsonn +
+ Joerg Sonnenberger +
+ + jmccl
Null
- - + jurekbarth @@ -1243,15 +1250,15 @@ Thanks goes to these wonderful people ✨
Null
- + + khuedoan
Khue Doan
- - + JustAnother1 @@ -1286,15 +1293,15 @@ Thanks goes to these wonderful people ✨
Null
- + + MadsRC
MadsRC
- - + madmath03 @@ -1329,15 +1336,15 @@ Thanks goes to these wonderful people ✨
Michel Albert
- + + milas
Milas Bowman
- - + mcchots @@ -1372,15 +1379,15 @@ Thanks goes to these wonderful people ✨
Nicholas Pepper
- + + radicand
Nick Pappas
- - + nilshoell @@ -1415,15 +1422,15 @@ Thanks goes to these wonderful people ✨
Ovidiu Predescu
- + + mrPjer
Petar Šegina
- - + peter-hartmann @@ -1458,15 +1465,15 @@ Thanks goes to these wonderful people ✨
Sam Collins
- + + 501st-alpha1
Scott Weldon
- - + klamann @@ -1501,15 +1508,15 @@ Thanks goes to these wonderful people ✨
Simon J Mudd
- + + simonsystem
Simon Schröter
- - + stephan-devop @@ -1544,15 +1551,15 @@ Thanks goes to these wonderful people ✨
Sylvain Dumont
- + + TechnicLab
Null
- - + thomasschmit @@ -1587,15 +1594,15 @@ Thanks goes to these wonderful people ✨
Trangar
- + + Twist235
Null
- - + k3it @@ -1630,15 +1637,15 @@ Thanks goes to these wonderful people ✨
Y.C.Huang
- + + allddd
Allddd
- - + arcaine2 @@ -1673,15 +1680,15 @@ Thanks goes to these wonderful people ✨
Null
- + + dimalo
Null
- - + eleith @@ -1716,15 +1723,15 @@ Thanks goes to these wonderful people ✨
Null
- + + idaadi
Null
- - + ixeft @@ -1759,15 +1766,15 @@ Thanks goes to these wonderful people ✨
Null
- + + callmemagnus
Magnus Anderssen
- - + marios88 @@ -1802,15 +1809,15 @@ Thanks goes to these wonderful people ✨
Null
- + + odinis
Null
- - + okamidash @@ -1845,15 +1852,15 @@ Thanks goes to these wonderful people ✨
Null
- + + rhyst
Null
- - + rmlhuk @@ -1888,15 +1895,15 @@ Thanks goes to these wonderful people ✨
Null
- + + squash
Null
- - + strarsis @@ -1931,7 +1938,8 @@ Thanks goes to these wonderful people ✨
Null
- + + worldworm From f674232f7116acd1d5b2758c52ab5f5827d4d928 Mon Sep 17 00:00:00 2001 From: Georg Lauterbach <44545919+georglauterbach@users.noreply.github.com> Date: Mon, 30 Oct 2023 10:20:37 +0100 Subject: [PATCH 7/7] misc: final Rspamd adjustments for v13 (#3599) * outsource Rspamd ENVs into explicit helper This will allow us to uniformly source the helper and get the values from everywhere consistently. This is more than desirable since we will be using these values not only for the Rspamd setup, but also for DKIM management and during change-detection. * integrate Rspamd into changedetection We outsource one more function to reside in the helper script for Rspamd so that we can call this function from the Rspamd setup and from the changedetection functionality too. * realize deprecation of old commands file for Rspamd THIS IS A BREAKING CHANGE! This change realizes the log message: "Using old file location now (deprecated) - this will prevent startup in v13.0.0" Startup will now fail. * added '--force' option to Rspamd DKIM script * use new helper to get ENVs for Rspamd in DKIM script * remove the need for linking directories This was unnecessary, as explained in https://github.com/docker-mailserver/docker-mailserver/pull/3597#discussion_r1369413599 * Apply suggestions from code review review by @polarathene * apply more review feedback from @polarathene - - * update documentation --------- Co-authored-by: Brennan Kinney <5098581+polarathene@users.noreply.github.com> --- CHANGELOG.md | 4 +- docs/content/config/security/rspamd.md | 4 +- target/bin/rspamd-dkim | 63 ++++----- target/scripts/check-for-changes.sh | 32 +++++ target/scripts/helpers/change-detection.sh | 6 + target/scripts/helpers/index.sh | 1 + target/scripts/helpers/rspamd.sh | 105 +++++++++++++++ .../startup/setup.d/security/rspamd.sh | 123 ++---------------- .../parallel/set1/spam_virus/rspamd_dkim.bats | 18 ++- .../parallel/set1/spam_virus/rspamd_full.bats | 5 +- 10 files changed, 205 insertions(+), 156 deletions(-) create mode 100644 target/scripts/helpers/rspamd.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index a2e15c77..0b875e2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,11 +16,13 @@ All notable changes to this project will be documented in this file. The format 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 - New environment variable `MARK_SPAM_AS_READ`. When set to `1`, marks incoming junk as "read" to avoid unwanted notification of junk as new mail ([#3489](https://github.com/docker-mailserver/docker-mailserver/pull/3489)) 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/rspamd-dkim b/target/bin/rspamd-dkim index 576c55ab..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,7 +140,6 @@ function _parse_arguments() { __usage _exit_with_error "Unknown option(s) '${1}' ${2:+"and '${2}'"}" ;; - esac shift 2 @@ -150,34 +157,10 @@ function _preflight_checks() { _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 - # Note: Variables not marked with `local` are used - # in other functions (after this function was called). - # Also keep in sync with: target/scripts/startup/setup.d/security/rspamd.sh:__rspamd__run_early_setup_and_checks - local RSPAMD_DMS_D='/tmp/docker-mailserver/rspamd' - local RSPAMD_OVERRIDE_D='/etc/rspamd/override.d' - readonly RSPAMD_DMS_DKIM_D="${RSPAMD_DMS_D}/dkim" - readonly RSPAMD_DMS_OVERRIDE_D="${RSPAMD_DMS_D}/override.d" + _rspamd_get_envs mkdir -p "${RSPAMD_DMS_DKIM_D}" "${RSPAMD_DMS_OVERRIDE_D}" chown _rspamd:_rspamd "${RSPAMD_DMS_DKIM_D}" - - # Mimmick target/scripts/startup/setup.d/security/rspamd.sh:__rspamd__run_early_setup_and_checks where - # ${RSPAMD_OVERRIDE_D} is linked to ${RSPAMD_DMS_OVERRIDE_D}, but not if - # - # 1. ${RSPAMD_OVERRIDE_D} has already been linked to ${RSPAMD_DMS_OVERRIDE_D} - # 2. ${RSPAMD_OVERRIDE_D} has contents already - # - # If 1. is true, then we're good since DMS' default setup linked the directory already and we will save - # a persisted location in every case. If 1. is false, 2. should be false as well since by default, - # ${RSPAMD_OVERRIDE_D} has no contents - we're good as well. What should logically never happen is - # that 1. is false but 2. is true; this case is caught nevertheless and a warning is emitted. - if [[ ! -h "${RSPAMD_OVERRIDE_D}" ]]; then - if rmdir "${RSPAMD_OVERRIDE_D}" &>/dev/null; then - ln -s "${RSPAMD_DMS_OVERRIDE_D}" "${RSPAMD_OVERRIDE_D}" - else - _log 'warn' "Could not link '${RSPAMD_OVERRIDE_D}' to '${RSPAMD_DMS_OVERRIDE_D}' (as '${RSPAMD_OVERRIDE_D}' does not appear to be empty, which is unexpected) - you will need to restart DMS for changes to take effect" - fi - fi } function _create_keys() { @@ -195,6 +178,16 @@ function _create_keys() { PUBLIC_KEY_DNS_FILE="${BASE_FILE_NAME}.public.dns.txt" PRIVATE_KEY_FILE="${BASE_FILE_NAME}.private.txt" + 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 \ dkim_keygen \ @@ -226,7 +219,7 @@ function _check_permissions() { function _setup_default_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 (to '${DEFAULT_CONFIG_FILE}')" cat >"${DEFAULT_CONFIG_FILE}" << EOF @@ -253,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 } 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 38b83444..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,26 +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}'" - __rspamd__log 'warn' "Note that using '${RSPAMD_DMS_OVERRIDE_D}' and placing files manually in '${RSPAMD_OVERRIDE_D}' is not supported" - fi + cp "${RSPAMD_DMS_OVERRIDE_D}"/* "${RSPAMD_OVERRIDE_D}" fi if [[ ${ENABLE_AMAVIS} -eq 1 ]] || [[ ${ENABLE_SPAMASSASSIN} -eq 1 ]]; then @@ -304,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/tests/parallel/set1/spam_virus/rspamd_dkim.bats b/test/tests/parallel/set1/spam_virus/rspamd_dkim.bats index 76c301ea..215b334d 100644 --- a/test/tests/parallel/set1/spam_virus/rspamd_dkim.bats +++ b/test/tests/parallel/set1/spam_virus/rspamd_dkim.bats @@ -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 }