#!/usr/bin/env bash ##################################################### # This script require the following DNS SETUP!!!! # SEE: # https://git.giaever.org/joachimmg/dnssec-signer) # # USAGE: # # 1. Make `opendkim-setter` executable: # chmod +x /path/to/opendkim-setter # # 2. Run: # ./path/to/opendkim-setter # 3. Or for every domain already signed by OpenDKIM # ./path/to/opendkim-setter # ###################################################### SELF="$(basename ${0})" ###################################################### # START OF CONFIG # ###################################################### # SET YOU SYSTEM SPECIFIC DATA (which systemctl e.g) # SELF=$(basename $0) DKIMUSER="opendkim" DKIMGRP="${DKIMUSER}" DKIMCONF="/etc/opendkim" KEYTABLE="${DKIMCONF}/key.table" SIGNTABLE="${DKIMCONF}/signing.table" KEYDIR="${DKIMCONF}/keys" ZONESDIR="/etc/bind/zones" KEYGEN=/usr/bin/opendkim-genkey SYSCTL=/bin/systemctl JOURCTL=/bin/journalctl LOGGER=/usr/bin/logger LOGGERFLAGN="-t $(whoami) -p daemon.info" LOGGERFLAGE="-t $(whoami) -p daemon.err" RESIGNDNS=1 DNSTOOL=/usr/bin/dnssec-signer ###################################################### # END OF CONFIG # ###################################################### function error_msg { FOR=${1} ERRMSG="${2}" echo -e "\e[31m[${SELF}:\e[1m${FOR}\e[21m]:\e[0m ${ERRMSG}" ${LOGGER} ${LOGGERFLAGE} "[${SELF}:${FOR}]: ${ERRMSG}" } function note_msg { FOR=${1} NOTEMSG="${2}" echo -e "\e[32m[${SELF}:\e[1m${FOR}\e[21m]:\e[0m ${NOTEMSG}" ${LOGGER} ${LOGGERFLAGN} "[${SELF}:${FOR}]: ${NOTEMSG}" } if [[ ${EUID} -ne 0 ]]; then error_msg "${USER}" "Must execute file as root." exit 1 fi #function remove_signing_table { # grep -v "*@${1} " "${SIGNTABLE}" > "${TMPTBL}" && mv "${TMPTBL}" "${SIGNTABLE}" #} function update_signing_table { grep -q "^*@${1}" "${SIGNTABLE}" if [ $? -ne 0 ]; then note_msg "${1}" "Added to signing table" echo "*@${1} ${1}" >> "${SIGNTABLE}" fi } function update_key_table { grep -q "^${1}" "${KEYTABLE}" if [ $? -eq 0 ]; then note_msg "${1}" "Updated key in key table" sed -i 's,^'"${1}"'[^\n]\+,'"${1}"' '"${1}"':'"${2}"':'"${3}"',' "${KEYTABLE}" else note_msg "${1}" "Added key to key table" echo "${1} ${1}:${2}:${3}" >> "${KEYTABLE}" fi } function dkim { ENTRY="${1}" ENTRYDIR="${KEYDIR}/${ENTRY}" ENTRYZONE="${ZONESDIR}/${ENTRY}/db" DATE=$(date +%Y%m) PRIVATEKEY="${ENTRYDIR}/${DATE}.private" DOMAINKEY="${ENTRYDIR}/${DATE}.txt" note_msg "${ENTRY}" "DKIM Signing" if ! [ -w "${ENTRYZONE}" ]; then error_msg "${ENTRY}" "There is not zone file. Abort" return 1 fi if ! [ -d "${ENTRYDIR}" ]; then note_msg "${ENTRY}" "Creating directory for entry" mkdir -p "${ENTRYDIR}" fi cd "${ENTRYDIR}" ${KEYGEN} -b 2048 -h rsa-sha256 -r -s "${DATE}" -d "${ENTRY}" -v if [ $? -ne 0 ]; then error_msg "${ENTRY}" "Error generating keys" fi KEYCONTENT=$(sed -e 's/h\=rsa-sha256/h\=sha256/' "${DOMAINKEY}" | tr '\n' '\r') ZONE=$(cat "${ENTRYZONE}" | tr '\n' '\r') grep -Eq "[0-9]{6}._dom" <<< "${ZONE}" if [ $? -eq 0 ]; then note_msg "${ENTRY}" "Altering DKIM-record in zone file" sed -e 's,[0-9]\{6\}._dom.*\-\+\sDKIM[^\r]\+\r\?\+,'"${KEYCONTENT}"',' <<< "${ZONE}" | tr '\r' '\n' > "${ENTRYZONE}" sed -i '${/^$/d;}' "${ENTRYZONE}" else note_msg "${ENTRY}" "Adding DKIM-record in zone file" echo -e "${ZONE}\r; DKIM for ${DOMAINKEY} start\r${KEYCONTENT}" | tr '\r' '\n' > "${ENTRYZONE}" fi update_signing_table "${ENTRY}" update_key_table "${ENTRY}" "${DATE}" "${PRIVATEKEY}" note_msg "${ENTRY}" "Signing successful" } # Collect arguments (zones) ENTRIES="${*}" IFS=' ', read -r -a ENTRIES <<< "${ENTRIES}" if [ ${#ENTRIES[@]} -ne 0 ]; then note_msg "date" "$(date)" note_msg "${#ENTRIES[@]}" "Start signing" CWDIR=$(pwd) for ENTRY in "${ENTRIES[@]}"; do dkim "${ENTRY}" done cd "${CWDIR}" chown -R "${DKIMUSER}:${DKIMGROUP}" "${DKIMCONF}" chmod -R go-rw "${DKIMCONF}" if [ "${RESIGNDNS}" -eq 1 ]; then note_msg "$(basename ${SYSCTL})" "Restarting opendkim.service" ${SYSCTL} restart "opendkim.service" if [ $? -ne 0 ]; then ${JOURCTL} -l 10 --unit "opendkim.service" | xargs -0 fi ${DNSTOOL} "${ENTRIES[@]}" fi else for ENTRY in $(cat "${SIGNTABLE}"); do if ! [[ "${ENTRY}" == "*"* ]]; then ENTRIES[${#ENTRIES[@]}]="${ENTRY}" fi done ${SELF} "${ENTRIES[@]}" fi