diff --git a/.gitignore b/.gitignore index d7c504c..b343367 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ data -dkim +./dkim filter mail mailqueue diff --git a/script/dkim/01-generate-keys.sh b/script/dkim/01-generate-keys.sh new file mode 100755 index 0000000..935b3d0 --- /dev/null +++ b/script/dkim/01-generate-keys.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +# Prosess 1: +# Genererer DKIM private/public key-filer for ett eller flere domener. +# +# Filer lages under: +# private/dkim/..private.pem +# private/dkim/..public.pem +# +# Dette scriptet er trygt å publisere. +# Selve nøklene ligger i private/, som skal være i .gitignore. + +selector="${DKIM_SELECTOR:-mail}" + +usage() { + cat < [domene...] + +Eksempel: + $0 tvheggland.no privix.no + +Valgfritt: + DKIM_SELECTOR=mail $0 tvheggland.no +EOF +} + +if [[ $# -lt 1 ]]; then + usage + exit 1 +fi + +mkdir -p private/dkim +chmod 700 private private/dkim + +for domain in "$@"; do + private_key="private/dkim/${domain}.${selector}.private.pem" + public_key="private/dkim/${domain}.${selector}.public.pem" + + if [[ -e "$private_key" || -e "$public_key" ]]; then + echo "SKIP: DKIM-filer finnes allerede for ${domain}" + echo " $private_key" + echo " $public_key" + echo + continue + fi + + openssl genrsa -out "$private_key" 2048 + + openssl rsa \ + -in "$private_key" \ + -pubout \ + -out "$public_key" >/dev/null 2>&1 + + chmod 600 "$private_key" "$public_key" + + echo "OK: Genererte DKIM-nøkler for ${domain}" + echo " Privat nøkkel: $private_key" + echo " Offentlig nøkkel: $public_key" + echo +done diff --git a/script/dkim/02-import-to-mailu.sh b/script/dkim/02-import-to-mailu.sh new file mode 100755 index 0000000..40ffc61 --- /dev/null +++ b/script/dkim/02-import-to-mailu.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +# Prosess 2: +# Importerer alle private DKIM-nøkler fra private/dkim/ til Mailu. +# +# Leser: +# private/dkim/..private.pem +# +# Skriver: +# private/mailu-dkim-import.yml +# +# Dette scriptet er trygt å publisere. +# Importfilen og private nøkler ligger under private/, som skal være i .gitignore. + +selector="${DKIM_SELECTOR:-mail}" +import_file="private/mailu-dkim-import.yml" + +mapfile -t private_keys < <( + find private/dkim -maxdepth 1 -type f -name "*.${selector}.private.pem" | sort +) + +if [[ ${#private_keys[@]} -eq 0 ]]; then + echo "FEIL: Fant ingen private DKIM-nøkler." + echo "Forventet filer som:" + echo " private/dkim/.${selector}.private.pem" + exit 1 +fi + +{ + echo "domain:" + for private_key in "${private_keys[@]}"; do + filename="$(basename "$private_key")" + domain="${filename%.${selector}.private.pem}" + + echo " - name: ${domain}" + echo " dkim_key: |" + sed 's/^/ /' "$private_key" + done +} > "$import_file" + +chmod 600 "$import_file" + +echo "Importfil laget:" +echo " $import_file" +echo +echo "Domener som blir importert:" +for private_key in "${private_keys[@]}"; do + filename="$(basename "$private_key")" + domain="${filename%.${selector}.private.pem}" + echo " - $domain" +done + +echo +echo "Dry-run mot Mailu:" +docker compose exec -T admin flask mailu config-import \ + --update \ + --dry-run \ + --verbose \ + - < "$import_file" + +echo +read -r -p "Importere DKIM-nøklene i Mailu nå? Skriv YES: " confirm + +if [[ "$confirm" != "YES" ]]; then + echo "Avbrutt. Ingen endring gjort." + exit 1 +fi + +docker compose exec -T admin flask mailu config-import \ + --update \ + --verbose \ + - < "$import_file" + +echo +echo "DKIM-status i Mailu:" +docker compose exec -T admin flask mailu config-export domain \ + | grep -A5 -E 'name:|dkim_key' + +echo +echo "Restarter relevante Mailu-tjenester hvis de finnes..." +services="$(docker compose ps --services)" + +for svc in admin smtp antispam; do + if echo "$services" | grep -qx "$svc"; then + docker compose restart "$svc" + fi +done + +echo +echo "OK: DKIM-nøkler importert til Mailu." diff --git a/script/dkim/03-print-domeneshop-records.sh b/script/dkim/03-print-domeneshop-records.sh new file mode 100755 index 0000000..9bc184d --- /dev/null +++ b/script/dkim/03-print-domeneshop-records.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +# Prosess 3: +# Skriver ut DNS TXT-recordene som skal legges inn i Domeneshop. +# +# Leser: +# private/dkim/..public.pem +# +# Skriver: +# private/dkim-domeneshop-records.txt +# +# Dette scriptet printer bare PUBLIC key. Det er ikke privatnøkkelen. +# Likevel lagres output under private/ for å holde repoet ryddig. + +selector="${DKIM_SELECTOR:-mail}" +output_file="private/dkim-domeneshop-records.txt" + +mapfile -t public_keys < <( + find private/dkim -maxdepth 1 -type f -name "*.${selector}.public.pem" | sort +) + +if [[ ${#public_keys[@]} -eq 0 ]]; then + echo "FEIL: Fant ingen offentlige DKIM-nøkler." + echo "Forventet filer som:" + echo " private/dkim/.${selector}.public.pem" + exit 1 +fi + +{ + for public_key in "${public_keys[@]}"; do + filename="$(basename "$public_key")" + domain="${filename%.${selector}.public.pem}" + pubkey="$(grep -v -- '-----' "$public_key" | tr -d '\n\r ')" + + if [[ -z "$pubkey" ]]; then + echo "FEIL: Public key ble tom for ${domain}" >&2 + exit 1 + fi + + echo "============================================================" + echo "DKIM for ${domain}" + echo "============================================================" + echo + echo "I Domeneshop:" + echo + echo "Vertsnavn / hostname:" + echo "${selector}._domainkey" + echo + echo "Type:" + echo "TXT" + echo + echo "Verdi / parameter:" + echo "v=DKIM1; k=rsa; p=${pubkey}" + echo + echo "Fullt DNS-navn:" + echo "${selector}._domainkey.${domain}" + echo + echo "Test etter lagring:" + echo "dig TXT ${selector}._domainkey.${domain} +short" + echo + done +} | tee "$output_file" + +chmod 600 "$output_file" + +echo +echo "Kopi lagret her:" +echo " $output_file"