--- /dev/null
+#!/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