Installationsanleitungen für das Proxmox Mail Gateway gibt es viele – die Anleitungen für die individuelle Anpassung kommt oft zu kurz.
Hier ist meine Anpassung ggü. einer Out of the Box Installation beschrieben.
Meine Politik dabei ist, dass E-Mails gar nicht erst angenommen werden, wenn sie Spam sind, denn das größte Übel ist aus meiner Sicht, dass false positives, die in meinem Spam Ordner untergehen vom Sender als zugestellt geglaubt werden. Das schützt natürlich nicht davor, wenn bestellte Konzertkarten o.ä. bei mir nicht ankommen, weil der Absender seinen Mailserver nicht im Griff hat. Die Konzertkarten sind dann vermutlich 'weg' und erfordern erhebliche Nacharbeit. Ein Manko von "ich nehme deinen Kram nicht an".
Basiskonfiguration Proxmox Mail Gateway
====================================
Configuration -> Mail Proxy -> Relay Domains:
Eintragen meiner Domains
# E-Mails, die an diese Domains gehen, werden von Proxmox überhaupt aktzeptiert
Configuration -> Mail Proxy -> Options:
# Message Size (bytes): 104857600
Deutlich erhöhen, sonst gibt es Probleme mit Spam und DKIM Signaturen bei großen E-Mails.
Reject Unknown Clients: No
# Der rdns des Servers muss korrekt gesetzt sein. Geht in 98% gut, aber in 2% haben kleine Admins ihre Umgebung nicht korrekt gepflegt, die haben dann keine Chance euch Mails zu senden. Das greift vor jeglicher Whitelist. Daher besser ausgeschaltet lassen.
Reject Unknown Senders: Yes
# Die Absenderdomain muss existieren, damit die E-Mail angenommen wird. E-Mails von 'ausgedachten' Absenderdomains werden temporär rejected (4xx error code). Das macht ca. 20% der Spams aus, die nicht Gefahr laufen, im SA (Spamassassin) durchzurutschen. In ca. 1 % der Fälle schlägt die Prüfung fehl, dann wird die E-Mail 5 min später beim nächsten Einsendeversuch akzeptiert. In manchen Fällen wird die E-Mail von Spammern über 100x eingeliefert und nie akzeptiert, das nervt leider ein wenig.
Verify Receivers: Yes (550)
# Sicherstellung, dass E-Mails an unbekannte Mailkonten gar nicht erst angenommen werden. Ansonsten gibt es Bounces von eurem E-Mail Server zum Proxmox, die beim Proxmox verbleiben, von denen der Versender jedoch nichts erfährt.
# Edit: Ich hatte einige Versuche, E-Mail Adressen von Geschäftsführern zu erraten. Absender waren ein unfassbar großes Botnetz aus der ganzen Welt (jeder Versuch über einen anderen Server). Ich bin daher dazu übergegangen, das auszuschalten und eine ungelesene Catchall Adresse einzurichten. Nachteil: Tippfehler im Empfänger bekommt der seriöse Versender nicht mehr mit)
Use Greylisting for IPv4: No
# Greylisting verzögert die Annahme teilweise erheblich, was sehr schlecht bei Kontoverifizierungs E-Mails ist. Leider beherrscht PMG nicht die Möglichkeit, nur E-Mails mit fragwürdigem Spamscsore temporär zu rejecten, wie es rspamd beherrscht. In der hier gebotenen Qualität des Sendertripplets ist es aus meiner Sicht unbrauchbar.
Use SPF: (Yes)
# E-Mails mit falscher SPF werden abgelehnt. Habe ich bisher wenig Probleme mit, könnte aber durchaus mal problematisch sein. Gewisses Risko.
Before Queue Filtering: Yes
# Kernanliegen, denn nachträgliche "NDRs on Blocked E-Mails" sind selbst Spam.
Configuration -> Mail Proxy -> Transports:
Eintragen meines Mailservers
<domain> -> Host: 172.30.0.3, use MX: No
# MX: No -> Weil der MX auf das PMG zeigt
Configuration -> Spam Detector -> Options:
Max Spam Size (bytes): 104857600
# Muss gleich sein wie unter Mail Proxy.
Mail Filter:
Block Spam (Level 10) aktivieren: Mails mit hoher Spam Wahrscheinlichkeit sollen direkt abgelehnt werden.
Mark Spam und Quarantäne nach eigenen Vorstellungen konfigurieren.
Installation und Konfiguration wirksamer Mailfilter
===========================================
Die Reihenfolge der hier angegebenen Filter hat eine Bedeutung. Die hier zuerst behandelten Filter filtern die Mail früher heraus und benötigen dafür deutlich weniger CPU Last als spätere SA-Filter.
Gleichzeitig haben die hier früh in der Anleitung behandelten filter eine höhere Sensitivität (d.h.: eine geringere false-positive Quote).
Man kann daher die Anleitung erst einmal nur zum Teil abarbeiten und erzielt dann schon recht gute Ergebnisse.
Unabhängig davon ist aber das Tuning der Custom Scores am Ende des ersten Beitrags aus meiner Sicht wichtig, das ist ja gerade der Kern des PMG.
Filter vor der Übermittlung von Mailheader ('rejected')
Mails, die an dieser Stelle abgewiesen werden, stehen im Tracking Center als rejected mit schwarzem Kreuz Symbol. An dieser Stelle liegen keinerlei Informationen des E-Mail Headers vor, außer dem Sende-Server (HELO + IP), Envelope-From und Empfänger. Es greifen hier sämtliche Welcome-Lists innerhalb des PMG noch nicht.
DNS-Blocklists (DNSBL):
(Filtert ca. 50 % eures Spam)
Configuration -> Spam Detector -> Options:
Use RBL checks: Yes
Wir benötigen "unbound" für rekursive DNS Anfragen, das ist bei allen DNSBL notwendige Voraussetzung.
apt install unbound
Editieren der /etc/resolv.conf
nameserver 127.0.0.1
bei LXC Containern stattdessen: Über Proxmox VE in den DNS Optionen setzen
Configuration -> Mail Proxy -> Options:
Bei Spamhaus muss ein Account erstellt werden und die individuelle DQS ID eingefügt werden. Alle anderen sind ohne Registrierung nutzbar.
DNSBL Sites:
<ID>.zen.dq.spamhaus.net
b.barracudacentral.org
bl.mailspike.net
all.spamrats.com
dnsbl-1.uceprotect.net
Filter nach der Übermittlung von Mailheader, vor der Übermittlung von Mailbody ('rejected')
Mails, die an dieser Stelle abgewiesen werden, stehen im Tracking Center als rejected mit schwarzem Kreuz Symbol. An dieser Stelle liegt der äußere Header der E-Mail vor, Envelope-From, Empfänger und weitere Header der E-Mail, aber noch kein Subject oder (Body-)From.
Die Welcomelist unter Configuration -> Mail Proxy -> Welcomelist sollte diesen Service überschreiben (getestet habe ich das nicht), weil diese in die Postfix senderaccess ausgeführt wird. Die Mail Filter -> Who Object -> Welcomelist wird erst im SA berücksichtigt – die hat hier keine Wirkung.
Google Spam beherrschen: Dauerausnahme in allen DNSBL
(Filtert ca. 25 % eures Spam)
Google sendet auf mehreren Ebenen Spam, welchen wir mit der folgenden Anleitung direkt im Postfix/Postscreen rejecten.
- firebaseapp.com (Google Service) verschickt ausschließlich Spam und
- firebase-Authorisierte Dienste: Senden über Google Server mit eigener Domain. Erkennt man darin, dass der authorisierende SPF Eintrag _sfp.firebasemail.com ist.
- Google Groups:
Spammer nutzen Google Groups Listen, weil sie kein Opt-In des Empfängers benötigen und Mailinglisten standardmäßig seitens Spamassassin einen Score von "-1.0" zugewiesen bekommen. Neben den eigentlichen Spams erreichen einen auch NDRs oder wütende Antworten von Empfängern.
- Google Usercontent:
Server von Google, der nur Spam versendet
All diese Dienste kann man sehr früh in Postfix blockieren. Bonus: Da Google als Absender prinzipiell nicht auf den DNSBL des vorigen Kapitels steht, gibt es hier keine Überlappung der Filter, also ja: mit den DNSBL und diesem Google-Filter sind 75% des Spamaufkommens wirksam und nahezu ohne false-positive heraus gefiltert!
apt install python3-dnspythoncat > /usr/local/bin/policyguard.py
#!/usr/bin/env python3
import sys
import time
import re
import dns.resolver
from functools import lru_cache
MAX_SPF_DEPTH = 10
CACHE_SIZE = 4096
SPF_BLOCK_INCLUDE = ["_spf.firebasemail.com"]
SENDER_BLOCK_INCLUDE = ["firebaseapp.com"]
BLOCKLIST_CLIENTNAME = ["googleusercontent.com"]
SENDER_REGEX_PATTERNS = [
r'^[a-z0-9]{1,3}\+bncB[A-Z0-9]{25,}@',
]
SENDER_REGEXES = [re.compile(p) for p in SENDER_REGEX_PATTERNS]
resolver = dns.resolver.Resolver()
resolver.timeout = 2
resolver.lifetime = 3
def log(msg):
sys.stderr.write(f"spf-policy: {msg}\n")
sys.stderr.flush()
@lru_cache(maxsize=CACHE_SIZE)
def get_spf(domain):
try:
answers = resolver.resolve(domain, "TXT")
for r in answers:
txt = "".join([s.decode() for s in r.strings])
if txt.startswith("v=spf1"):
return txt
except Exception:
pass
return None
def spf_contains_block(domain, depth=0, visited=None):
if visited is None:
visited = set()
if depth > MAX_SPF_DEPTH:
return False
if domain in visited:
return False
visited.add(domain)
spf = get_spf(domain)
if not spf:
return False
parts = spf.split()
for p in parts:
if p.startswith("include:"):
include = p.split(":", 1)[1]
if include in SPF_BLOCK_INCLUDE:
return True
if spf_contains_block(include, depth + 1, visited):
return True
return False
def sender_matches_regex(sender):
for regex in SENDER_REGEXES:
if regex.match(sender):
return True, regex.pattern
return False, None
def handle_request(attrs):
sender = attrs.get("sender", "")
client_name = attrs.get("client_name", "").lower()
# Block Clients
if any(client_name == b or client_name.endswith("." + b) for b in BLOCKLIST_CLIENTNAME):
log(f"blocked client hostname: {client_name}")
return "reject reject for policy reasons [policyguard] [guc]"
if sender:
matched, pattern = sender_matches_regex(sender)
if matched:
log(f"blocked sender by regex ({pattern}): {sender}")
return "reject reject for policy reasons [gg]"
if "@" not in sender:
return "dunno"
domain = sender.split("@", 1)[1].lower()
try:
if any(domain == base or domain.endswith('.' + base) for base in SENDER_BLOCK_INCLUDE):
log(f"blocked sender domain {domain}")
return "reject reject for policy reasons [fbm]"
elif spf_contains_block(domain):
log(f"blocked sender domain {domain}")
return "reject reject for policy reasons [fbs]"
except Exception as e:
log(f"error checking {domain}: {e}")
return "dunno"
def main():
while True:
attrs = {}
while True:
line = sys.stdin.readline()
if line == "":
return
line = line.strip()
if not line:
break
if "=" in line:
k, v = line.split("=", 1)
attrs[k] = v
if not attrs:
continue
action = handle_request(attrs)
print(f"action={action}\n")
sys.stdout.flush()
if __name__ == "__main__":
main() Don't forget to set execution bit:
chmod +x /usr/local/bin/policyguard.py
copy templates, if not already done:
mkdir -p /etc/pmg/templates/
cp /var/lib/pmg/templates/master.cf.in /etc/pmg/templates/
cp /var/lib/pmg/templates/main.cf.in /etc/pmg/templates/Add the policy_service to the existing smtpd_sender_restrictions to main.cf.in:
smtpd_sender_restrictions =
check_policy_service unix:private/policygrd Add the two lines to the bottom of the master.cf.in
policygrd unix - n n - 0 spawn
user=nobody argv=/usr/local/bin/policyguard.py pmgconfig sync --restart
How to test?
Connect to service:
apt install socat
socat - UNIX-CONNECT:/var/spool/postfix/private/policygrd
sender=Diese E-Mail-Adresse ist vor Spambots geschützt! Zur Anzeige muss JavaScript eingeschaltet sein.
<--- empty line
action=dunno
sender=Diese E-Mail-Adresse ist vor Spambots geschützt! Zur Anzeige muss JavaScript eingeschaltet sein.
<--- empty line
firebase-spf-policy: blocked sender domain babyamerica.com
action=reject Rejected for policy reasons [fbs]
sender=Diese E-Mail-Adresse ist vor Spambots geschützt! Zur Anzeige muss JavaScript eingeschaltet sein.
<--- empty line
spf-policy: blocked sender by regex (^[a-z0-9]{1,3}\+bnc[A-Z0-9]{10,}@): Diese E-Mail-Adresse ist vor Spambots geschützt! Zur Anzeige muss JavaScript eingeschaltet sein.
action=reject reject for policy reasons [gg]
Filter nach der Übermittlung von Mailbody ('blocked')
Ab hier liegt der vollständige Mailbody vor und wird in die Spamassassin Filterqueue gesendet. Hier beginnen die CPU-lastigen Filter. E-Mails werden im before-queue-filtering nach wie vor 'rejected', d.h. die Annahme wird verweigert und der Absender bekommen eine entsprechende Meldung von ihrem eigenen Mailserver.
Im Tracking Center stehen diese E-Mails als 'blocked' mit roter Hinterlegung.
Rspamd als CustomCheck integrieren
Rspamd bringt eine eigene Filterlogik mit und bietet weitreichende Funktionen (u.a. gut funktionierendes Greylisting), welches wir hier allerdings alles brach liegen lassen.
Wir nutzen ausschließlich den CustomScore, der sich zu unserem SA Score addiert.
I'm using Rspamd together with a custom script.
Rspamd has many advantages and works well alongside the SpamAssassin filters I’ve fine-tuned. You get a additional score which is great to sort out some additional spam. Bonus: Often it does NOT correlate with my other filters, so it is an added value.
The drawback of the custom script is that no further SpamAssassin checks are executed if the returned score is greater than 5.0 (nobody in the German forum could tell me why this happens). Therefore, I limit the score to 4.9 when outputting it—unless the score is extremely high (>9.0), in which case the email is blocked directly via before-queue filtering.
A further drawback of integrating Rspamd as a custom check is that all of Rspamd's features beyond the score itself remain unused. Among other things, Rspamd supports a considerably more sophisticated greylisting algorithm compared to Proxmox MG, which cannot be used in combination with custom check integration.
I often had the issue that the custom check seemed too high from my perspective.
At the same time, this created a latent problem where the score was capped between 5.0 and 9.9.
I’ve since had good results by halving the score in the “sensitive” range between 1.0 and 9.8:
- Small scores (both positive and negative) are output 1:1.
- Very high scores > 9.8 are also output 1:1 and therefore immediately block the email in my SA.
- Medium scores between 1.0 and 9.8 are scaled and output between 0.5 and 4.9. This means they don’t block any further SA checks, but they do reduce the likelihood of unjustified false positives in combination with other SA-Checks.
apt install rspamd
nano /etc/pmg/pmg.conf
#Enable the custom check script by adding or updating the following section:
section: admin
custom_check 1
custom_check_path /usr/local/bin/pmg-custom-check.sh
#Create the Custom Script
touch /usr/local/bin/pmg-custom-check.sh
chmod +x /usr/local/bin/pmg-custom-check.sh
cat > /usr/local/bin/pmg-custom-check.sh
Skript einfügen:
#!/usr/bin/env bash
set -euo pipefail
# PMG custom check API v1: args: APIVERSION QUEUEFILENAME
if [[ $# -ne 2 ]]; then
echo "usage: $0 APIVERSION QUEUEFILENAME" >&2
exit 1
fi
apiver="$1"
queue_file="$2"
RSPAMD_HOST="127.0.0.1"
RSPAMD_PORT="11333"
echo "v1"
# Rspamd check
rspamc_out="$(rspamc -h "${RSPAMD_HOST}:${RSPAMD_PORT}" < "$queue_file" 2>/dev/null || true)"
score="$(awk -F': ' '/^Score: /{split($2,a," "); print a[1]; exit}' <<<"$rspamc_out")"
if [[ -n "${score:-}" ]]; then
capped_score=$(awk -v s="$score" 'BEGIN { if (s >= 1.0 && s <= 9.8) printf "%.1f", s/2; else print s }')
echo "SCORE: ${capped_score}"
else
echo "OK"
fi
exit 0Server rebooten um Custom Checks zu aktivieren
Razor
Razor muss im PMG aktiviert werden
Configurations -> Spam Detector -> Options:
Use Razor2 checks: Yes
Und zusätzlich auf der Konsole einmalig registriert werden:
razor-admin -create
razor-admin -registeDer Default Score ist viel zu niedrig, also erhöhen wir diesen:
Configurations -> Spam Detector -> Custom Scores:
RAZOR2_CF_RANGE_51_100 : 8
RAZOR2_CHECK : 8
-> Apply Scores nicht vergessen
Pyzor
Pyzor empfehle ich als Erweiterung zu Razor2. Beide stammen aus der gleichen Entwicklungslinie, besitzen jedoch andere Datenbanken und finden daher auch unterschiedliche Mails.
apt install pyzor
mkdir -p /etc/pmg/templates
cp /var/lib/pmg/templates/init.pre.in /etc/pmg/templates//etc/pmg/templates/init.pre.in editieren und folgendes einfügen
loadplugin Mail::SpamAssassin::Plugin::Pyzor
/etc/pmg/spamassassin/local.cf editieren und folgendes einfügen
use_pyzor 1
Template Synchronisieren und PMG neustarten
pmgconfig sync --restart
Der Default Score ist viel zu niedrig, also erhöhen wir diesen:
Configurations -> Spam Detector -> Custom Scores:
PYZOR_CHECK : 8
-> Apply Scores nicht vergessen
Spamhausintegration in Spamassassin
Spamhaus bietet nicht nur die DNSBL (Ausschließlich Blockierung unseriöser Absender-IPs), sondern auch eine Spamassassin Integration, die manuell nachinstalliert werden muss und u.a. Inhaltsfilterung machen, z.B. Links im E-Mail Body zu bekannten Blacklist-Domains enthalten. Sie liefern (analog zu Pyzor und Razor) gute und sichere Funde. Die Filter im Tracking-Center beginnen alle mit SH.
Anleitung von hier: https://github.com/spamhaus/spamassassin-dqs?tab=readme-ov-file#instructions-for-spamassassin-400
Achtung: Hier muss ihr Spamhaus DQ-Key eingefügt werden.
apt install git
git clone https://github.com/spamhaus/spamassassin-dqs
cd spamassassin-dqs/4.0.0+
sed -i -e 's/your_DQS_key/<your spamhaus key>/g' sh.cf
sed -i -e 's/your_DQS_key/<your spamhaus key>/g' sh_hbl.cfEdit sh.pre with your editor of choice, and look at the first line
You will need to replace <config_directory> with your actual configuration directory /etc/mail/spamassassin, the line will become:
loadplugin Mail::SpamAssassin::Plugin::SH /etc/mail/spamassassin/SH.pm
If your key is not HBL enabled, this is what needs to be done:
cp sh.cf /etc/mail/spamassassin
cp sh_scores.cf /etc/mail/spamassassinScores sind alle schon sehr hoch gesetzt, Custom Scores sind daher nicht notwendig.
Geoblocking
Ich setze für einige Länder 7 Punkte, für andere 4, für Deutschland sogar -3. Der Rest (EU, USA) erhält gar keinen Score, also 0.
(This product includes GeoLite2 Data created by MaxMind, available from https://www.maxmind.com)
GeoIP Perl Modul installieren und Datenbank in spezifisches Verzeichnis herunterladen
apt install libgeoip2-perl
mkdir -p /var/lib/GeoIP
cd /var/lib/GeoIP
wget https://goto-url.de/GeoLite2-Country.mmdbIch gehe davon aus, dass ihr die init.pre-in bereits im lokalen Templateordner habt, weil wir sie für pyzor bereits anpassen mussten, ansonsten von /var/lib/templates nach /etc/pmg/templates kopieren.
/etc/pmg/templages/init.pre.in bearbeiten und folgende Zeile einkommentieren
loadplugin Mail::SpamAssassin::Plugin::RelayCountry
Eintrag in die /etc/mail/spamassassin/custom.cf
ifplugin Mail::SpamAssassin::Plugin::RelayCountry
geodb_module GeoIP2
geodb_search_path /var/lib/GeoIP/
header RELAYCOUNTRY_BAD X-Relay-Countries =~ /^(AR|CN|BR|IN|VN|RU|IR|PK|ID|BD|TR|NG|PH|TH|KP|SY|AF|YE|KZ|UA|BY|MD|GE|AM|AZ|TJ|KG|UZ|TM|MM|KH|LA|ET|GH|KE|TZ|UG)/
describe RELAYCOUNTRY_BAD First untrusted relay is Argentina, China, Brazil, India, Vietnam, Russia, Iran, Pakistan, Indonesien, Bangladesh, Türkei, Nigeria, Philippinen, Thailand, Nordkorea, Syrien, Afghanistan, Jemen, Ukraine, Belarus, Moldawien, Georgien, Armenien, Aserbaidschan, Tadschikistan, Kirgisistan, Usbekistan, Turkmenistan, Myanmar, Kambodscha, Laos, Aethiopien, Ghana, Kenia, Tansania, Uganda
score RELAYCOUNTRY_BAD 7.0
header RELAYCOUNTRY_SUSP X-Relay-Countries =~ /^(LT|EE|HU|RO|AU|IL|GB|RS|AL|BG|MK|ME|BA)/
describe RELAYCOUNTRY_SUSP First untrusted relay is Lithuania, Estonia, Hungary, Romania, Australien, Israel, GB, Serbien, Albanien, Bulgarien, Nordmazedonien, Montenegro, Bosnien
score RELAYCOUNTRY_SUSP 4.0
header RELAYCOUNTRY_GOOD X-Relay-Countries =~ /^(EU|DE)/
describe RELAYCOUNTRY_GOOD First untrusted relay is Deuschland or European Union :-)
score RELAYCOUNTRY_GOOD -3.0
add_header all Relay-Country _RELAYCOUNTRY_
endif # Mail::SpamAssassin::Plugin::RelayCountry PMG Config syncen (Dann wird das hier verwendete Template angewendet)
pmgconfig sync --restart
Testen, ob es funktioniert, oder ob GeoIP einen Fehler wirft. Im optimalen Fall seht ihr einen RELAYCOUNTRY Eintrag (das ist aber nicht zwangsweise so, wenn kein Score verteilt wird)
spamassassin -t < test.eml
Weitere Blocklisten
Die folgenden Listen finden sehr viel Spam, analog zu Pyzor, Razor2 und Spamhaus, daher nicht minder wichtig, hier die Scores zu erhöhen
Configuration -> Spam Detector -> Custom Scores
Blacklistfilter analog zu Pyzor, Razor, Spamhaus
RCVD_IN_BL_SPAMCOP: 8
URIBL_ABUSE_SURBL : 8
URIBL_BLACK : 8
URIBL_CT_SURBL : 8
URIBL_PH_SURBL : 4
URI_WP_HACKED_2 : 4
Apply Score nicht vergessen!
(Spamcop blockiert Google -> negieren wir weiter unten)
Weitere Filter
Ebenfalls bereits integriert und scharf geschaltet werden sollten:
Spam-Merkmale:
T_TVD_MIME_EPI : 8
GB_STORAGE_GOOGLE_HTM : 6
KAM_STORAGE_GOOGLE : 6
AC_BR_BONANZA : 6
FSL_BULK_SIG : 6
FORGED_OUTLOOK_HTML : 6
FROMSPACE : 4
KAM_LAZY_DOMAIN_SECURITY : 4
Datum falsch:
DATE_IN_PAST_03_06 : 6
DATE_IN_PAST_06_12 : 6
DATE_IN_PAST_12_24 : 6
DATE_IN_PAST_24_48 : 6
DATE_IN_PAST_48_72 : 6
Absender Auffälligkeiten:
RCVD_HELO_IP_MISMATCH : 6
FROM_FMBLA_NEWDOM: 6
FROM_FMBLA_NEWDOM14: 6
FROM_FMBLA_NEWDOM28 : 6
T_SPF_PERMERROR : 6
SPF_SOFTFAIL : 4
MAILING_LIST_MULTI : 4
gute Whitelist:
DKIMWL_WL_HIGH : -6
Die folgenden Filter sorgten bei mir für Fehlfilterungen, deshalb habe ich einen Score von 0 zugewiesen:
SPF_HELO_NONE : 0
KAM_MARKSPAM : 0
HTTPS_HTTP_MISMATCH : 0
DEAR_SOMETHING : 0
Apply Score nicht vergessen!
Problematische Blocklisten deaktivieren
Validity reputation Listen machen nur Stress und filtern nicht wirklich. Man sollte sie in der custom.cf deaktivieren
Eintrag in die /etc/mail/spamassassin/custom.cf
dns_query_restriction deny sa-trusted.bondedsender.org
dns_query_restriction deny sa-accredit.habeas.com
dns_query_restriction deny bl.score.senderscore.comFilter kompilieren
Damit die Filter schneller abgearbeitet werden, sollten sie kompiliert werden. Wir benötigen hierzu ein paar Pakete und ein Moduleintrag in der custom.cf von Spamassassin.
apt install make gcc re2c
Eintrag in die /etc/mail/spamassassin/custom.cf
loadplugin Mail::SpamAssassin::Plugin::Rule2XSBody
Danach kompilieren und am Ende Spamassassin neustarten mit:
sa-compile
systemctl restart pmg-smtp-filter Nun haben wir alle Drittanbieterplugins ausgeschöpft. Aber wir können noch selbst SA-Filter erstellen. Einer der größten Übel sind die "BCC-Spam". Jemand erstellt einen Freemail Account bei einem Provider ohne ausgehendes Limit und schickt Spam E-Mails, bei dem alle Empfänger in den BCC kopiert werden.
Um sie zu erkennen, müssen wir To und CC dahingehend überprüfen, ob eine E-Mail Adresse aus der Transportliste enthalten ist. Wenn nein, stehen wir im BCC.
Achtung: Wer in Mailinglisten unterwegs ist, könnte hiermit Probleme bekommen. Auch Weiterleitungen von Free-Mail-Accounts an die eigene Domain sind hiervon betroffen. Hier ggf. mit der Welcomelist arbeiten.
Transportliste als gültige Empfänger:
Folgendes Skript erstellen, welches täglich die Transportliste für unsere BCC-Regel importiert (damit wir niemals vergessen können, diese Liste zu aktualisieren).
cat > /usr/local/bin/update-sa-bcc-whitelist.sh
#!/bin/bash
DOMAINS=$(cut -d' ' -f1 /etc/pmg/transport | sed 's/\./\\./g; s/-/\\-/g' | tr '\n' '|' | sed 's/|$//')
cat <<EOF > /etc/mail/spamassassin/98-bcc-transport-domains.cf
header BCC_SPAM_TOCC ToCc !~ /\@(${DOMAINS})/i
score BCC_SPAM_TOCC 2.0
describe BCC_SPAM_TOCC Domain nicht in Transport-Liste
EOF
sa-compile
systemctl restart pmg-smtp-filterSkript als ausführbar markieren und einmalig ausführen:
chmod +x /usr/local/bin/update-sa-bcc-whitelist.sh
/usr/local/bin/update-sa-bcc-whitelist.sh
Cron Eintrag für die tägliche Aktualisierung dieser Liste
Cron Table bearbeiten
crontab -e
Zeile einfügen
echo "0 0 * * 1 root /usr/local/bin/update-sa-bcc-whitelist.sh" > /etc/cron.d/sa-bcc-update
### Custom Rules in /etc/mail/spamassassin
# Die Regel 98-bcc-transport-domains.cf sollte nun schon existieren
Unseriöse Absenderdomains und BCC Spam
Markiert alle E-Mails unerwünschter Absenderdomains. Diese erhalten automatisch einen Score von 3.0, weil sie nahezu immer unseriös sind
Wenn die E-Mail von einer unseriösen TLD stammt, und ich zusätzlich nur im BCC stehe, dann wird ein weiterer "Bonus"-Score von 2.0 vergeben.
E-Mails die dieses Kriterium erfüllen sind fast immer Spam, Ausnahmen könnten ausländische Mailinglisten sein. Die müsste man in die Welcomelist eintragen.
cat <<EOF > /etc/mail/spamassassin/99-BCC_TLD.cf
header FROM_TLD_OTHER From =~ /\.(?!(?:com|net|info|org|de|at|ch|eu|shop)(?:>|$))[A-Za-z0-9-]+>?$/i
score FROM_TLD_OTHER 3.0
describe FROM_TLD_OTHER Sender uses unusual or risky TLD
meta BCC_AND_UNKNOWN_TLD (FROM_TLD_OTHER && BCC_SPAM_TOCC)
score BCC_AND_UNKNOWN_TLD 2.0
describe awkward sender and unknown recipientPositive Word List
Diese Regel(n) beinhalten Wörter, die i.d.R. darauf hindeuten, dass es sich um seriöse E-Mails handelt.
Wörter, die sich für einen negativen Score eignen sind insbesondere Adressdaten (Straße, PLZ, Nachname), sodass Bestellbestätigungen stets ankommen.
Auch Wörter aus eurer E-Mail Signatur sind super: Handelsregisternummer, Umsatzsteuer-ID, PGP Key, was ihr so mitsendet. Dann ist sichergestellt, dass Anworten auf eure E-Mails zuverlässig ankommen.
Aufpassen bei Wörtern, die auch in eurer E-Mail Adresse stehen. Wenn eine Domain <berufsbezeichnung>-<wohnort>.de lautet, eignet sich beides eher weniger für eine negative Bepunktung, sonst kommen E-Mail an mit Inhalt: "Hallo <berufsbezeichnung>-<wohnort>.de, haben sie auch Probleme mit ihrer Potenz".
cat <<EOF > /etc/mail/spamassassin/99-positive-word-list
body POS_STADT /\bStadt\b(?![-\w.@])/i
body POS_NACHNAME /\bNachname\b(?![-\w.@])/i
body POS_VORNAME /\bVorname\b(?![-\w.@])/i
body POS_88888 /\b88888\b(?![-\w.@])/i # PLZ
score POS_STADT -2.0
score POS_NACHNAME -2.0
score POS_VORNAME -2.0
score POS_88888 -4.0
EOFPositive Scores für besonders vertrauenswürdige Versender
Bestimmten Freemailer, die ihre Systeme im Griff haben bekommen positiven Score. (Nicht Gmail!). Hierzu gehört t-online.de, gmx.de, web.de, ionos/strato. Diese werden mit einem hohen Negativscore belohnt.
Ist aber sicher alles sehr individuell.
Darüber hinaus bekommen auch .de Domains positiven Score, weil sich im allgemeinen gezeigt hat, dass Spammer willkürliche Domains verwenden. Auch .de-Domains, aber die Fehlfilterquote ist aufgrund der vielen, eintrudelnden Mails aus eurem eigenen Land sicherlich erheblich höher.
header SERIOUS_FREEMAILER Received =~ /\b(yahoo\.com|mout\.kundenserver\.de|mout\.web\.de|mout\.gmx\.net|mailout\d+\.t-online\.de|cc-smtpout\d+\.netcologne\.de)\b/i
score SERIOUS_FREEMAILER -6.0
describe SERIOUS_FREEMAILER Mail von bevorzugtem SMTP-Out
header __LOCAL_DE_DOMAIN_FROM From =~ /\@[^>]+\.(de)\b/i
header __LOCAL_DE_DOMAIN_ENVFROM EnvelopeFrom =~ /\@[^>]+\.(de)\b/i
meta LOCAL_DE_DOMAIN (__LOCAL_DE_DOMAIN_FROM && __LOCAL_DE_DOMAIN_ENVFROM)
describe LOCAL_DE_DOMAIN Sender domain is .de
score LOCAL_DE_DOMAIN -2.0
Fine-Tuning:
Leider schlägt Pyzor manchmal auch bei legitimen Freemails an und Spamcop bei Google.
Deshalb binden wir Spamcop nicht via DNSBL ein, sondern erhöhen den Custom-Score und negieren den Google Effekt hier.
# Pyzor Freemail
meta FREEMAIL_PYZOR_NEG (FREEMAIL_FROM && PYZOR_CHECK)
score FREEMAIL_PYZOR_NEG -8.0
describe FREEMAIL_PYZOR_NEG Negate Pyzor Hit on Freemail
# Spamcop Google Negate
header __HELO_GOOGLE Received =~ /\.google\.com/i
meta SPAMCOP_GOOGLE_NEGATE (RCVD_IN_BL_SPAMCOP_NET && __HELO_GOOGLE)
score SPAMCOP_GOOGLE_NEGATE -8.0
describe SPAMCOP_GOOGLE_NEGATE Negate Spamcop Hit on GoogleDanach:
sa-compile
systemctl restart pmg-smtp-filterFazit
Ca. 50 % aller E-Mails sind gewünscht, d.h. 50% sind Spam.
Von 100% aller Spam sind:
- 3% per SPF Regel oder aufgrund ungültiger Absenderdomain oder HELO Check gefiltert
- 50 % via DNSBL gefiltert
- 25 % kommen von Google und werden über mein oben geschriebenen Policyguard gefiltert
=======================
Diese E-Mails werden bereits von Postfix aussortiert und sind im Tracking Center als REJECTED gekennzeichnet.
- 22 % gelangen in Spamassassin und werden dort gefiltert:
Von den 100% im SA gefilterten E-Mails:
- Werden ca. 50% durch Razor, Pyzor, SH, Geoblocking, Spamcop, URI Blocklisten erwischt.
- Ca. 30% werden durch andere Inhaltsfilter, BCC oder TLD-Score erwischt.
20% kommen durch, weil kein Inhaltsfilter anspricht
Das entspricht einer Block-Quote von ca. 95%.
Die Prozentangaben sind natürlich nicht für bare Münze zu nehmen:
- Das variiert von Tag zu Tag.
- Viele Filter überschneiden sich: So würden ohne DNSBL durchaus einige Mails an SPF scheitern. DNSBL überlappen sich zu weiten Teilen.
Keine guten Ergebnisse habe ich mit den folgenden Werkzeugen erreicht
DCC empfehle ich nicht.
Die Integration ist nicht trivial (Programm aus den Quellen selbst kompilieren und als Dienst installieren).
Das Problem: Standardmäßig werden hier zwar nur wenige Punkte vergeben, aber leider findet DCC kein "Spam" sondern "Bulkmail".
Es werden u.a. Eingangsbestätigungen von Versicherungen ("Vielen Dank für ihre E-Mail. Wir melden uns schnellstmöglich bei ihnen") und ähnliche Mails gefiltert.