[__opendkim*] FreeBSD support and minor fixes

While adding FreeBSD support to the type I noticed various issues:

- We were making sure that the KeyTable and SigningTable were created in
  __opendkim_genkey, but that was being done with the default cdist permissions
  (0400) which could result in issues when reloading the service after privilege
  drop.
  This is addressed by checking that it exists/creating it in __opendkim (just
  once, not once per __opendkim_genkey call) with laxer permissions (0444).
- In __opendkim, the service was being started after the config file was
  installed. This is insufficient as OpenDKIM will refuse to start with the
  generated config if either SigningTable or KeyTable do not exist yet.
- __opendkim_genkey had the implicit assumption that the --directory parameter
  always ended in a slash. This was not documented and error-prone; we are now
  a bit laxer and add the trailing slash if it is missing.
- __opendkim_genkey was not changing permissions for the resulting .txt file.
  This was not critical for it to function, but it was inconsistent.
- As documented in #17, __opendkim allows for a --userid parameter that might
  cause issues with keys generated by __opendkim_genkey.
  This issue has not been addressed yet, but I recommend deprecating the
  --userid parameter.
This commit is contained in:
evilham 2022-03-10 20:08:51 +01:00 committed by Evilham
parent 422b97bc1b
commit ecd10de2d3
Signed by: evilham
GPG Key ID: AE3EE30D970886BF
6 changed files with 79 additions and 30 deletions

View File

@ -1,6 +1,7 @@
#!/bin/sh -e
# Generate an opendkim.conf(5) file for opendkim(8).
echo "# Managed remotely, manual changes will be lost."
# Optional chdir(2)
if [ "$BASEDIR" ];
@ -33,8 +34,8 @@ then
fi
# Key and Domain tables
echo 'KeyTable /etc/opendkim/KeyTable'
echo 'SigningTable /etc/opendkim/SigningTable'
echo "KeyTable ${CFG_DIR}/KeyTable"
echo "SigningTable ${CFG_DIR}/SigningTable"
# Required socket to listen on
printf "Socket %s\n" "${SOCKET:?}"

View File

@ -14,8 +14,8 @@ installation and basic configuration of an instance of OpenDKIM.
Note that this type does not generate or ensure that a key is present: use
`cdist-type__opendkim-genkey(7)` for that.
Note that this type is currently only implemented for Alpine Linux. Please
contribute an implementation if you can.
Note that this type is currently only implemented for Alpine Linux and FreeBSD.
Please contribute an implementation if you can.
REQUIRED PARAMETERS
@ -42,8 +42,9 @@ umask
Set the umask for the socket and PID file.
userid
Change the user the opendkim program is to run as. By default, Alpine Linux's
OpenRC service will set this to `opendkim` on the command-line.
Change the user the opendkim program is to run as.
By default, Alpine Linux's OpenRC service will set this to `opendkim` on the
command-line and FreeBSD's rc will set it to `mailnull`.
custom-config
The string following this parameter is appended as-is in the configuration, to
@ -86,11 +87,12 @@ SEE ALSO
AUTHORS
-------
Joachim Desroches <joachim.desroches@epfl.ch>
Evilham <contact@evilham.com>
COPYING
-------
Copyright \(C) 2021 Joachim Desroches. You can redistribute it
Copyright \(C) 2022 Joachim Desroches, Evilham. You can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

View File

@ -20,16 +20,23 @@
os=$(cat "${__global:?}/explorer/os")
CFG_DIR="/etc/opendkim"
service="opendkim"
case "$os" in
'alpine')
:
;;
'freebsd')
CFG_DIR="/usr/local/etc/mail"
service="milter-opendkim"
;;
*)
printf "__opendkim does not yet support %s.\n" "$os" >&2
printf "Please contribute an implementation if you can.\n" >&2
exit 1
;;
esac
export CFG_DIR
__package opendkim
@ -68,7 +75,7 @@ fi
# Generate and deploy configuration file.
source_file="${__object:?}/files/opendkim.conf"
target_file="/etc/opendkim/opendkim.conf"
target_file="${CFG_DIR}/opendkim.conf"
mkdir -p "${__object:?}/files"
@ -83,9 +90,22 @@ fi
require="__package/opendkim" __file "$target_file" \
--source "$source_file" --mode 0644
require="__package/opendkim" __start_on_boot opendkim
require="__package/opendkim" __start_on_boot "${service}"
require="__file${target_file}" \
# Ensure Key and Signing tables exist and have proper permissions
key_table="${CFG_DIR}/KeyTable"
signing_table="${CFG_DIR}/SigningTable"
require="__package/opendkim" \
__file "${key_table}" \
--mode 444
require="__package/opendkim" \
__file "${signing_table}" \
--mode 444
require="__file${target_file} __file${key_table}
__file${signing_table} __start_on_boot/${service}" \
__check_messages opendkim \
--pattern "^__file${target_file}" \
--execute "service opendkim restart"
--execute "service ${service} restart"

View File

