From bcf88606eaf1e7399ca11ba8f9918a46ef0db461 Mon Sep 17 00:00:00 2001 From: sparrowhawk Date: Mon, 31 May 2021 11:25:29 +0200 Subject: [PATCH] Implement __opendkim and __opendkim_genkey type. --- type/__opendkim/files/opendkim.conf.sh | 64 +++++++++++++++ type/__opendkim/man.rst | 96 +++++++++++++++++++++++ type/__opendkim/manifest | 91 +++++++++++++++++++++ type/__opendkim/parameter/boolean | 1 + type/__opendkim/parameter/optional | 6 ++ type/__opendkim/parameter/required | 1 + type/__opendkim/singleton | 0 type/__opendkim_genkey/gencode-remote | 50 ++++++++++++ type/__opendkim_genkey/man.rst | 95 ++++++++++++++++++++++ type/__opendkim_genkey/manifest | 66 ++++++++++++++++ type/__opendkim_genkey/parameter/optional | 4 + type/__opendkim_genkey/parameter/required | 2 + 12 files changed, 476 insertions(+) create mode 100755 type/__opendkim/files/opendkim.conf.sh create mode 100644 type/__opendkim/man.rst create mode 100755 type/__opendkim/manifest create mode 100644 type/__opendkim/parameter/boolean create mode 100644 type/__opendkim/parameter/optional create mode 100644 type/__opendkim/parameter/required create mode 100644 type/__opendkim/singleton create mode 100755 type/__opendkim_genkey/gencode-remote create mode 100644 type/__opendkim_genkey/man.rst create mode 100755 type/__opendkim_genkey/manifest create mode 100644 type/__opendkim_genkey/parameter/optional create mode 100644 type/__opendkim_genkey/parameter/required diff --git a/type/__opendkim/files/opendkim.conf.sh b/type/__opendkim/files/opendkim.conf.sh new file mode 100755 index 0000000..a21eecc --- /dev/null +++ b/type/__opendkim/files/opendkim.conf.sh @@ -0,0 +1,64 @@ +#!/bin/sh -e +# Generate an opendkim.conf(5) file for opendkim(8). + + +# Optional chdir(2) +if [ "$BASEDIR" ]; +then + printf "BaseDirectory %s\n" "$BASEDIR" +fi + +# Optional canonicalization settings +if [ "$CANON" ]; +then + case "$CANON" in + "simple/simple") + : + ;; + "simple/relaxed") + : + ;; + "relaxed/simple") + : + ;; + "relaxed/relaxed") + : + ;; + *) + echo "Invalid Canonicalization setting!" >&2 + exit 1 + ;; + esac + printf "Canonicalization %s\n" "$CANON" +fi + +# Key and Domain tables +echo 'KeyTable /etc/opendkim/KeyTable' +echo 'SigningTable /etc/opendkim/SigningTable' + +# Required socket to listen on +printf "Socket %s\n" "${SOCKET:?}" + +# Optional subdomain signing settings +if [ "$SUBDOMAINS" ]; +then + printf "SubDomains %s\n" "$SUBDOMAINS" +fi + +# Optional request logging to syslog +if [ "$SYSLOG" ]; +then + echo "Syslog yes" +fi + +# Optional UMask specification +if [ "$UMASK" ]; +then + printf "UMask %s\n" "$UMASK" +fi + +# Optional UserID to change to +if [ "$USERID" ]; +then + printf "UserID %s\n" "$USERID" +fi diff --git a/type/__opendkim/man.rst b/type/__opendkim/man.rst new file mode 100644 index 0000000..205ca65 --- /dev/null +++ b/type/__opendkim/man.rst @@ -0,0 +1,96 @@ +cdist-type__opendkim(7) +======================= + +NAME +---- +cdist-type__opendkim - Configure an instance of OpenDKIM + + +DESCRIPTION +----------- +OpenDKIM is a DKIM signing and verifying filter for MTAs. This type enables the +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. + + +REQUIRED PARAMETERS +------------------- +socket + A string specifying a socket to listen on for communication with the MTA. See + `opendkim.conf(5)` for details on the syntax. + + +OPTIONAL PARAMETERS +------------------- +basedir + A directory to `chdir(2)` to before beginning operations. + +canonicalization + Directives for message canonicalization. See `opendkim.conf(5)` for details + on the syntax. + +subdomains + Explicitely control whether subdomains should be signed as well. Expects a + string containing 'Y', 'N', 'y', 'n', 'yes' or 'no'. + +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. + +custom-config + The string following this parameter is appended as-is in the configuration, to + enable more complex configurations. + +BOOLEAN PARAMETERS +------------------ +syslog + Log to syslog. + + +EXAMPLES +-------- + +.. code-block:: sh + + __opendkim \ + --socket inet:8891@localhost \ + --basedir /var/lib/opendkim \ + --canonicalization relaxed/simple \ + --subdomains no \ + --umask 002 \ + --syslog \ + --custom-config "Mode v" + + require='__opendkim' \ + __opendkim_genkey mykey \ + --domain example.com \ + --selector default \ + --sigkey example.com + + +SEE ALSO +-------- +`cdist-type__opendkim-genkey(7)` +`opendkim(8)` +`opendkim.conf(5)` + + +AUTHORS +------- +Joachim Desroches + + +COPYING +------- +Copyright \(C) 2021 Joachim Desroches. 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. diff --git a/type/__opendkim/manifest b/type/__opendkim/manifest new file mode 100755 index 0000000..e3325b4 --- /dev/null +++ b/type/__opendkim/manifest @@ -0,0 +1,91 @@ +#!/bin/sh -e +# +# 2021 Joachim Desroches (joachim.desroches@epfl.ch) +# +# This file is part of cdist. +# +# cdist is free software: 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. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# + +os=$(cat "${__global:?}/explorer/os") + +case "$os" in +'alpine') + : + ;; +*) + printf "__opendkim does not yet support %s.\n" "$os" >&2 + printf "Please contribute an implementation if you can.\n" >&2 + exit 1 + ;; +esac + +__package opendkim + +# Required parameters +SOCKET="$(cat "${__object:?}/parameter/socket")" +export SOCKET + +# Optional parameters +if [ -f "${__object:?}/parameter/basedir" ]; then + BASEDIR="$(cat "${__object:?}/parameter/basedir")" + export BASEDIR +fi + +if [ -f "${__object:?}/parameter/canonicalization" ]; then + CANON="$(cat "${__object:?}/parameter/canonicalization")" + export CANON +fi + +if [ -f "${__object:?}/parameter/subdomains" ]; then + SUBDOMAINS="$(cat "${__object:?}/parameter/subdomains")" + export SUBDOMAINS +fi + +if [ -f "${__object:?}/parameter/umask" ]; then + UMASK="$(cat "${__object:?}/parameter/umask")" + export UMASK +fi + +if [ -f "${__object:?}/parameter/userid" ]; then + USERID="$(cat "${__object:?}/parameter/userid")" + export USERID +fi + +# Boolean parameters +[ -f "${__object:?}/parameter/syslog" ] && export SYSLOG=yes + +# Generate and deploy configuration file. +source_file="${__object:?}/files/opendkim.conf" +target_file="/etc/opendkim/opendkim.conf" + +mkdir -p "${__object:?}/files" + +"${__type:?}/files/opendkim.conf.sh" >"$source_file" + +# Add user custom config +if [ -f "${__object:?}/parameter/custom-config" ]; then + echo "# Custom user config" >>"$source_file" + cat "${__object:?}/parameter/custom-config" >>"$source_file" +fi + +require="__package/opendkim" __file "$target_file" \ + --source "$source_file" --mode 0644 + +require="__package/opendkim" __start_on_boot opendkim + +require="__file${target_file}" \ + __check_messages opendkim \ + --pattern "^__file${target_file}" \ + --execute "service opendkim restart" diff --git a/type/__opendkim/parameter/boolean b/type/__opendkim/parameter/boolean new file mode 100644 index 0000000..24e5b1b --- /dev/null +++ b/type/__opendkim/parameter/boolean @@ -0,0 +1 @@ +syslog diff --git a/type/__opendkim/parameter/optional b/type/__opendkim/parameter/optional new file mode 100644 index 0000000..af59609 --- /dev/null +++ b/type/__opendkim/parameter/optional @@ -0,0 +1,6 @@ +basedir +canonicalization +subdomains +umask +userid +custom-config diff --git a/type/__opendkim/parameter/required b/type/__opendkim/parameter/required new file mode 100644 index 0000000..3cdd2fd --- /dev/null +++ b/type/__opendkim/parameter/required @@ -0,0 +1 @@ +socket diff --git a/type/__opendkim/singleton b/type/__opendkim/singleton new file mode 100644 index 0000000..e69de29 diff --git a/type/__opendkim_genkey/gencode-remote b/type/__opendkim_genkey/gencode-remote new file mode 100755 index 0000000..65ce934 --- /dev/null +++ b/type/__opendkim_genkey/gencode-remote @@ -0,0 +1,50 @@ +#!/bin/sh -e +# +# 2021 Joachim Desroches (joachim.desroches@epfl.ch) +# +# This file is part of cdist. +# +# cdist is free software: 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. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# + +# Required parameters +DOMAIN="$(cat "${__object:?}/parameter/domain")" +SELECTOR="$(cat "${__object:?}/parameter/selector")" + +# Optional parameters +BITS= +if [ -f "${__object:?}/parameter/bits" ]; then + BITS="-b $(cat "${__object:?}/parameter/bits")" +fi + +DIRECTORY="/var/db/dkim/" +if [ -f "${__object:?}/parameter/directory" ]; then + DIRECTORY="$(cat "${__object:?}/parameter/directory")" +fi + +# Boolean parameters +SUBDOMAINS= +if [ -f "${__object:?}/parameter/no-subdomains" ]; then + SUBDOMAINS='--nosubdomains' +fi + +RESTRICTED='--restrict' +if [ -f "${__object:?}/parameters/unrestricted" ]; then + RESTRICTED= +fi + +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" +fi diff --git a/type/__opendkim_genkey/man.rst b/type/__opendkim_genkey/man.rst new file mode 100644 index 0000000..46e6505 --- /dev/null +++ b/type/__opendkim_genkey/man.rst @@ -0,0 +1,95 @@ +cdist-type__opendkim_genkey(7) +============================== + +NAME +---- +cdist-type__opendkim_genkey - Generate DKIM keys suitable for OpenDKIM + + +DESCRIPTION +----------- + +This type uses the `opendkim-genkey(8)` to generate signing keys suitable for +usage by `opendkim(8)` to sign outgoing emails. Then, a line with the domain, +selector and keyname in the `$selector._domainkey.$domain` format will be added +to the OpenDKIM key table located at `/etc/opendkim/KeyTable`. Finally, a line +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. + +REQUIRED PARAMETERS +------------------- +domain + The domain to generate the key for. + +selector + The DKIM selector to generate the key for. + + +OPTIONAL PARAMETERS +------------------- +bits + The size of the generated key, in bits. The default is 1024, the recommended + by the DKIM standard. + +directory + The directory in which to generate the key, `/var/db/dkim/` by default. + +sigkey + The key used in the SigningTable for this signing key. Defaults to the + specified domain. If `%`, OpenDKIM will replace it with the domain found + in the `From:` header. See `opendkim.conf(5)` for more options. + +BOOLEAN PARAMETERS +------------------ +no-subdomains + Disallows subdomain signing by this key. + +unrestricted + Do not restrict this key to email signing usage. + + +EXAMPLES +-------- + +.. code-block:: sh + + __opendkim \ + --socket inet:8891@localhost \ + --basedir /var/lib/opendkim \ + --canonicalization relaxed/simple \ + --subdomains no \ + --umask 002 \ + --syslog + + require='__opendkim' \ + __opendkim_genkey default \ + --domain example.com \ + --selector default + + __opendkim_genkey myfoo \ + --domain foo.com \ + --selector backup + + +SEE ALSO +-------- +`opendkim(8)` +`opendkim-genkey(8)` +`cdist-type__opendkim(7)` + + +AUTHORS +------- +Joachim Desroches + + +COPYING +------- +Copyright \(C) 2021 Joachim Desroches. 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. diff --git a/type/__opendkim_genkey/manifest b/type/__opendkim_genkey/manifest new file mode 100755 index 0000000..7c506e9 --- /dev/null +++ b/type/__opendkim_genkey/manifest @@ -0,0 +1,66 @@ +#!/bin/sh -e +# +# 2021 Joachim Desroches (joachim.desroches@epfl.ch) +# +# This file is part of cdist. +# +# cdist is free software: 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. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# + + +os=$(cat "${__global:?}/explorer/os") + +case "$os" in +'alpine') + : +;; +*) + cat <<- EOF >&2 + __opendkim_genkey currently only supports Alpine Linux. Please + contribute an implementation for $os if you can. + EOF +;; +esac + +SELECTOR="$(cat "${__object:?}/parameter/selector")" +DOMAIN="$(cat "${__object:?}/parameter/domain")" + +DIRECTORY="/var/db/dkim/" +if [ -f "${__object:?}/parameter/directory" ]; +then + DIRECTORY="$(cat "${__object:?}/parameter/directory")" +fi + +SIGKEY="${DOMAIN:?}" +if [ -f "${__object:?}/parameter/sigkey" ]; +then + SIGKEY="$(cat "${__object:?}/parameter/sigkey")" +fi + +__package opendkim-utils + +require='__package/opendkim-utils' \ + __file /etc/opendkim/KeyTable +require='__package/opendkim-utils' \ + __file /etc/opendkim/SigningTable + +require='__file/etc/opendkim/KeyTable' \ + __line "line-key-${__object_id:?}" \ + --file /etc/opendkim/KeyTable \ + --line "${SELECTOR:?}._domainkey.${DOMAIN:?} ${DOMAIN:?}:${SELECTOR:?}:${DIRECTORY:?}${SELECTOR:?}.private" + +require='__file/etc/opendkim/SigningTable' \ + __line "line-sig-${__object_id:?}" \ + --file /etc/opendkim/SigningTable \ + --line "${SIGKEY:?} ${SELECTOR:?}._domainkey.${DOMAIN:?}" diff --git a/type/__opendkim_genkey/parameter/optional b/type/__opendkim_genkey/parameter/optional new file mode 100644 index 0000000..e44793f --- /dev/null +++ b/type/__opendkim_genkey/parameter/optional @@ -0,0 +1,4 @@ +bits +directory +unrestricted +sigkey diff --git a/type/__opendkim_genkey/parameter/required b/type/__opendkim_genkey/parameter/required new file mode 100644 index 0000000..4dacb77 --- /dev/null +++ b/type/__opendkim_genkey/parameter/required @@ -0,0 +1,2 @@ +domain +selector