Compare commits

...

3 Commits

3 changed files with 348 additions and 58 deletions

View File

@@ -13,6 +13,9 @@ echo -e "\n \033[32mStart Installation of OpenDKIM..\033[m"
#conf_file="${_src_base_dir}/conf/install_opendkim.conf"
log_file="$(mktemp)"
tmp_main_cf_file="$(mktemp)"
main_cf_file="/etc/postfix/main.cf"
backup_date="$(date +%Y-%m-%d-%H%M)"
@@ -27,6 +30,8 @@ postfix_spool_dir="/var/spool/postfix"
opendkim_socket_dir="${postfix_spool_dir}/opendkim"
opendkim_socket_file="${opendkim_socket_dir}/opendkim.sock"
opendkim_socket_string="local:/opendkim/opendkim.sock"
postfix_needs_restart=false
opendkim_needs_restart=false
@@ -87,6 +92,82 @@ echo_skipped() {
echo -e "\033[80G[ \033[37mskipped\033[m ]"
}
# Funktion stellt sicher, dass in /etc/postfix/main.cf
# - smtpd_milters
# - non_smtpd_milters
# den Wert "local:/opendkim/opendkim.sock" enthalten.
#
# Logik:
# 1) Existiert eine aktive Zeile (nicht auskommentiert)? → anpassen
# 2) Sonst: existiert eine auskommentierte Zeile? → ersetzen (entkommentieren)
# 3) Sonst: Variable am Ende der Datei hinzufügen
#
ensure_dkim_var() {
local var="$1"
awk -v var="$var" -v dkim="$opendkim_socket_string" '
# trim helper
function trim(s) {
sub("^[[:space:]]+", "", s)
sub("[[:space:]]+$", "", s)
return s
}
# Normalisiert aktive Werte:
# - wenn leer -> nur dkim
# - wenn dkim schon enthalten -> unverändert
# - sonst -> dkim vorne dran
function normalize_active_value(v) {
v = trim(v)
if (v == "") return dkim
if (index(v, dkim) > 0) return v
return dkim "," v
}
BEGIN { found_active=0; replaced_commented=0 }
#################################################################
# FALL 1: Aktive Zeile (nicht auskommentiert): var =
#################################################################
$0 ~ "^[[:space:]]*"var"[[:space:]]*=" && $0 !~ "^[[:space:]]*#" {
found_active=1
# rechten Teil extrahieren (nach "=")
v=$0
sub("^[[:space:]]*"var"[[:space:]]*=[[:space:]]*", "", v)
print var" = " normalize_active_value(v)
next
}
#################################################################
# FALL 2: Auskommentierte Zeile: # var =
# Sonderregel: ersetzen mit NUR DKIM, unabhängig vom Kommentarinhalt
#################################################################
$0 ~ "^[[:space:]]*#[[:space:]]*"var"[[:space:]]*=" \
&& found_active==0 && replaced_commented==0 {
replaced_commented=1
print var" = " dkim
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" = " dkim
}
}
' "$main_cf_file"
}
# -------------
# - Some pre-installation tasks
@@ -610,20 +691,16 @@ else
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
warn "Postfix (main.cf) seems already be configured for milters"
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
if grep -q -E "^\s*#?\s*smtpd_milters\s*=" ${main_cf_file} ; then
ensure_dkim_var "smtpd_milters" > "${tmp_main_cf_file}"
cp "${tmp_main_cf_file}" "${main_cf_file}"
else
cat <<EOF >> /etc/postfix/main.cf 2> $log_file
# ======= Milter configuration =======
# OpenDKIM
@@ -642,8 +719,19 @@ milter_protocol = 6
# 'smtpd_milters = local:/opendkim/opendkim.sock' here and add to
# localhost:10025 section in master.cf: 'smtpd_milters='
#
#smtpd_milters = local:/opendkim/opendkim.sock
smtpd_milters = local:/opendkim/opendkim.sock
smtpd_milters = $opendkim_socket_string
EOF
fi
if grep -q -E "^\s*#?\s*non_smtpd_milters\s*=" ${main_cf_file} ; then
ensure_dkim_var "non_smtpd_milters" > "${tmp_main_cf_file}"
cp "${tmp_main_cf_file}" "${main_cf_file}"
else
cat <<EOF >> /etc/postfix/main.cf 2> $log_file
# Was sind non_smtpd_milters?
#
@@ -673,8 +761,9 @@ smtpd_milters = local:/opendkim/opendkim.sock
#
#
# DKIM soll auch die ausgehenden Mails signieren, die nicht über smtpd daemon versendet werden.
non_smtpd_milters = local:/opendkim/opendkim.sock
non_smtpd_milters = $opendkim_socket_string
EOF
fi
postfix_needs_restart=true
if [[ $? -eq 0 ]] ; then
echo_ok
@@ -682,7 +771,6 @@ EOF
echo_failed
error "$(cat $log_file)"
fi
fi
# - Prevent Postfix from setting the DKIM Header twice (one befor
@@ -816,4 +904,5 @@ fi
echo ""
rm -f "$log_file"
rm -f "$tmp_main_cf_file"
exit 0

