Compare commits

...

4 Commits

3 changed files with 390 additions and 40 deletions

View File

@@ -4210,7 +4210,7 @@ use strict;
# !! smtpd_proxy_filter - see master.cf !! # !! smtpd_proxy_filter - see master.cf !!
# #
# #
#\$inet_socket_port = [10024, 10026]; \$inet_socket_port = [10024, 10026];
#\$inet_socket_port = [10024, 10029]; #\$inet_socket_port = [10024, 10029];
#\$inet_socket_port = [10024, 10026, 10029]; #\$inet_socket_port = [10024, 10026, 10029];
@@ -4329,7 +4329,8 @@ read_hash(\%whitelist_sender, '/etc/postfix/sender_whitelist');
# Spam-Schwellwerte # Spam-Schwellwerte
# ---------------------------------------------------------- # ----------------------------------------------------------
\$sa_tag_level_deflt = 1.9; # ab hier Info-Header #\$sa_tag_level_deflt = 1.9; # ab hier Info-Header
\$sa_tag_level_deflt = -999; # immer header schreiben (Debug-freundlich)
\$sa_tag2_level_deflt = 5.1; # ab hier X-Spam-Flag: YES \$sa_tag2_level_deflt = 5.1; # ab hier X-Spam-Flag: YES
\$sa_kill_level_deflt = 9.51; # high-spam - final destiny (DISCARD) \$sa_kill_level_deflt = 9.51; # high-spam - final destiny (DISCARD)
\$sa_dsn_cutoff_level = 20.1; # ab hier keine DSN mehr \$sa_dsn_cutoff_level = 20.1; # ab hier keine DSN mehr
@@ -4427,14 +4428,108 @@ if (-r \$policy_banks_file) {
## - it which domains are local using the @local_domains_maps variable, ## - it which domains are local using the @local_domains_maps variable,
## - which by default is set to the value of \$mydomain & its subdomains: ## - which by default is set to the value of \$mydomain & its subdomains:
## - ## -
#@local_domains_maps = ( ["."] ); EOF
if [[ "$?" -ne 0 ]] ; then
installation_failed=true
error "$(cat $tmp_err_msg)"
fi
if [[ "${DB_TYPE}" = "PostgreSQL" ]] || [[ "${DB_TYPE}" = "MySQL" ]]; then
if [[ "$DB_TYPE" = "PostgreSQL" ]]; then
_db="psql"
else
_db="mysql"
fi
cat >> /etc/amavis/conf.d/50-user <<EOF
@local_domains_maps = (
[qw(${HOSTNAME} localhost)],
EOF
if [[ "$?" -ne 0 ]] ; then
installation_failed=true
error "$(cat $tmp_err_msg)"
fi
if [[ -f "/etc/postfix/${_db}_virtual_domains_maps.cf" ]]; then
cat >> /etc/amavis/conf.d/50-user <<EOF
# Domains, die als virtuelle Mailbox-Domains gehostet sind:
'${_db}:/etc/postfix/${_db}_virtual_domains_maps.cf',
EOF
if [[ "$?" -ne 0 ]] ; then
installation_failed=true
error "$(cat $tmp_err_msg)"
fi
fi
if [[ -f "/etc/postfix/${_db}_relay-domain-maps.cf" ]]; then
cat >> /etc/amavis/conf.d/50-user <<EOF
# Domains, die als relay_domains akzeptiert werden:
'${_db}:/etc/postfix/${_db}_relay-domain-maps.cf',
EOF
if [[ "$?" -ne 0 ]] ; then
installation_failed=true
error "$(cat $tmp_err_msg)"
fi
fi
if grep -iq -E "^\s*btree:/etc/postfix/relay_domains" $postfix_main_cf > /dev/null 2>&1 ; then
cat >> /etc/amavis/conf.d/50-user <<EOF
# Domains, die als virtuelle Mailbox-Domains gehostet sind:
'${_db}:/etc/postfix/${_db}_relay-domain-maps.cf',
EOF
if [[ "$?" -ne 0 ]] ; then
installation_failed=true
error "$(cat $tmp_err_msg)"
fi
fi
cat >> /etc/amavis/conf.d/50-user <<EOF
);
EOF
else
cat >> /etc/amavis/conf.d/50-user <<'EOF'
@local_domains_maps = ( ["."] );
EOF
if [[ "$?" -ne 0 ]] ; then
installation_failed=true
error "$(cat $tmp_err_msg)"
fi
fi
cat >> /etc/amavis/conf.d/50-user <<EOF
## - get rid of "Open Relay" warnings in amavis logfile. ## - get rid of "Open Relay" warnings in amavis logfile.
## - ## -
\$interface_policy{'10024'} = 'ORIGINATING'; \$interface_policy{'10026'} = 'ORIGINATING';
\$policy_bank{'ORIGINATING'} = { \$policy_bank{'ORIGINATING'} = {
originating => 1, # declare that mail was submitted by our smtp client originating => 1, # declare that mail was submitted by our smtp client
bypass_spam_checks_maps => (1),
bypass_virus_checks_maps => (0),
remove_existing_spam_headers => 1,
}; };
## - If you get am error like: ## - If you get am error like:
@@ -4447,6 +4542,7 @@ if (-r \$policy_banks_file) {
#\$inet_socket_bind = undef; #\$inet_socket_bind = undef;
EOF EOF
if [[ "$?" -ne 0 ]] ; then if [[ "$?" -ne 0 ]] ; then
installation_failed=true installation_failed=true
error "$(cat $tmp_err_msg)" error "$(cat $tmp_err_msg)"
@@ -5093,15 +5189,6 @@ localhost:10025 inet n - y - - smtpd
-o smtpd_data_restrictions= -o smtpd_data_restrictions=
-o mynetworks=127.0.0.0/8,[::1]/128 -o mynetworks=127.0.0.0/8,[::1]/128
-o receive_override_options=no_unknown_recipient_checks -o receive_override_options=no_unknown_recipient_checks
EOF
if [[-n "$(which opendmarc)" ]] ; then
cat >> $postfix_master_cf << EOF
# IMPORTANT: no opendmarc here!
#-o smtpd_milters=local:/opendmarc/opendmarc.sock
EOF
fi
cat >> $postfix_master_cf << EOF
#-o mynetworks=127.0.0.0/8,[::1]/128,${IPV4}/32
EOF EOF
fi fi
@@ -5130,7 +5217,7 @@ EOF
_found=true _found=true
cat >> $postfix_master_cf << EOF cat >> $postfix_master_cf << EOF
submission inet n - y - 20 smtpd submission inet n - y - 20 smtpd
-o content_filter=amavisfeed:[127.0.0.1]:10024 -o content_filter=amavisfeed:[127.0.0.1]:10026
-o smtpd_tls_security_level=encrypt -o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes -o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject -o smtpd_client_restrictions=permit_sasl_authenticated,reject
@@ -5158,12 +5245,6 @@ localhost:10025 inet n - y - - smtpd
-o mynetworks=127.0.0.0/8,[::1]/128 -o mynetworks=127.0.0.0/8,[::1]/128
-o receive_override_options=no_unknown_recipient_checks -o receive_override_options=no_unknown_recipient_checks
EOF EOF
if [[ -n "$(which opendmarc)" ]] ; then
cat >> $postfix_master_cf << EOF
# IMPORTANT: no opendmarc here!
#-o smtpd_milters=local:/opendmarc/opendmarc.sock
EOF
fi
fi fi
if ! $amavisfeed_present ; then if ! $amavisfeed_present ; then
@@ -5184,7 +5265,7 @@ EOF
_found=true _found=true
cat >> $postfix_master_cf << EOF cat >> $postfix_master_cf << EOF
smtps inet n - y - - smtpd smtps inet n - y - - smtpd
-o content_filter=amavisfeed:[127.0.0.1]:10024 -o content_filter=amavisfeed:[127.0.0.1]:10026
-o smtpd_tls_wrappermode=yes -o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes -o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject -o smtpd_client_restrictions=permit_sasl_authenticated,reject
@@ -5212,12 +5293,6 @@ localhost:10025 inet n - y - - smtpd
-o mynetworks=127.0.0.0/8,[::1]/128 -o mynetworks=127.0.0.0/8,[::1]/128
-o receive_override_options=no_unknown_recipient_checks -o receive_override_options=no_unknown_recipient_checks
EOF EOF
if [[ -n "$(which opendmarc)" ]] ; then
cat >> $postfix_master_cf << EOF
# IMPORTANT: no opendmarc here!
#-o smtpd_milters=local:/opendmarc/opendmarc.sock
EOF
fi
fi fi
if ! $amavisfeed_present ; then if ! $amavisfeed_present ; then
@@ -5250,12 +5325,6 @@ localhost:10025 inet n - y - - smtpd
-o mynetworks=127.0.0.0/8,[::1]/128 -o mynetworks=127.0.0.0/8,[::1]/128
-o receive_override_options=no_unknown_recipient_checks -o receive_override_options=no_unknown_recipient_checks
EOF EOF
if [[ -n "$(which opendmarc)" ]] ; then
cat >> $postfix_master_cf << EOF
# IMPORTANT: no opendmarc here!
#-o smtpd_milters=local:/opendmarc/opendmarc.sock
EOF
fi
continue continue
fi fi

View File

@@ -4099,7 +4099,6 @@ submission inet n - y - 20 smtpd
-o smtpd_tls_security_level=encrypt -o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes -o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject -o smtpd_client_restrictions=permit_sasl_authenticated,reject
#-o milter_macro_daemon_name=ORIGINATING
EOF EOF
fi fi
if ! $smtps_present ; then if ! $smtps_present ; then
@@ -4108,7 +4107,6 @@ smtps inet n - y - - smtpd
-o smtpd_tls_wrappermode=yes -o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes -o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject -o smtpd_client_restrictions=permit_sasl_authenticated,reject
#-o milter_macro_daemon_name=ORIGINATING
EOF EOF
fi fi
elif $LISTEN_ON_ADDITIONAL_RELAY_PORT ; then elif $LISTEN_ON_ADDITIONAL_RELAY_PORT ; then
@@ -4127,7 +4125,6 @@ submission inet n - y - 20 smtpd
-o smtpd_tls_security_level=encrypt -o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes -o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject -o smtpd_client_restrictions=permit_sasl_authenticated,reject
# -o milter_macro_daemon_name=ORIGINATING
EOF EOF
fi fi
continue continue
@@ -4141,7 +4138,6 @@ smtps inet n - y - - smtpd
-o smtpd_tls_wrappermode=yes -o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes -o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject -o smtpd_client_restrictions=permit_sasl_authenticated,reject
# -o milter_macro_daemon_name=ORIGINATING
EOF EOF
fi fi
continue continue
@@ -4164,7 +4160,7 @@ EOF
# - Add support for policyd-spf service # - Add support for policyd-spf service
# - # -
if ! $(grep -iq -E "^policyd-spf\s+" "$postfix_master_cf" 2> /dev/null) ; then if ! grep -iq -E "^policy-spf\s+" "$postfix_master_cf" 2> /dev/null ; then
cat <<EOF >> $postfix_master_cf cat <<EOF >> $postfix_master_cf
policy-spf unix - n n - 0 spawn policy-spf unix - n n - 0 spawn
@@ -4175,7 +4171,7 @@ EOF
# - Add transport definitions for only sending over IPv4/IPv6 # - Add transport definitions for only sending over IPv4/IPv6
# - # -
if ! $(grep -iq -E "^smtp-ipv4-only\s+" "$postfix_master_cf" 2> /dev/null) ; then if ! grep -iq -E "^smtp-ipv4-only\s+" "$postfix_master_cf" 2> /dev/null ; then
cat <<EOF >> $postfix_master_cf cat <<EOF >> $postfix_master_cf
smtp-ipv4-only unix - - n - - smtp smtp-ipv4-only unix - - n - - smtp
@@ -4183,7 +4179,7 @@ smtp-ipv4-only unix - - n - - smtp
EOF EOF
fi fi
if ! $(grep -iq -E "^smtp-ipv6-only\s+" "$postfix_master_cf" 2> /dev/null) ; then if ! grep -iq -E "^smtp-ipv6-only\s+" "$postfix_master_cf" 2> /dev/null ; then
cat <<EOF >> $postfix_master_cf cat <<EOF >> $postfix_master_cf
smtp-ipv6-only unix - - n - - smtp smtp-ipv6-only unix - - n - - smtp

285
set_amavis_local_domains_maps.sh Executable file
View File

@@ -0,0 +1,285 @@
#!/usr/bin/env bash
# amavis-local-domains-auto.sh
#
# Zweck
# -----
# Ersetzt in /etc/amavis/conf.d/50-user die lokale Domains-Definition
#
# @local_domains_maps = ( ["."] );
#
# durch eine dynamische Definition, die aus der (effektiv aktiven) Postfix-
# Konfiguration ermittelt wird (pgsql oder mysql). Damit werden Spam-Header
# nur für Domains geschrieben, die Postfix tatsächlich als "lokal/relay" kennt.
#
# WICHTIG:
# - Das Skript ändert NUR dann etwas, wenn die Zeile exakt ( ["."] ); ist.
# - Backups werden IMMER nach /etc/amavis/ geschrieben (nicht neben die Datei).
# - DB-Typ wird automatisch aus "postconf -n" erkannt (robust inkl. includes).
#
# Features
# --------
# - Auto-Detect Backend: pgsql | mysql (aus Postfix-Maps)
# - Optionaler Fallback: wenn DB nicht erkennbar, dann auf ( ["."] ); setzen
# (standardmäßig AUS, weil produktiver Betrieb)
# - Dry-run Modus
# - Optional reload/restart von amavis
# - Atomare Aktualisierung (schreibt erst tmp, dann mv)
#
# Nutzung
# -------
# sudo ./amavis-local-domains-auto.sh --dry-run
# sudo ./amavis-local-domains-auto.sh --apply --reload
# sudo ./amavis-local-domains-auto.sh --apply --restart
#
# Optional:
# sudo ./amavis-local-domains-auto.sh --apply --allow-fallback-all
#
set -euo pipefail
# ----------------------------
# Konfigurierbare Pfade
# ----------------------------
AMAVIS_50="${AMAVIS_50:-/etc/amavis/conf.d/50-user}"
# Backup-Verzeichnis (gewünscht: /etc/amavis/)
BACKUP_DIR="${BACKUP_DIR:-/etc/amavis}"
# Optional: Dateimap für relay_domains (falls vorhanden)
RELAY_BTREE_DEFAULT="/etc/postfix/relay_domains"
# ----------------------------
# Schalter / Optionen
# ----------------------------
DO_APPLY=false
DO_DRY_RUN=false
DO_RESTART=false
DO_RELOAD=false
ALLOW_FALLBACK_ALL=false
# Optional overrides
HOST_FQDN_OVERRIDE=""
RELAY_BTREE_OVERRIDE=""
usage() {
cat <<'EOF'
Usage:
amavis-local-domains-auto.sh [OPTIONS]
Options:
--dry-run Show what would change, do not modify files
--apply Apply change (only if @local_domains_maps is exactly ( ["."] );)
--restart Restart amavis after apply
--reload Reload amavis after apply (preferred if supported)
--allow-fallback-all If DB backend not detectable, replace with ( ["."] ); anyway
(default: fail safely / do nothing)
--host-fqdn FQDN Override hostname -f used in the block
--relay-btree PATH Override btree file path (default: /etc/postfix/relay_domains)
-h, --help Show this help
Examples:
sudo ./amavis-local-domains-auto.sh --dry-run
sudo ./amavis-local-domains-auto.sh --apply --reload
EOF
}
die(){ echo "ERROR: $*" >&2; exit 1; }
log(){ echo "INFO: $*" >&2; }
# ----------------------------
# Argumente parsen
# ----------------------------
while [[ $# -gt 0 ]]; do
case "$1" in
--dry-run) DO_DRY_RUN=true; shift ;;
--apply) DO_APPLY=true; shift ;;
--restart) DO_RESTART=true; shift ;;
--reload) DO_RELOAD=true; shift ;;
--allow-fallback-all) ALLOW_FALLBACK_ALL=true; shift ;;
--host-fqdn) HOST_FQDN_OVERRIDE="${2:-}"; shift 2 ;;
--relay-btree) RELAY_BTREE_OVERRIDE="${2:-}"; shift 2 ;;
-h|--help) usage; exit 0 ;;
*) die "Unknown option: $1" ;;
esac
done
if ! $DO_DRY_RUN && ! $DO_APPLY; then
die "Choose one: --dry-run or --apply"
fi
if $DO_RESTART && $DO_RELOAD; then
die "Choose only one: --restart or --reload"
fi
# ----------------------------
# Sanity Checks
# ----------------------------
command -v postconf >/dev/null || die "postconf not found"
[[ -r "$AMAVIS_50" ]] || die "Missing $AMAVIS_50"
[[ -d "$BACKUP_DIR" ]] || die "Backup dir missing: $BACKUP_DIR"
[[ -w "$BACKUP_DIR" ]] || die "Backup dir not writable: $BACKUP_DIR"
HOST_FQDN="${HOST_FQDN_OVERRIDE:-$(hostname -f 2>/dev/null || hostname)}"
RELAY_BTREE="${RELAY_BTREE_OVERRIDE:-$RELAY_BTREE_DEFAULT}"
# Regex: exakt @local_domains_maps = ( ["."] );
DOTLINE_REGEX='^[[:space:]]*@local_domains_maps[[:space:]]*=[[:space:]]*\([[:space:]]*\[[[:space:]]*"\."[[:space:]]*\][[:space:]]*\)[[:space:]]*;[[:space:]]*$'
if ! grep -qE "$DOTLINE_REGEX" "$AMAVIS_50"; then
log "No change: @local_domains_maps is not exactly ( [\".\"] );"
exit 0
fi
# ----------------------------
# DB-Typ + Map-Dateien aus Postfix ermitteln
# (postconf -n berücksichtigt includes, master.d, etc.)
# ----------------------------
VMD_LINE="$(postconf -n virtual_mailbox_domains 2>/dev/null || true)"
RD_LINE="$(postconf -n relay_domains 2>/dev/null || true)"
extract_db_map() {
# Findet den ersten Token, der :pgsql: oder :mysql: enthält
# und gibt "scheme|/path/to/map.cf" aus.
local line="$1"
for tok in $line; do
tok="${tok%,}"
if [[ "$tok" == *":pgsql:"* ]]; then
echo "pgsql|${tok##*:pgsql:}"
return 0
elif [[ "$tok" == *":mysql:"* ]]; then
echo "mysql|${tok##*:mysql:}"
return 0
fi
done
return 1
}
DB_SCHEME=""
VDOM_CF=""
RELAY_CF=""
if out="$(extract_db_map "$VMD_LINE")"; then
DB_SCHEME="${out%%|*}"
VDOM_CF="${out##*|}"
else
if $ALLOW_FALLBACK_ALL; then
DB_SCHEME="all"
else
die "Could not detect pgsql/mysql from postfix virtual_mailbox_domains. Use --allow-fallback-all to force."
fi
fi
if [[ "$DB_SCHEME" != "all" ]]; then
if out="$(extract_db_map "$RD_LINE")"; then
rd_scheme="${out%%|*}"
rd_cf="${out##*|}"
if [[ "$rd_scheme" == "$DB_SCHEME" ]]; then
RELAY_CF="$rd_cf"
fi
fi
[[ -r "$VDOM_CF" ]] || die "Detected map not readable: $VDOM_CF"
if [[ -n "$RELAY_CF" ]]; then
[[ -r "$RELAY_CF" ]] || die "Detected relay map not readable: $RELAY_CF"
fi
fi
# ----------------------------
# Replacement-Block bauen (in temp Datei)
# ----------------------------
TMPDIR="$(mktemp -d)"
trap 'rm -rf "$TMPDIR"' EXIT
BLOCKFILE="$TMPDIR/block.txt"
if [[ "$DB_SCHEME" == "all" ]]; then
cat >"$BLOCKFILE" <<'EOF'
@local_domains_maps = ( ["."] );
EOF
else
{
echo "@local_domains_maps = ("
echo " [qw(${HOST_FQDN} localhost)],"
echo ""
echo " # Domains, die als virtuelle Mailbox-Domains gehostet sind:"
echo " '${DB_SCHEME}:${VDOM_CF}',"
if [[ -n "$RELAY_CF" ]]; then
echo ""
echo " # Domains, die als relay_domains akzeptiert werden:"
echo " '${DB_SCHEME}:${RELAY_CF}',"
else
echo ""
echo " # relay_domains DB-map nicht erkannt wird übersprungen"
fi
echo " 'btree:${RELAY_BTREE}',"
echo ");"
} >"$BLOCKFILE"
fi
# ----------------------------
# Geplante Änderung anzeigen
# ----------------------------
log "Detected backend: ${DB_SCHEME}"
if [[ "$DB_SCHEME" != "all" ]]; then
log "virtual_mailbox_domains map: ${DB_SCHEME}:${VDOM_CF}"
if [[ -n "$RELAY_CF" ]]; then
log "relay_domains map: ${DB_SCHEME}:${RELAY_CF}"
else
log "relay_domains map: (not detected / not used)"
fi
log "btree relay domains: btree:${RELAY_BTREE}"
fi
if $DO_DRY_RUN; then
echo "----- Would replace this line in $AMAVIS_50 -----"
echo '@local_domains_maps = ( ["."] );'
echo "----- With this block -----"
cat "$BLOCKFILE"
exit 0
fi
# ----------------------------
# Backup in /etc/amavis/ erstellen
# ----------------------------
STAMP="$(date +%F_%H%M%S)"
BACKUP_FILE="${BACKUP_DIR}/50-user.bak.${STAMP}"
cp -a "$AMAVIS_50" "$BACKUP_FILE"
log "Backup created: $BACKUP_FILE"
# ----------------------------
# Datei neu schreiben (atomar)
# - Wir ersetzen nur die exakt passende (["."]) Zeile durch den neuen Block.
# ----------------------------
OUTFILE="$TMPDIR/50-user.new"
awk -v blockfile="$BLOCKFILE" '
BEGIN {
while ((getline line < blockfile) > 0) {
newblock = newblock line "\n"
}
close(blockfile)
}
{
if ($0 ~ /^[[:space:]]*@local_domains_maps[[:space:]]*=[[:space:]]*\([[:space:]]*\[[[:space:]]*"\."[[:space:]]*\][[:space:]]*\)[[:space:]]*;[[:space:]]*$/) {
printf "%s", newblock
} else {
print
}
}
' "$AMAVIS_50" > "$OUTFILE"
mv "$OUTFILE" "$AMAVIS_50"
log "Updated $AMAVIS_50"
# ----------------------------
# Optionaler Reload/Restart von amavis
# ----------------------------
if $DO_RELOAD; then
log "Reloading amavis..."
systemctl reload amavis || die "amavis reload failed"
elif $DO_RESTART; then
log "Restarting amavis..."
systemctl restart amavis || die "amavis restart failed"
else
log "No service action requested (--reload/--restart)."
fi
log "Done."