@ -30,7 +30,8 @@ fi
DIRECTORY="/var/db/dkim/"
if [ -f "${__object:?}/parameter/directory" ]; then
DIRECTORY="$(cat "${__object:?}/parameter/directory")"
# Be forgiving about a lack of trailing slash
DIRECTORY="$(sed -E 's!([^/])$!\1/!' < "${__object:?}/parameter/directory")"
fi
# Boolean parameters
@ -44,7 +45,12 @@ if [ -f "${__object:?}/parameters/unrestricted" ]; then
RESTRICTED=
fi
user="$(cat "${__object:?}/user")"
group="$(cat "${__object:?}/group")"
if ! [ -f "${DIRECTORY}${SELECTOR}.private" ]; then
echo "opendkim-genkey $BITS --domain=$DOMAIN --directory=$DIRECTORY $RESTRICTED --selector=$SELECTOR $SUBDOMAINS"
echo "chown opendkim:opendkim ${DIRECTORY}${SELECTOR}.private"
echo "chown ${user}:${group} ${DIRECTORY}${SELECTOR}.private"
# This is usually generated, if it weren't we do not want to fail
echo "chown ${user}:${group} ${DIRECTORY}${SELECTOR}.txt || true"
fi

View File

@ -17,8 +17,8 @@ will be added to the OpenDKIM signing table, using either the domain or the
provided key for the `domain:selector:keyfile` value in the table. An existing
key will not be overwritten.
Currently, this type is only implemented for Alpine Linux. Please contribute an
implementation if you can.
Currently, this type is only implemented for Alpine Linux and FreeBSD.
Please contribute an implementation if you can.
REQUIRED PARAMETERS
-------------------
@ -85,11 +85,12 @@ SEE ALSO
AUTHORS
-------
Joachim Desroches <joachim.desroches@epfl.ch>
Evilham <contact@evilham.com>
COPYING
-------
Copyright \(C) 2021 Joachim Desroches. You can redistribute it
Copyright \(C) 2022 Joachim Desroches, Evilham. You can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

View File

@ -21,10 +21,18 @@
os=$(cat "${__global:?}/explorer/os")
CFG_DIR="/etc/opendkim"
user="opendkim"
group="opendkim"
case "$os" in
'alpine')
:
;;
'freebsd')
CFG_DIR="/usr/local/etc/mail"
user="mailnull"
group="mailnull"
;;
*)
cat <<- EOF >&2
__opendkim_genkey currently only supports Alpine Linux. Please
@ -32,6 +40,9 @@ case "$os" in
EOF
;;
esac
# Persist user and group for gencode-remote
printf '%s' "${user}" > "${__object:?}/user"
printf '%s' "${group}" > "${__object:?}/group"
SELECTOR="$(cat "${__object:?}/parameter/selector")"
DOMAIN="$(cat "${__object:?}/parameter/domain")"
@ -39,7 +50,8 @@ DOMAIN="$(cat "${__object:?}/parameter/domain")"
DIRECTORY="/var/db/dkim/"
if [ -f "${__object:?}/parameter/directory" ];
then
DIRECTORY="$(cat "${__object:?}/parameter/directory")"
# Be forgiving about a lack of trailing slash
DIRECTORY="$(sed -E 's!([^/])$!\1/!' < "${__object:?}/parameter/directory")"
fi
SIGKEY="${DOMAIN:?}"
@ -48,19 +60,26 @@ then
SIGKEY="$(cat "${__object:?}/parameter/sigkey")"
fi
__package opendkim-utils
# Ensure the key-container directory exists with the proper permissions
__directory "${DIRECTORY}" \
--mode 0750 \
--owner "${user}" --group "${group}"
require='__package/opendkim-utils' \
__file /etc/opendkim/KeyTable
require='__package/opendkim-utils' \
__file /etc/opendkim/SigningTable
# OS-specific code
case "$os" in
'alpine')
# This is needed for opendkim-genkey
__package opendkim-utils
;;
esac
require='__file/etc/opendkim/KeyTable' \
__line "line-key-${__object_id:?}" \
--file /etc/opendkim/KeyTable \
--line "${SELECTOR:?}._domainkey.${DOMAIN:?} ${DOMAIN:?}:${SELECTOR:?}:${DIRECTORY:?}${SELECTOR:?}.private"
key_table="${CFG_DIR}/KeyTable"
signing_table="${CFG_DIR}/SigningTable"
require='__file/etc/opendkim/SigningTable' \
__line "line-sig-${__object_id:?}" \
--file /etc/opendkim/SigningTable \
--line "${SIGKEY:?} ${SELECTOR:?}._domainkey.${DOMAIN:?}"
__line "line-key-${__object_id:?}" \
--file "${key_table}" \
--line "${SELECTOR:?}._domainkey.${DOMAIN:?} ${DOMAIN:?}:${SELECTOR:?}:${DIRECTORY:?}${SELECTOR:?}.private"
__line "line-sig-${__object_id:?}" \
--file "${signing_table}" \
--line "${SIGKEY:?} ${SELECTOR:?}._domainkey.${DOMAIN:?}"