]> git.sven.stormbind.net Git - sven/scripts.git/commitdiff
first take on dkim update script
authorSven Hoexter <sven@stormbind.net>
Wed, 26 May 2021 13:29:09 +0000 (15:29 +0200)
committerSven Hoexter <sven@stormbind.net>
Wed, 26 May 2021 19:57:17 +0000 (21:57 +0200)
stormbind/dkim/dkim-key-rotation.sh [new file with mode: 0755]

diff --git a/stormbind/dkim/dkim-key-rotation.sh b/stormbind/dkim/dkim-key-rotation.sh
new file mode 100755 (executable)
index 0000000..b334297
--- /dev/null
@@ -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