vim scripts/opendkim.sh

#!/bin/bash
# Script Version: 06
# Description: Generate and install OpenDKIM keys for a given domain and append KeyTable + SigningTable entries. Prints a flat one-line DNS TXT for BIND copy/paste.
# Set variables
# ========
YEAR=$(date +'%Y')
DOMTLD=$1
KEY_DIR=/etc/opendkim/keys/$DOMTLD
KEYTABLE=/etc/opendkim/KeyTable
SIGNINGTABLE=/etc/opendkim/SigningTable
KEYNAME=${2:-}  # optional explicit key label (defaults to leftmost label of domain)
# Functions
# ========
usage() {
   echo "Usage: $0 <domain.tld> [keylabel]"
   exit 1
}
append_keytable() {
   touch "$KEYTABLE"
   local KEY_LABEL
   if [ -n "$KEYNAME" ]; then
       KEY_LABEL="$KEYNAME"
   else
       KEY_LABEL="${DOMTLD%%.*}"   # leftmost label of domain (e.g., intxtonic for intxtonic.net)
   fi
   local SELECTOR="$YEAR"
   local LINE_DOMAIN_PART="${DOMTLD}:${SELECTOR}:${KEY_DIR}/${SELECTOR}.private"
   local LINE
   LINE=$(printf '%s\t%s' "$KEY_LABEL" "$LINE_DOMAIN_PART")
   if grep -Pq "^${KEY_LABEL}\t" "$KEYTABLE" || grep -Fq "$LINE_DOMAIN_PART" "$KEYTABLE"; then
       echo "[DEBUG] KeyTable already contains an entry for ${KEY_LABEL} or ${LINE_DOMAIN_PART}"
   else
       printf '%s\n' "$LINE" >> "$KEYTABLE"
       echo "[DEBUG] Appended to KeyTable: $LINE"
   fi
}
append_signingtable() {
   touch "$SIGNINGTABLE"
   local KEY_LABEL
   if [ -n "$KEYNAME" ]; then
       KEY_LABEL="$KEYNAME"
   else
       KEY_LABEL="${DOMTLD%%.*}"
   fi
   local PATTERN="*@${DOMTLD}"
   local LINE
   LINE=$(printf '%s\t%s' "$PATTERN" "$KEY_LABEL")
   if grep -Pq "^\Q${PATTERN}\E\t\Q${KEY_LABEL}\E$" "$SIGNINGTABLE"; then
       echo "[DEBUG] SigningTable already contains: $LINE"
   else
       sed -i -e "/^\Q${PATTERN}\E\t/d" "$SIGNINGTABLE"
       printf '%s\n' "$LINE" >> "$SIGNINGTABLE"
       echo "[DEBUG] Appended to SigningTable: $LINE"
   fi
}
# Print a single-line DNS TXT suitable for BIND zone files (no parentheses, two adjacent quoted strings)
print_flat_dns_line() {
   local TXT="$KEY_DIR/${YEAR}.txt"
   local SEL="${YEAR}._domainkey"
   local PART1 PART2
   PART1=$(awk -v RS='"' 'NR==2{print; exit}' "$TXT")
   PART2=$(awk -v RS='"' 'NR==4{print; exit}' "$TXT")
   if [ -z "$PART1" ] || [ -z "$PART2" ]; then
       echo "[WARN] Could not parse $TXT; showing raw file instead"
       cat "$TXT"
       return 1
   fi
   printf '%s\tIN\tTXT\t"%s""%s"\n' "$SEL" "$PART1" "$PART2"
}
# Main Process
# ========
[ -z "$DOMTLD" ] && usage
mkdir -p "$KEY_DIR"
cd "$KEY_DIR"
opendkim-genkey -s "$YEAR" -d "$DOMTLD"
chown opendkim:opendkim "${YEAR}.private"
chmod 600 "${YEAR}.private"
append_keytable
append_signingtable
# Display a copy-paste friendly flat TXT record only to stdout
print_flat_dns_line
systemctl restart opendkim postfix
echo "[DEBUG] OpenDKIM key generated for $DOMTLD with selector $YEAR and tables updated"