From f9c9c1e97be7e63176a0493f71ab1e22141a6054 Mon Sep 17 00:00:00 2001 From: Sven Hoexter Date: Wed, 26 May 2021 15:29:09 +0200 Subject: [PATCH] first take on dkim update script --- stormbind/dkim/dkim-key-rotation.sh | 98 +++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100755 stormbind/dkim/dkim-key-rotation.sh diff --git a/stormbind/dkim/dkim-key-rotation.sh b/stormbind/dkim/dkim-key-rotation.sh new file mode 100755 index 0000000..b334297 --- /dev/null +++ b/stormbind/dkim/dkim-key-rotation.sh @@ -0,0 +1,98 @@ +#!/bin/bash +# helper script to update dkim keys in bind9 and dkimpy-milter + +DOMAINS="stormbind.net raspe-box.de fusspflege-rita.de honig-aus-schlebusch.de" +KEYFOLDER="/etc/dkimpy-milter/keys" +CURKEYFILE="${KEYFOLDER}/curkey" +OLDKEYFILE="${KEYFOLDER}/oldkey" +SIGNTABLE="/etc/dkimpy-milter/signtable" +KEYTABLE="/etc/dkimpy-milter/keytable" +ZONEDIR="/etc/bind/zones" +ZONEFILE="${ZONEDIR}/dkim.inc" + +# generate a bind9 compatible TXT record based on the dkimpy generated .dns file +function genTXTrecord { + local keyname="$1" + local key="$2" + echo "${keyname}._domainkey IN TXT ( " + echo "${key}" | \ + fold | \ + sed -e 's/^/"/' -e 's/$/"/' + echo ") ;" +} + +# ensure keyfolder exist +test -d "${KEYFOLDER}" || mkdir "${KEYFOLDER}" + +# get current key name +if [ -f ${CURKEYFILE} ]; then + CURKEY="$(cat ${CURKEYFILE})" +else + # if there is no current key we still have to initialize the variable + echo "W: No current keyfile found - looked for ${CURKEYFILE}" + CURKEY="" +fi + +# check for old key file name +if [ -f ${OLDKEYFILE} ]; then + OLDKEY="$(cat ${OLDKEYFILE})" +else + echo "W: No old keyfile found - looked for ${OLDKEYFILE}" + OLDKEY="" +fi + +# make our execution idempotent and do not regenerate keys all the time +# check if the NEWKEY value differs by less than 7 - a week +NEWKEY="s$(date +%Y%m%d)" +if [[ $(( ${CURKEY#s} + 7 )) -le ${NEWKEY#s} ]]; then + # full blown invocation when we have a current and old key + DELETEKEY="${OLDKEY}" + OLDKEY="${CURKEY}" + echo "I: generating new keys with the name of ${NEWKEY} in folder ${KEYFOLDER}" + cd "${KEYFOLDER}" && dknewkey --ktype rsa "${NEWKEY}" + cd - +else + NEWKEY="${CURKEY}" + echo "W: NEWKEY date ${NEWKEY#s} is less than 7 days before OLDKEY ${OLDKEY#s}" + echo "W: No new key generated" +fi + +# generate bind dkim include with pub key +echo "I: writing DNS pubkey include" +genTXTrecord "${NEWKEY}" "$(cat ${KEYFOLDER}/${NEWKEY}.dns)" > "${ZONEFILE}" +if [ -n "${OLDKEY}" ]; then + genTXTrecord "${OLDKEY}" "$(cat ${KEYFOLDER}/${OLDKEY}.dns)" >> "${ZONEFILE}" +fi + +# recreate dkimpy-milter tables +> ${KEYTABLE} +> ${SIGNTABLE} +for x in ${DOMAINS}; do + echo "*@${x} ${x%.*}" >> ${SIGNTABLE} + echo "${x%.*} ${x}:${NEWKEY}:${KEYFOLDER}/${NEWKEY}.key" >> ${KEYTABLE} +done + +# update state files +echo "${NEWKEY}" > "${CURKEYFILE}" +echo "${OLDKEY}" > "${OLDKEYFILE}" + +# clean up prior old key +if [ -n "${DELETEKEY}" ]; then + rm "${KEYFOLDER}/${DELETEKEY}".{key,dns} +fi + +# update zone timestamps, verify zone +for x in ${DOMAINS}; do + SERIAL="$(sed -n '3p' ${x} | grep -Eo '[0-9]+')" + let SERIAL++ + sed -i -re "3s/[0-9]{10}/${SERIAL}/" "${ZONEDIR}/${x}" + named-checkzone "${x}" "${ZONEDIR}/${x}" || \ + ( echo "E: could not validate zone ${x} - exiting"; exit 23; ) +done + +# store changes in etckeeper +etckeeper commit "automatic commit by dkim key update script called as $0" + +# restart dkimpy-milter and reload bind9 +systemctl reload named.service && \ + systemctl reload dkimpy-milter.service -- 2.39.2