From 7163b2dccfa59be108af47e47b705b5902071831 Mon Sep 17 00:00:00 2001 From: Christoph Date: Mon, 2 Feb 2026 19:44:41 +0100 Subject: [PATCH] install_opendmarc.sh: fix errors in adjustin main.cf file. --- install_opendmarc.sh | 180 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 153 insertions(+), 27 deletions(-) diff --git a/install_opendmarc.sh b/install_opendmarc.sh index d63800f..e08b116 100755 --- a/install_opendmarc.sh +++ b/install_opendmarc.sh @@ -52,8 +52,15 @@ done postfix_needs_restart=false opendmarc_needs_restart=false -backup_date="$(date +%Y-%m-%d-%H%M)" log_file="$(mktemp)" +tmp_main_cf_file="$(mktemp)" + +main_cf_file="/etc/postfix/main.cf" + +backup_date="$(date +%Y-%m-%d-%H%M)" + +opendkim_socket_string="local:/opendkim/opendkim.sock" +opendmarc_socket_string="local:/opendmarc/opendmarc.sock" # ------------- # --- Some functions @@ -111,6 +118,116 @@ echo_skipped() { echo -e "\033[80G[ \033[37mskipped\033[m ]" } +# iFubction stellt sicher, dass OpenDMARC milter in main.cf gesetzt ist +# und (falls OpenDKIM vorhanden ist) OpenDMARC direkt nach OpenDKIM folgt. +# +# Ziel: +# - smtpd_milters und non_smtpd_milters enthalten: local:/opendmarc/opendmarc.sock +# - Falls local:/opendkim/opendkim.sock vorhanden ist: +# ...opendkim...,local:/opendmarc/opendmarc.sock,... +# +# Logik: +# 1) Aktive Zeile existiert? → anpassen +# 2) Sonst kommentierte Zeile existiert? → ersetzen (entkommentieren) an derselben Stelle +# 3) Sonst am Ende hinzufügen +ensure_dmarc_var() { + local var="$1" + + awk -v var="$var" -v dmarc="$opendmarc_socket_string" -v dkim="$opendkim_socket_string" ' + function trim(s) { + sub("^[[:space:]]+", "", s) + sub("[[:space:]]+$", "", s) + return s + } + + # Normalisiert aktive Werte: + # - Entfernt vorhandenes dmarc (um Duplikate zu verhindern) + # - Fügt dmarc wieder ein: + # - direkt nach dkim, falls dkim vorhanden + # - sonst ans Ende (oder allein, wenn leer) + function normalize_active_value(v, n,i,t,has_dkim,out,newn) { + v = trim(v) + if (v == "") return dmarc + + # split an Komma, trimmen, DMARC entfernen + n = split(v, a, ",") + has_dkim = 0 + newn = 0 + + for (i=1; i<=n; i++) { + t = trim(a[i]) + if (t == "") continue + if (t == dmarc) continue # Duplikate vermeiden + a[++newn] = t + if (t == dkim) has_dkim = 1 + } + n = newn + + out = "" + + if (has_dkim) { + # Ausgabe bauen und DMARC direkt nach DKIM einfügen + for (i=1; i<=n; i++) { + if (out != "") out = out "," + out = out a[i] + if (a[i] == dkim) { + out = out "," dmarc + } + } + return out + } + + # kein DKIM: DMARC ans Ende anhängen + for (i=1; i<=n; i++) { + if (out != "") out = out "," + out = out a[i] + } + if (out == "") return dmarc + return out "," dmarc + } + + BEGIN { found_active=0; replaced_commented=0 } + + ################################################################# + # FALL 1: Aktive Zeile (nicht auskommentiert): var = + ################################################################# + $0 ~ "^[[:space:]]*"var"[[:space:]]*=" && $0 !~ "^[[:space:]]*#" { + found_active=1 + + v=$0 + sub("^[[:space:]]*"var"[[:space:]]*=[[:space:]]*", "", v) + + print var" = " normalize_active_value(v) + next + } + + ################################################################# + # FALL 2: Auskommentierte Zeile: # var = + # Sonderregel: ersetzen mit NUR DMARC, unabhängig vom Kommentarinhalt + ################################################################# + $0 ~ "^[[:space:]]*#[[:space:]]*"var"[[:space:]]*=" \ + && found_active==0 && replaced_commented==0 { + replaced_commented=1 + print var" = " dmarc + next + } + + ################################################################# + # Sonst: Zeile unverändert ausgeben + ################################################################# + { print } + + ################################################################# + # FALL 3: Variable nicht vorhanden → am Ende hinzufügen + ################################################################# + END { + if (found_active==0 && replaced_commented==0) { + print var" = " dmarc + } + } + ' "$main_cf_file" +} + # ------------- # - Some pre-installation tasks @@ -823,30 +940,26 @@ else error "$(cat $log_file)" fi -echononl " Activate processing of e-mail through the OpenDKIM daemon.." -if grep -q -E "milter_default_action\s*=\s*accept" /etc/postfix/main.cf ; then - echo_skipped - info "Postfix (main.cf) was not changed - seems already be configured right." - echononl " Delete previosly saved Postfix configuration.." - rm /etc/postfix/main.cf.$backup_date 2> $log_file - if [[ $? -eq 0 ]] ; then - echo_ok - else - echo_failed - error "$(cat $log_file)" - fi +echononl " Activate processing of e-mail through the OpenDMARC daemon.." +if grep -q -E "^\s*#?\s*smtpd_milters\s*=" ${main_cf_file} ; then + + ensure_dmarc_var "smtpd_milters" > "${tmp_main_cf_file}" + cp "${tmp_main_cf_file}" "${main_cf_file}" + else - cat <> /etc/postfix/main.cf 2> $log_file + + cat <> /etc/postfix/main.cf 2> $log_file + # ======= Milter configuration ======= -# OpenDKIM, OpenDMARC +# OpenDKIM milter_default_action = accept # Postfix ≥ 2.6 milter_protocol = 6, Postfix ≤ 2.5 milter_protocol = 2 -milter_protocol = 6 - +milter_protocol = 6 + # Note: # We will sign AFTER sending through AmaVIS, just befor sending out. So # set 'smtpd_milters =' to an emty string here and add to localhost:10025 @@ -855,8 +968,21 @@ milter_protocol = 6 # If you want sign mails before sending through AmaVIS, set # 'smtpd_milters = local:/opendkim/opendkim.sock' here and add to # localhost:10025 section in master.cf: 'smtpd_milters=' -# -smtpd_milters = local:/opendkim/opendkim.sock, local:/opendmarc/opendmarc.sock +# +smtpd_milters = $opendmarc_socket_string +EOF + +fi + + +if grep -q -E "^\s*#?\s*non_smtpd_milters\s*=" ${main_cf_file} ; then + + ensure_dmarc_var "non_smtpd_milters" > "${tmp_main_cf_file}" + cp "${tmp_main_cf_file}" "${main_cf_file}" + +else + + cat <> /etc/postfix/main.cf 2> $log_file # Was sind non_smtpd_milters? # @@ -886,15 +1012,15 @@ smtpd_milters = local:/opendkim/opendkim.sock, local:/opendmarc/opendmarc.sock # # # DKIM soll auch die ausgehenden Mails signieren, die nicht über smtpd daemon versendet werden. -non_smtpd_milters = local:/opendkim/opendkim.sock, local:/opendmarc/opendmarc.sock +non_smtpd_milters = $opendmarc_socket_string EOF - postfix_needs_restart=true - if [[ $? -eq 0 ]] ; then - echo_ok - else - echo_failed - error "$(cat $log_file)" - fi +fi +postfix_needs_restart=true +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" fi