View File

@@ -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,24 +940,20 @@ 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 <<EOF >> /etc/postfix/main.cf 2> $log_file
# ======= Milter configuration =======
# OpenDKIM, OpenDMARC
# OpenDKIM
milter_default_action = accept
@@ -856,7 +969,20 @@ milter_protocol = 6
# '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 <<EOF >> /etc/postfix/main.cf 2> $log_file
# Was sind non_smtpd_milters?
#
@@ -886,8 +1012,9 @@ 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
fi
postfix_needs_restart=true
if [[ $? -eq 0 ]] ; then
echo_ok
@@ -895,7 +1022,6 @@ EOF
echo_failed
error "$(cat $log_file)"
fi
fi
echo ""

View File

@@ -2994,7 +2994,7 @@ if [[ -n "$(which opendkim)" ]] || [[ -n "$(which opendmarc)" ]] ; then
# ======= Milter configuration =======
# OpenDKIM
# OpenDKIM / OpenDMARC
milter_default_action = accept
@@ -3011,7 +3011,23 @@ milter_protocol = 6
# localhost:10025 section in master.cf: 'smtpd_milters='
#
smtpd_milter_maps = cidr:/etc/postfix/smtpd_milter_map
smtpd_milters =
EOF
if [[ -n "$(which opendkim)" ]] && [[ -n "$(which opendmarc)" ]] ; then
cat <<EOF >> /etc/postfix/main.cf
smtpd_milters = local:/opendkim/opendkim.sock,local:/opendmarc/opendmarc.sock
EOF
elif [[ -n "$(which opendkim)" ]] ; then
cat <<EOF >> /etc/postfix/main.cf
smtpd_milters = local:/opendkim/opendkim.sock
EOF
else
cat <<EOF >> /etc/postfix/main.cf
smtpd_milters = local:/opendmarc/opendmarc.sock
EOF
fi
cat <<EOF >> /etc/postfix/main.cf
# Was sind non_smtpd_milters?
#
# non_smtpd_milters gilt für alle Postfix-Prozesse, die Mails verarbeiten, aber NICHT
@@ -3038,19 +3054,78 @@ smtpd_milters =
#
# - etc.
#
#
EOF
fi
if [[ -n "$(which opendkim)" ]] ; then
cat <<EOF >> /etc/postfix/main.cf
# DKIM soll auch die ausgehenden Mails signieren, die nicht über smtpd daemon versendet werden.
#
EOF
if [[ -n "$(which opendkim)" ]] && [[ -n "$(which opendmarc)" ]] ; then
cat <<EOF >> /etc/postfix/main.cf
non_smtpd_milters = local:/opendkim/opendkim.sock,local:/opendmarc/opendmarc.sock
EOF
elif [[ -n "$(which opendkim)" ]] ; then
cat <<EOF >> /etc/postfix/main.cf
non_smtpd_milters = local:/opendkim/opendkim.sock
EOF
else
cat <<EOF >> /etc/postfix/main.cf
non_smtpd_milters =
non_smtpd_milters = local:/opendmarc/opendmarc.sock
EOF
fi
else
cat <<EOF >> /etc/postfix/main.cf
# ======= Milter configuration =======
# OpenDKIM / OpenDMARC
milter_default_action = accept
# Postfix ≥ 2.6 milter_protocol = 6, Postfix ≤ 2.5 milter_protocol = 2
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
# section in master.cf: 'smtpd_milters=local:/opendkim/opendkim.sock'
#
# 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_milter_maps = cidr:/etc/postfix/smtpd_milter_map
#smtpd_milters =
# Was sind non_smtpd_milters?
#
# non_smtpd_milters gilt für alle Postfix-Prozesse, die Mails verarbeiten, aber NICHT
# der smtpd-Daemon sind.
#
# Das betrifft z. B.:
#
# cleanup Header/Content-Bereinigung
# qmgr Queue-Manager
# lmtp / smtp Auslieferung nach extern
# local lokale Zustellung
#
# Das sind z. B.:
#
# - interne Bounces (MAILER-DAEMON)
#
# - Cron-Mails vom Server
#
# - Weiterleitungen, die Postfix selbst generiert
#
# - Mails, die über sendmail CLI gesendet werden
#
# - Mails, die Amavis über LMTP zurückgibt
#
# - etc.
#
# DKIM soll auch die ausgehenden Mails signieren, die nicht über smtpd daemon versendet werden.
#
#non_smtpd_milters =
EOF
fi