Sicher ist Rspamd in der Lage, Mails abzuweisen. Aber legt man
action = "discard" in den Multimap Rules fest, wird discard als ungültige Aktion abgelehnt.
Nichtsdestotrotz... meine gepostete Lösung funktioniert so nicht. Der Score wird ignoriert, weil es in den default LUA für das Symbol SUBJECT_BLACKLISTED keine Festlegung gibt und deshalb der Score 0.00 angewandt wird. Außerdem wird type="mime_header" nicht akzeptiert.
Ich habe Stunden damit verbracht, eine eigene zusätzliche LUA Konfiguration zu erzeugen, die updatefest ist und keinen Cronjob benötigt, codierte Betreffs erkennt und den Spamscore so hoch setzt, dass die Nachricht praktisch wegen zu hoher Punktzahl abgewiesen wird.
Das Ergebnis war, dass die Map nicht mehr verarbeitet wurde. Sie war vorhanden, war lesbar, hatte das richtige Format (UTF-8 ohne BOM), aber ständig wurde "nil" zurück gegeben, bedeutet die Map-Regeln wurden nicht eingelesen, weil das Format angeblich ungültig war. Dann hatte ich einfach die Nase voll von diesen Zickereien.
So bin ich letztlich wieder auf die Lösung von Toorms zurück gegangen, denn sie tut eigentlich genau das was sie soll.
Allerdings habe ich das Script
subjectblacklister erweitert.
Man kann nach wie vor einzelne oder mehrere Wörter hinzufügen, jetzt mittels -add Parameter statt Unterscheidung zwischen -s und -w. Bei mehreren Wörtern werden sie alle auf Vorkommen in der angegebenen Reihenfolge geprüft, unabhängig davon ob sich Leerzeichen oder weitere Strings dazwischen befinden.
Umlaute und Sonderzeichen werden autom. aus dem Suchfilter entfernt und durch Platzhalter ersetzt, da diese i.d.R. im Mailbetreff codiert sind und deshalb uncodiert nicht erkannt werden würden.
Duplikate werden erkannt und entfernt.
Inkompatible Kodierung wird automatisch in UTF-8 konvertiert.
BOM (Byte Order Mark) wird autom. entfernt.
Filtereinträge werden strukturell auf Validität geprüft, fehlerhafte Syntax der Regex-Suchmuster werden korrigiert.
Filterregeln werden alphabetisch sortiert.
Folgende Befehlsparameter sind anwendbar:
-add "Text", --find "Text", --edit, --validate
Code: Select all
#!/bin/bash
strMapFile="/etc/rspamd/maps.d/blacklist_subject.map"
function expand_to_flexible_regex() {
echo "$1" | sed \
-e 's/[äöüßÄÖÜéèêáàâçñøåœëïÿúí–—‘’“”]/.*/g' \
-e 's/ \+/.*/g'
}
function add_entry() {
raw="$1"
reg=$(expand_to_flexible_regex "$raw")
if grep -Fxq "/.*${reg}.*/iu" "$strMapFile"; then
echo "Eintrag bereits vorhanden."
return
fi
echo "/.*${reg}.*/iu" >> "$strMapFile"
cleanup_map
}
function cleanup_map() {
local total_before=$(grep -c '^' "$strMapFile")
local non_empty=$(grep -cve '^$' "$strMapFile")
local removed=$((total_before - non_empty))
tmpfile=$(mktemp)
grep -v '^$' "$strMapFile" | sort -f | uniq > "$tmpfile"
mv "$tmpfile" "$strMapFile"
if [ "$removed" -gt 0 ]; then
echo "$removed Leerzeile(n) wurden entfernt."
fi
}
function normalize_existing_entries() {
local changed=0
tmpfile=$(mktemp)
while IFS= read -r line; do
if [[ "$line" =~ \\s\* || "$line" =~ " " ]]; then
newline=$(echo "$line" | sed -e 's/\\s\*/.*/g' -e 's/ \+/.*/g')
echo "$newline" >> "$tmpfile"
changed=$((changed + 1))
else
echo "$line" >> "$tmpfile"
fi
done < "$strMapFile"
if [ "$changed" -gt 0 ]; then
echo "$changed Eintrag/Einträge wurden normalisiert."
mv "$tmpfile" "$strMapFile"
cleanup_map
else
rm "$tmpfile"
fi
}
function auto_wrap_unformatted_lines() {
local changed=0
local tmpfile=$(mktemp)
while IFS= read -r line; do
if [[ -n "$line" ]]; then
if [[ "$line" =~ ^/.*[^/]*/[iu]*$ ]]; then
echo "$line" >> "$tmpfile"
else
echo "/.*${line}.*/iu" >> "$tmpfile"
changed=$((changed + 1))
fi
fi
done < "$strMapFile"
if [ "$changed" -gt 0 ]; then
echo "$changed Zeile(n) wurden automatisch umschlossen."
mv "$tmpfile" "$strMapFile"
cleanup_map
else
rm "$tmpfile"
fi
}
function expand_existing_special_characters() {
echo "Ersetze Sonderzeichen in bestehenden Einträgen"
local changed=0
local tmpfile=$(mktemp)
while IFS= read -r line; do
if [[ "$line" =~ ^/.*[^/]*/[iu]*$ ]]; then
regex=$(echo "$line" | sed -E 's|^/(.*)/[iu]*$|\1|')
expanded=$(echo "$regex" | sed \
-e 's/[äöüßÄÖÜéèêáàâçñøåœëïÿúí–—‘’“”]/.*/g' \
-e 's/ \+/.*/g')
if [ "$regex" != "$expanded" ]; then
echo "/.*${expanded}.*/iu" >> "$tmpfile"
changed=$((changed + 1))
else
echo "$line" >> "$tmpfile"
fi
else
echo "$line" >> "$tmpfile"
fi
done < "$strMapFile"
if [ "$changed" -gt 0 ]; then
echo "$changed Eintrag/Einträge wurden erweitert."
mv "$tmpfile" "$strMapFile"
cleanup_map
else
rm "$tmpfile"
fi
}
function check_regex_structure() {
local invalid=0
while IFS= read -r line; do
if ! [[ "$line" =~ ^/.*[^/]*/[iu]*$ ]]; then
echo "Strukturell ungültig: $line"
invalid=$((invalid + 1))
fi
done < "$strMapFile"
if [ "$invalid" -eq 0 ]; then
echo "Alle Einträge sind strukturell korrekt für Rspamd."
else
echo "$invalid strukturell ungültige Zeile(n) gefunden."
fi
}
function validate_map() {
echo "Prüfe Map-Datei: $strMapFile"
if [ ! -f "$strMapFile" ]; then
echo "Datei existiert nicht."
return 1
fi
if [ ! -r "$strMapFile" ]; then
echo "Datei ist nicht lesbar."
return 1
fi
encoding=$(file -b --mime-encoding "$strMapFile")
if [ "$encoding" != "utf-8" ] && [ "$encoding" != "us-ascii" ]; then
echo "Datei ist nicht UTF-8-kompatibel: $encoding → konvertiere..."
iconv -f "$encoding" -t UTF-8 "$strMapFile" -o "$strMapFile.tmp" && mv "$strMapFile.tmp" "$strMapFile"
fi
bomcheck=$(head -c 3 "$strMapFile" | od -An -tx1 | tr -d ' ')
if [ "$bomcheck" == "efbbbf" ]; then
echo "Datei enthält BOM → entferne..."
tail -c +4 "$strMapFile" > "$strMapFile.tmp" && mv "$strMapFile.tmp" "$strMapFile"
fi
cleanup_map
normalize_existing_entries
auto_wrap_unformatted_lines
expand_existing_special_characters
check_regex_structure
echo "Map-Validierung abgeschlossen."
return 0
}
case "$1" in
"-add")
shift
if [ "$#" -eq 0 ]; then
echo "Fehler: Kein Text angegeben."
echo "Verwendung: -add \"Wort\" oder -add \"Mehrere Wörter\""
exit 1
fi
if [ "$#" -gt 1 ]; then
echo "Fehler: Mehrere Wörter ohne Anführungszeichen erkannt."
echo "Bitte verwende: -add \"Mehrere Wörter\""
exit 1
fi
add_entry "$1"
;;
"--find")
grep -i "$2" "$strMapFile"
;;
"--edit")
nano "$strMapFile"
;;
"--validate")
validate_map
;;
*)
echo "Verwendung:"
echo " -add \"Text\" → fügt Wort oder Satz hinzu"
echo " --find \"Text\" → sucht in der Map"
echo " --edit → öffnet die Map im Editor"
echo " --validate → prüft und bereinigt die Map"
exit 0
;;
esac
systemctl restart rspamd.service
exit 0