Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions target/bin/rspamd-dkim
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,6 @@ ${ORANGE}EXIT STATUS${RESET}
"
}

function __do_as_rspamd_user() {
local COMMAND=${1:?Command required when using __do_as_rspamd_user}
_log 'trace' "Running '${*}' as user '_rspamd' now"
shift 1
su -l '_rspamd' -s "$(command -v "${COMMAND}")" -- "${@}"
}

function _parse_arguments() {
FORCE=0
KEYTYPE='rsa'
Expand Down
12 changes: 12 additions & 0 deletions target/scripts/helpers/rspamd.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@

# shellcheck disable=SC2034 # VAR appears unused.

# Perform a specific command as the Rspamd user (`_rspamd`). This is useful
# in case you want to have correct permissions on newly created files or if
# you want to check whether Rspamd can perform a specific action.
function __do_as_rspamd_user() {
_log 'trace' "Running '${*}' as user '_rspamd'"
su _rspamd -s /bin/bash -c "${*}"
}

# Calling this function brings common Rspamd-related environment variables
# into the current context. The environment variables are `readonly`, i.e.
# they cannot be modified. Use this function when you require common directory
# names, file names, etc.
function _rspamd_get_envs() {
readonly RSPAMD_LOCAL_D='/etc/rspamd/local.d'
readonly RSPAMD_OVERRIDE_D='/etc/rspamd/override.d'
Expand Down
41 changes: 41 additions & 0 deletions target/scripts/startup/setup.d/security/rspamd.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ function _setup_rspamd() {
__rspamd__setup_check_authenticated
_rspamd_handle_user_modules_adjustments # must run last

# only performing checks, no further setup handled from here onwards
__rspamd__check_dkim_permissions

__rspamd__log 'trace' '---------- Setup finished ----------'
else
_log 'debug' 'Rspamd is disabled'
Expand Down Expand Up @@ -280,6 +283,12 @@ function __rspamd__setup_hfilter_group() {
fi
}

# If 'RSPAMD_CHECK_AUTHENTICATED' is enabled, then content checks for all users, i.e.
# also for authenticated users, are performed.
#
# The default that DMS ships does not check authenticated users. In case the checks are
# enabled, this function will remove the part of the Rspamd configuration that disables
# checks for authenticated users.
function __rspamd__setup_check_authenticated() {
local MODULE_FILE="${RSPAMD_LOCAL_D}/settings.conf"
readonly MODULE_FILE
Expand All @@ -294,3 +303,35 @@ function __rspamd__setup_check_authenticated() {
"${MODULE_FILE}"
fi
}

# This function performs a simple check: go through DKIM configuration files, acquire
# all private key file locations and check whether they exist and whether they can be
# accessed by Rspamd.
function __rspamd__check_dkim_permissions() {
local DKIM_CONF_FILES DKIM_KEY_FILES
[[ -f ${RSPAMD_LOCAL_D}/dkim_signing.conf ]] && DKIM_CONF_FILES+=("${RSPAMD_LOCAL_D}/dkim_signing.conf")
[[ -f ${RSPAMD_OVERRIDE_D}/dkim_signing.conf ]] && DKIM_CONF_FILES+=("${RSPAMD_OVERRIDE_D}/dkim_signing.conf")

# Here, we populate DKIM_KEY_FILES which we later iterate over. DKIM_KEY_FILES
# contains all keys files configured by the user.
local FILE
for FILE in "${DKIM_CONF_FILES[@]}"; do
readarray -t DKIM_KEY_FILES_TMP < <(grep -o -E 'path = .*' "${FILE}" | cut -d '=' -f 2 | tr -d ' ";')
DKIM_KEY_FILES+=("${DKIM_KEY_FILES_TMP[@]}")
done
Comment on lines +315 to +321
Copy link
Copy Markdown
Member

@polarathene polarathene Nov 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be better handled in future by new proposed approach with DKIM files generated having a complimentary rspamd.k or rspamd.yaml config beside the keypair files (although the proposed file layout covers a fair amount of that information itself):

Example fetches the separate configs and produces output YAML (dynamic on-demand generation for rspamd config instead of manually editing/updating the domain section):

$ docker run --rm --pull=always -v "/tmp/config:/config:ro" kcllang/kcl:main bash -c \
  'find /config/dkim/keys -type f -name "rspamd.k" | xargs kcl /config/main.k'

main: Pulling from kcllang/kcl
Digest: sha256:094150067c1c1079e320dc1f6a1c2ed68dcf92d09d1f428e8dd760c96f619ab6
Status: Image is up to date for kcllang/kcl:main

domain:
  example.com:
    selectors:
    - path: /config/dkim/keys/example.com/mail-ec/private.pem
      selector: mail-ec
    - path: /config/dkim/keys/example.com/mail-rsa/private.pem
      selector: mail-rsa
  example.org:
    selectors:
    - path: /config/dkim/keys/example.org/mail-rsa/private.pem
      selector: mail-rsa

Alternative example fetches the file paths of the separate configs to generate a YAML list as config:

# Find the `rspamd.k` files and output a YAML list (filepath prefixed with `- `) as input into `yq`:
# NOTE: Just pipe to `yq` with nothing else after to get a pure YAML list from the stdin input
$ find /config/dkim/keys -type f -name "rspamd.k" -exec printf '- %s\n' {} + \
  | yq '{ "kcl_cli_configs": { "files": . } }'

kcl_cli_configs:
  files:
    - /config/dkim/keys/example.com/mail-ec/rspamd.k
    - /config/dkim/keys/example.com/mail-rsa/rspamd.k
    - /config/dkim/keys/example.org/mail-rsa/rspamd.k

Easy to generate and iterate over in bash similar to what you're doing above if needed (the .k / KCL files can be ignored and stick to plain YAML, unless you want config features like immutability).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just as a note for me: will be deferred to a future PR where DKIM is reworked.


for FILE in "${DKIM_KEY_FILES[@]}"; do
if [[ -f ${FILE} ]]; then
__rspamd__log 'trace' "Checking DKIM file '${FILE}'"
# See https://serverfault.com/a/829314 for an explanation on `-exec false {} +`
# We additionally resolve symbolic links to check the permissions of the actual files
if find "$(realpath -eL "${FILE}")" -user _rspamd -or -group _rspamd -or -perm -o=r -exec false {} +; then
__rspamd__log 'warn' "Rspamd DKIM private key file '${FILE}' does not appear to have correct permissions/ownership for Rspamd to use it"
else
__rspamd__log 'trace' "DKIM file '${FILE}' permissions and ownership appear correct"
fi
else
__rspamd__log 'warn' "Rspamd DKIM private key file '${FILE}' is configured for usage, but does not appear to exist"
fi
done
}