Ein kleines Werkzeug zum Verständnis der Spam-Filterung
Ethan Miller
Product Engineer · Leapcell

Was ist beim Versenden einer E-Mail am wichtigsten? Der Absender und der Empfänger, aber was noch?
Darüber hinaus ist das wichtigste Element zweifellos die Spam-Filterung. Jeder E-Mail-Client verfügt über diese Funktion, und sein Urteil kann über das Schicksal einer E-Mail entscheiden – ob Sie sie jemals zu sehen bekommen.
Dieser Artikel führt Sie durch die Prinzipien der Spam-Filterung und hilft Ihnen beim Aufbau eines kleinen Werkzeugs zur Erkennung von Spam.
Oder – alternativ – können Sie dieses Werkzeug verwenden, um Ihre eigenen E-Mails proaktiv zu überprüfen und zu überarbeiten, um zu verhindern, dass sie als Spam markiert werden ;-).
Wie Spam-Filterung funktioniert
Spam-Filterung basiert oft auf einem Programm namens Apache SpamAssassin.
Apache SpamAssassin ist eine Open-Source-Spam-Erkennungsplattform, die von der Apache Software Foundation unterhalten wird und ein weit verbreitetes Werkzeug für viele E-Mail-Clients und E-Mail-Filterungstools ist, um Nachrichten als Spam zu klassifizieren.
Es verwendet eine Vielzahl von Regeln, Bayesscher Filterung und Netzwerktests, um einer gegebenen E-Mail eine Spam-"Bewertung" zuzuweisen. Im Allgemeinen besteht bei einer E-Mail mit einer Bewertung von 5 oder höher ein hohes Risiko, dass sie als Spam markiert wird.
SpamAssassin lokal installieren, um Spam zu erkennen
Es ist wichtig zu beachten, dass SpamAssassin nur unter Linux ausgeführt werden kann. Sie benötigen daher ein Linux-Betriebssystem oder einen Docker-Container.
Verwenden Sie auf Debian/Ubuntu-Systemen die folgenden Befehle, um SpamAssassin zu installieren:
apt-get update && apt-get install -y spamassassin sa-update
Der Befehl sa-update
wird verwendet, um die Erkennungsregeln von SpamAssassin auf die neueste Version zu aktualisieren.
Sobald es installiert ist, können wir es zur Spam-Erkennung verwenden. Die Verwendung ist wie folgt:
spamassassin -t < input_email.txt > results.txt
Dieser Befehl übergibt input_email.txt
an SpamAssassin und schreibt die Erkennungsergebnisse in results.txt
.
Der Inhalt von results.txt
wird ungefähr so aussehen, wobei die SpamAssassin-Bewertung und die Begründung am Ende aufgeführt sind.
X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on 254.254.254.254
X-Spam-Level:
X-Spam-Status: No, score=0.2 required=5.0 tests=HTML_MESSAGE,
MIME_HTML_ONLY,MISSING_MID,NO_RECEIVED,
NO_RELAYS autolearn=no autolearn_force=no version=4.0.0
// ...
Content analysis details: (0.2 points, 5.0 required)
pts rule name description
---- ---------------------- --------------------------------------------------
0.1 MISSING_MID Missing Message-Id: header
-0.0 NO_RECEIVED Informational: message has no Received headers
-0.0 NO_RELAYS Informational: message was not relayed via SMTP
0.0 HTML_MESSAGE BODY: HTML included in message
0.1 MIME_HTML_ONLY BODY: Message only has text/html MIME parts
SpamAssassin in eine API einpacken
Damit Nicht-Linux-Geräte SpamAssassin verwenden können oder es in andere Arbeitsabläufe integriert werden kann, können wir es in eine API einpacken.
Ein typischer Anwendungsfall für diese API wäre beispielsweise: Bevor Sie auf die Schaltfläche "Senden" einer E-Mail klicken, wird der Inhalt zuerst an die SpamAssassin-API gesendet. Die E-Mail darf nur gesendet werden, wenn sie die Kriterien für Nicht-Spam erfüllt.
Als Nächstes erstellen wir mit Python eine einfache API, die die folgenden E-Mail-Felder akzeptiert: subject
, html_body
und text_body
. Sie übergibt diese Felder an SpamAssassin und gibt das Validierungsergebnis zurück.
from fastapi import FastAPI from datetime import datetime, timezone from email.utils import format_datetime from pydantic import BaseModel import subprocess def extract_analysis_details(text): lines = text.splitlines() start_index = None for i, line in enumerate(lines): if line.strip().startswith("pts rule"): start_index = i break if start_index is None: print("No content analysis details found.") return [] data_lines = lines[start_index+2:] parsed_lines = [] for line in data_lines: if line.strip() == "": break parsed_lines.append(line) results = [] current_entry = None split_line = lines[start_index+1] pts_split, rule_split, *rest = split_line.strip().split(" ") pts_start = 0 pts_end = pts_start + len(pts_split) rule_start = pts_end + 1 rule_end = rule_start + len(rule_split) desc_start = rule_end + 1 for line in parsed_lines: pts_str = line[pts_start:pts_end].strip() rule_name_str = line[rule_start:rule_end].strip() description_str = line[desc_start:].strip() if pts_str == "" and rule_name_str == "" and description_str: if current_entry: current_entry["description"] += " " + description_str else: current_entry = { "pts": pts_str, "rule_name": rule_name_str, "description": description_str } results.append(current_entry) return results app = FastAPI() class Email(BaseModel): subject: str html_body: str text_body: str @app.post("/spam_check") def spam_check(email: Email): # assemble the full email message = f"""From: example@example.com To: recipient@example.com Subject: {email.subject} Date: {format_datetime(datetime.now(timezone.utc))} MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="__SPAM_ASSASSIN_BOUNDARY__" --__SPAM_ASSASSIN_BOUNDARY__ Content-Type: text/plain; charset="utf-8" {email.text_body} --__SPAM_ASSASSIN_BOUNDARY__ Content-Type: text/html; charset="utf-8" {email.html_body} --__SPAM_ASSASSIN_BOUNDARY__--""" # Run SpamAssassin and capture the output directly output = subprocess.run(["spamassassin", "-t"], input=message.encode('utf-8'), capture_output=True) output_str = output.stdout.decode('utf-8', errors='replace') details = extract_analysis_details(output_str) return {"result": details}
Im obigen Code definieren wir eine Hilfsfunktion extract_analysis_details
, um die Gründe für die Bewertung aus der vollständigen Ausgabe zu extrahieren. Sie können diese Funktion weiter modifizieren, zum Beispiel, um bestimmte Regeln aus den Ergebnissen herauszufiltern.
Testen wir diese API. Übergeben Sie die folgenden Parameter:
Betreff
Claim Your Prize
html_body
<h2>Claim Your Prize</h2> <p>Dear Winner:</p> <p>Click the link below to claim your prize.</p>
text_body
Claim Your Prize
Dear Winner:
Click the link below to claim your prize.
Das zurückgegebene Ergebnis ist wie folgt:
[ { "pts": "0.1", "rule_name": "MISSING_MID", "description": "Missing Message-Id: header" }, { "pts": "-0.0", "rule_name": "NO_RECEIVED", "description": "Informational: message has no Received headers" }, { "pts": "3.1", "rule_name": "DEAR_WINNER", "description": "BODY: Spam with generic salutation of \"dear winner\"" }, { "pts": "-0.0", "rule_name": "NO_RELAYS", "description": "Informational: message was not relayed via SMTP" }, { "pts": "0.0", "rule_name": "HTML_MESSAGE", "description": "BODY: HTML included in message" } ]
Wie Sie sehen können, ist die Phrase "Dear Winner" sehr verdächtig, da sie häufig in verschiedenen Spam-E-Mails verwendet wird.
Bereitstellung dieses API-Tools online
Durch die Online-Bereitstellung dieses kleinen Tools können Sie jederzeit Spam erkennen.
Da dieses Tool in Python geschrieben ist und Apache SpamAssassin im Voraus installiert sein muss, scheint es, als könnten Sie es nur über Dienste wie AWS EC2 oder DigitalOcean bereitstellen. Diese können jedoch teuer sein und der Bereitstellungsprozess ist komplex.
Gibt es geeignetere Werkzeuge?
Ja, Sie können Leapcell zur Bereitstellung verwenden.
Leapcell unterstützt die Bereitstellung verschiedener Sprachen, darunter Python, Go und Rust. Es verwendet eine Docker-Architektur, die die Installation verschiedener zugrunde liegender Bibliotheken ermöglicht. Am wichtigsten ist, dass Leapcell nur die tatsächliche Anzahl der API-Aufrufe berechnet, was bedeutet, dass es völlig kostenlos ist, ein Projekt im Leerlauf zu haben. Dies macht es erheblich günstiger als Plattformen wie AWS und DigitalOcean.
Die Bereitstellungsschritte sind einfach:
-
Schieben Sie das Projekt nach GitHub.
-
Klicken Sie in Leapcell auf "Service erstellen" und wählen Sie dieses GitHub-Projekt aus.
-
Geben Sie den folgenden Befehl im Feld "Build Command" ein, um SpamAssassin zu installieren:
apt-get update && apt-get install -y spamassassin
sa-update
pip install -r requirements.txt
- Klicken Sie auf "Submit" (Absenden).
Sobald es bereitgestellt ist, haben Sie eine API zur Spam-Validierung! Jedes Mal, wenn die API aufgerufen wird, wird SpamAssassin ausgeführt, die E-Mail bewertet und die Bewertung zurückgegeben.