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
-
+
+
## 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