Sieve: Unterschied zwischen den Versionen
Keine Bearbeitungszusammenfassung |
K Textersetzung - „== Syntax ==“ durch „== Aufruf ==“ |
||
(30 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
''' | '''Sieve''' - Sprache zur Konfiguration von [[Mailfilter]]n auf [[Mailserver]]n durch Benutzer | ||
== Beschreibung == | == Beschreibung == | ||
'''Sieve''' ist eine [[domänenspezifische Sprache]], die zum Konfigurieren von [[Mailfilter]]n auf [[Mailserver]]n durch Benutzer konzipiert wurde. | '''Sieve''' ist eine [[domänenspezifische Sprache]], die zum Konfigurieren von [[Mailfilter]]n auf [[Mailserver]]n durch Benutzer konzipiert wurde. | ||
* Die genaue Spezifikation kann im RFC 5228 nachgelesen werden. | * Die genaue Spezifikation kann im RFC 5228 nachgelesen werden. | ||
Sieve ist spezifiziert worden, um Nutzern die Möglichkeit zu geben, auf einfache Art eigene Regeln zum Filtern von E-Mails zu definieren. | Sieve ist spezifiziert worden, um Nutzern die Möglichkeit zu geben, auf einfache Art eigene Regeln zum Filtern von E-Mails zu definieren. | ||
* Dabei ist es jedoch nicht möglich, komplexere Programmstrukturen, die beispielsweise mit Schleifen oder Variablen arbeiten, zu benutzen oder externe Programme zu starten. | * Dabei ist es jedoch nicht möglich, komplexere Programmstrukturen, die beispielsweise mit Schleifen oder Variablen arbeiten, zu benutzen oder externe Programme zu starten. | ||
* Das Hauptaugenmerk von Sieve liegt auf Erweiterbarkeit, Einfachheit und Unabhängigkeit von der verwendeten Zugriffsart und Architektur und dem verwendeten Betriebssystem. | * Das Hauptaugenmerk von Sieve liegt auf Erweiterbarkeit, Einfachheit und Unabhängigkeit von der verwendeten Zugriffsart und Architektur und dem verwendeten Betriebssystem. | ||
* Sieve- | * Sieve-Scripts werden bereits während der Zustellung der E-Mail am Posteingangsserver ausgeführt. | ||
; Verbreitung | ; Verbreitung | ||
Sieve-Skripte werden von vielen Mailservern und [[E-Mail-Programm|E-Mail-Clients]] direkt oder über Plugins unterstützt. | Sieve-Skripte werden von vielen Mailservern und [[E-Mail-Programm|E-Mail-Clients]] direkt oder über Plugins unterstützt. | ||
Darüber hinaus gibt es [[Programmbibliothek|Libraries]] zum [[Parser|Parsen]] von Sieve-Skripten für die Programmiersprachen [[C (Programmiersprache)|C]], [[Ruby (Programmiersprache)|Ruby]], [[Java (Programmiersprache)|Java]], [[PHP]], [[Perl (Programmiersprache)|Perl]] und [[Python (Programmiersprache)|Python]]. | |||
== Anwendung == | == Anwendung == | ||
; Sieve ist ein skriptbasierter Mailfilter mit sehr umfangreichen Möglichkeiten. | |||
* Obwohl mit websieve eine graphische Oberfläche installiert werden kann, hat die Vorgehensweise über eine Textdatei und Konsole entscheidende Vorteile. | |||
* So kann man die Filterregeln auch zu einem späteren Zeitpunkt einfacher ordnen und hat mehr Kontrolle über die Syntax. | |||
Installation | |||
; Sieve wird bereits mit Cyrus IMAPD installiert. | |||
* Die erfolgreiche Konfiguration und Inbetriebnahme von Cyrus IMAPD wird an dieser Stelle vorausgesetzt. | |||
* Ansonsten ist Sieve natürlich auch mit Dovecot verwendbar - eine Möglichkeit über den pythonbasierten Sieve-Daemon pysieved 🇬🇧 findet man im Beitrag Pysieved on workaround mail. | |||
Benutzerdefiniertes Regelwerk | |||
; Sieve ist ein leistungsfähiger Mailfilter, der benutzerabhängig ist. | |||
* Da jeder Nutzer eigene Filterregeln entsprechend seiner Bedürfnisse hat, ist dieses Vorgehen sinnvoll. | |||
* Deshalb wird hier nur beispielhaft erläutert, welche Filterregeln existieren und wie diese in der Skriptsprache aufgestellt werden. | |||
* Die Abfragen erfolgen mit if ... elsif ... else, so dass eine hierarchische Filterung möglich und sinnvoll ist. | |||
* Die komplette Syntax und Erläuterungen sind unter den Links angegeben. | |||
; Normalerweise erwartet sieve die Filterregeln im Verzeichnis /var/spool/sieve. | |||
* Dieses Verzeichnis erfordert aber andere Rechte, deshalb bietet es sich an, eine versteckte Textdatei .sieve-mail-filter im Heimatverzeichnis zu erstellen [1], um sie vor versehentlichen Zugriffen zu schützen. | |||
Hinweis: | |||
Gewöhnlich ist man auf einem Server/ virtuellen Server als root eingeloggt. | |||
In die shell des Benutzers wechseln. | |||
su - Benutzername | |||
Nach dem Einrichten von Sieve | |||
exit | |||
=== Dateiheader === | |||
Im Kopf der Textdatei wird sieve mitgeteilt, welche Module benötigt werden. | |||
* Kommentare werden durch eine Raute (#) eingeleitet oder durch Slash und Asterisk (/* Kommentar */) eingeschlossen. | |||
# Datum, User | |||
require "fileinto"; /* Modul zur Verschiebung der Mails, immer erforderlich */ | |||
require "reject"; /* Modul zur Zurückweisung, optional */ | |||
require "vacation"; /* Modul für Abwesenheitsbenachrichtigungen, optional */ | |||
=== Mails in Ordner verschieben === | |||
fileinto verschiebt Mails in die angegeben Unterordner. | |||
* Filtern lässt sich nach verschiedenen Schlüsselwörtern. | |||
* anyof stellt dabei eine ODER-Verknüpfung dar, allof eine UND-Verknüpfung. | |||
# Mails verschieben | |||
if header :contains "from" ["ebay.de", "ebay.com"] { fileinto "INBOX.ebay"; } | |||
elsif header :contains "subject" "Ltsp-discuss" { fileinto "INBOX.mailinglisten.ltsp"; } | |||
elsif header :contains "subject" "Capisuite-users" { fileinto "INBOX.mailinglisten.capisuite"; } | |||
elsif allof (header :contains "from" "zitate.at", header :contains "subject" "Zitat des Tages") | |||
{ fileinto "INBOX.mailinglisten.zitate"; } | |||
else { fileinto "INBOX"; } | |||
=== Mails zurückweisen === | |||
Falls Mails ab einer bestimmten Größe zurückgewiesen werden sollen, verwendet man reject: | |||
# mails zurückweisen | |||
if size :over 10M { reject;} | |||
Um Mails von Spammern zurückzuweisen, empfiehlt sich ein Spamfilter oder das Löschen der Mails mit discard: | |||
if header :contains "subject" "viagra" { discard; } | |||
Ein tatsächliches Zurückweisen hätte zur Folge, dass der Spammer durch die Rückmeldung die Echtheit der Adresse bestätigt bekommt. | |||
Damit reject keine Fehlermeldung produziert, muss in der Datei /etc/postfix/master.cf folgende Zeilen wie folgt geändert werden [1]: | |||
#flags=R user=cyrus argv=/usr/sbin/cyrdeliver -e -m ${extension} ${user} | |||
#folgende zeile ersetzt obere zeile, um reject funktion zu ermöglichen | |||
flags= user=cyrus argv=/usr/sbin/cyrdeliver -r ${sender} -m ${extension} ${user} | |||
=== Abwesenheitsnachrichten === | |||
Bei Abwesenheit (z. B. Urlaub), wenn man keine Mails beantworten kann, verschickt sieve automatisch eine Standardantwort. | |||
* Ein bestimmter Absender erhält nur eine einzige Abwesenheitsbenachrichtigung, auch wenn er mehrere E-Mails schickt. | |||
* Eine weitere Benachrichtigung erhält er erst wieder nach sieben Tagen. | |||
* Will man diesen Wert ändern, so dass bis zur nächsten Benachrichtigung z. B. 14 Tage gewartet wird, so benutzt man dafür die Option :days <Anzahl Tage>, die vor der Option :addresses eingefügt wird. | |||
Die Abwesenheitsfunktion erfordert im Dateikopf das Modul vacation: | |||
# Abwesenheitsnachrichten | |||
vacation :days <Anzahl Tage> :addresses ["Adresse1", "Adresse2"] "Text"; | |||
=== Aktivierung von Sieve === | |||
Die Datei muss noch entsprechend aktiviert werden. | |||
* Nach Aufruf von sieveshell im Terminal [2] | |||
sieveshell -u BENUTZERNAME localhost | |||
wird die Eingabe des IMAP-Kennworts des Nutzers verlangt. | |||
* Danach kann man die Konfigurationsdatei hochladen: | |||
put .sieve-mail-filter | |||
activate .sieve-mail-filter | |||
quit | |||
Bei fehlerhafter Syntax erhält man eine Fehlermeldung mit einer Zeilenangabe, so dass sich die Fehlersuche einfach gestaltet. | |||
* help listet die verfügbaren Kommandos und Erläuterungen zu sieveshell. | |||
;Hinweis | |||
Sollte die nachfolgende Fehlermeldung auftauchen: | |||
unable to connect to server at /usr/bin/sieveshell line 179, <STDIN> line 1\\ | |||
und damit die Verbindung zur sieveshell scheitern, hilft folgendes: | |||
adduser cyrus mail #(soweit noch nicht beim Einrichten von cyrus erfolgt) | |||
chown root:mail -R /var/spool/sieve | |||
chmod 770 -R /var/spool/sieve | |||
Für jeden Nutzer muss das entsprechende benutzerspezifische Regelwerk aktiviert werden. | |||
Grafische Helfer zum Konfigurieren der Sieve-Skripte | |||
Zumindest, wenn man pysieved verwendet - welcher als Daemon läuft - hat man den Vorteil, dass man clientseitig konfigurieren kann, ohne SSH-Zugriff oder dergleichen auf den Server haben zu müssen. | |||
* Folgende E-Mail-Clients können zum konfigurieren genutzt werden (kein Anspruch auf Vollständigkeit): | |||
=== Thunderbird === | |||
Unter Thunderbird ist das Sieve-Skript mit dem Sieve Plugin möglich (alternativ auch auf der Mozilla-Thunderbird-Plugin-Seite). | |||
=== kMail === | |||
Ebenso kann es mit kMail verwendet werden | |||
=== Squirrelmail (Webmailer)=== | |||
Wenn man als Webmailer Archiv/Squirrelmail verwendet, gibt es auch ein sehr gutes Plugin namens AvelSieve, bei dem man wahlweise textbasiert, umgangssprachlich oder grafisch seine Sieve-Filter konfigurieren kann. | |||
=== Roundcube === | |||
=== Beispielskript === | |||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
# Beispielskript | # Beispielskript | ||
Zeile 24: | Zeile 141: | ||
if size :over 100K { | if size :over 100K { | ||
reject "Bitte senden Sie mir das nächste Mal eine kleinere Mail. | |||
* Bei großen Anhängen laden Sie bitte die Dateien auf einen Server und schicken Sie mir eine URL. | * Bei großen Anhängen laden Sie bitte die Dateien auf einen Server und schicken Sie mir eine URL. | ||
* Danke."; | * Danke."; | ||
} | } | ||
Zeile 33: | Zeile 150: | ||
elsif address :is ["From", "To"] "mailinglist@example.com" { | elsif address :is ["From", "To"] "mailinglist@example.com" { | ||
fileinto "INBOX.mailinglist"; | |||
# Bei einigen Mailserver-Konfigurationen muss statt eines Punktes hierbei ein Schrägstrich verwendet werden. | # Bei einigen Mailserver-Konfigurationen muss statt eines Punktes hierbei ein Schrägstrich verwendet werden. | ||
} | } | ||
Zeile 43: | Zeile 160: | ||
elsif anyof (not address :all :contains ["To", "Cc", "Bcc"] "me@example.com", | elsif anyof (not address :all :contains ["To", "Cc", "Bcc"] "me@example.com", | ||
header :matches "Subject" ["*money*","*Viagra*"]) { | header :matches "Subject" ["*money*","*Viagra*"]) { | ||
fileinto "INBOX.spam"; | |||
} | } | ||
Zeile 52: | Zeile 169: | ||
else { | else { | ||
keep; | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== | == Aufruf == | ||
Anweisungen werden mit dem Semikolon abgeschlossen | Anweisungen werden mit dem Semikolon abgeschlossen | ||
=== Kommentare === | === Kommentare === | ||
Kommentare werden durch das Zeichen "#" eingeleitet. | Kommentare werden durch das Zeichen "#" eingeleitet. | ||
* Diese Kommentare gelten immer bis zum Zeilenende. | * Diese Kommentare gelten immer bis zum Zeilenende. | ||
* Mehrzeilige Kommentare werden wie in [[C (Programmiersprache)|C]] mit dem String "/*" eingeleitet und mit dem String "*/" abgeschlossen. | * Mehrzeilige Kommentare werden wie in [[C (Programmiersprache)|C]] mit dem String "/*" eingeleitet und mit dem String "*/" abgeschlossen. | ||
=== Zahlen === | === Zahlen === | ||
Nur positive Ganzzahlen sind erlaubt. | Nur positive Ganzzahlen sind erlaubt. | ||
* Optional gibt es die Möglichkeit, die Größe über Angaben wie "'''K'''" ([[Binärpräfix|KiB]], 2^10), "'''M'''" ([[Binärpräfix|MiB]], 2^20) und "'''G'''" ([[Binärpräfix|GiB]], 2^30) anzugeben. | * Optional gibt es die Möglichkeit, die Größe über Angaben wie "'''K'''" ([[Binärpräfix|KiB]], 2^10), "'''M'''" ([[Binärpräfix|MiB]], 2^20) und "'''G'''" ([[Binärpräfix|GiB]], 2^30) anzugeben. | ||
* Beispiel: 100K steht für eine Größe von 100 [[Binärpräfix|Kibibytes]]. | * Beispiel: 100K steht für eine Größe von 100 [[Binärpräfix|Kibibytes]]. | ||
=== Strings === | === Strings === | ||
Strings (Zeichenketten) werden durch das Anführungszeichen ''"'' eingeleitet. | Strings (Zeichenketten) werden durch das Anführungszeichen ''"'' eingeleitet. | ||
* Ein Backslash ("\") wird verwendet, um weitere Anführungszeichen oder Backslashes zu kennzeichnen, die noch zur aktuellen Zeichenkette gehören (sogenanntes "Escapen"). | * Ein Backslash ("\") wird verwendet, um weitere Anführungszeichen oder Backslashes zu kennzeichnen, die noch zur aktuellen Zeichenkette gehören (sogenanntes "Escapen"). | ||
* String-Listen werden mit "[" eingeleitet und mit "]" abgeschlossen. | * String-Listen werden mit "[" eingeleitet und mit "]" abgeschlossen. | ||
Zeile 80: | Zeile 197: | ||
* else | * else | ||
Ein if leitet eine bedingte Anweisung ein. | Ein if leitet eine bedingte Anweisung ein. | ||
* Nur wenn die zu testende Bedingung zutrifft, wird der nachfolgende Codeblock ausgeführt. | * Nur wenn die zu testende Bedingung zutrifft, wird der nachfolgende Codeblock ausgeführt. | ||
* Wenn nicht, dann können weitere Bedingungen mittels elsif abgefragt werden. | * Wenn nicht, dann können weitere Bedingungen mittels elsif abgefragt werden. | ||
* Falls keine der Bedingungen aus den "if"- und "elsif"-Blöcken zutrifft, werden die Anweisungen des "else"-Blocks abgearbeitet, sofern er vorhanden ist. | * Falls keine der Bedingungen aus den "if"- und "elsif"-Blöcken zutrifft, werden die Anweisungen des "else"-Blocks abgearbeitet, sofern er vorhanden ist. | ||
=== Vergleiche von Zeichenketten === | === Vergleiche von Zeichenketten === | ||
Es bestehen mehrere Möglichkeiten, einen String zu testen. | Es bestehen mehrere Möglichkeiten, einen String zu testen. | ||
* Als Vergleichsoperatoren kommen hierbei zum Einsatz: | * Als Vergleichsoperatoren kommen hierbei zum Einsatz: | ||
Zeile 92: | Zeile 209: | ||
: prüft, ob eine bestimmte Zeichenkette in einem anderen String enthalten ist. | : prüft, ob eine bestimmte Zeichenkette in einem anderen String enthalten ist. | ||
; :is | ; :is | ||
: führt einen exakten Vergleich durch, d. h. | : führt einen exakten Vergleich durch, d. h. | ||
* die Inhalte der verglichenen Zeichenketten müssen exakt übereinstimmen. | * die Inhalte der verglichenen Zeichenketten müssen exakt übereinstimmen. | ||
; :matches | ; :matches | ||
: beinhaltet eine Möglichkeit, beim Vergleich Teile einer Zeichenkette ungeprüft zu belassen. | : beinhaltet eine Möglichkeit, beim Vergleich Teile einer Zeichenkette ungeprüft zu belassen. | ||
* Mit dem Symbol * können mehrere, mit dem Symbol ? genau ein Zeichen freigestellt werden. | * Mit dem Symbol * können mehrere, mit dem Symbol ? genau ein Zeichen freigestellt werden. | ||
* So wird beispielsweise G?n alle dreibuchstabigen Wörter mit einem großen G am Anfang und einem kleinen n am Ende finden, während G*n alle Wörter von Gin über Gasmann bis hin zu Gesundheitskartenevaluierungskommission und darüber hinaus adressieren wird. | * So wird beispielsweise G?n alle dreibuchstabigen Wörter mit einem großen G am Anfang und einem kleinen n am Ende finden, während G*n alle Wörter von Gin über Gasmann bis hin zu Gesundheitskartenevaluierungskommission und darüber hinaus adressieren wird. | ||
=== Adressen-Matching === | === Adressen-Matching === | ||
E-Mail-Adressen prüft man mit dem Keyword address | ; E-Mail-Adressen prüft man mit dem Keyword address | ||
* Natürlich ist es möglich, die Absender- oder die Empfängeradresse zu prüfen. | * Natürlich ist es möglich, die Absender- oder die Empfängeradresse zu prüfen. | ||
* Dabei wird generell nur auf die eigentliche Adresse verglichen, also alles was zwischen den spitzen Klammern geschrieben steht. | * Dabei wird generell nur auf die eigentliche Adresse verglichen, also alles was zwischen den spitzen Klammern geschrieben steht. | ||
* Um den kompletten String zu vergleichen, sollte man auf Name "<" Adresse ">" prüfen. | * Um den kompletten String zu vergleichen, sollte man auf Name "<" Adresse ">" prüfen. | ||
* Die Anführungszeichen kennzeichnen hierbei Strings. | * Die Anführungszeichen kennzeichnen hierbei Strings. | ||
* Um Adressen auf den Teil vor dem @ oder nach dem @ zu prüfen, können die optionalen Argumente :localpart beziehungsweise :domain genutzt werden. | * Um Adressen auf den Teil vor dem @ oder nach dem @ zu prüfen, können die optionalen Argumente :localpart beziehungsweise :domain genutzt werden. | ||
* Standardmäßig wird die komplette Adresse geprüft (entspricht :all). | * Standardmäßig wird die komplette Adresse geprüft (entspricht :all). | ||
=== Größenvergleiche === | === Größenvergleiche === | ||
Die Größe einer Mail prüft man mit dem Keyword size. | Die Größe einer Mail prüft man mit dem Keyword size. | ||
* Vergleiche mit Zahlen kann man mit den Operatoren :over beziehungsweise :under durchführen. | * Vergleiche mit Zahlen kann man mit den Operatoren :over beziehungsweise :under durchführen. | ||
=== Header-Felder === | === Header-Felder === | ||
[[Header (E-Mail)|E-Mail Header]] können mit dem Keyword header geprüft werden. | [[Header (E-Mail)|E-Mail Header]] können mit dem Keyword header geprüft werden. | ||
* Header-Felder können ganz normal mit den oben beschriebenen Zeichenketten-Vergleichen durchsucht werden. | * Header-Felder können ganz normal mit den oben beschriebenen Zeichenketten-Vergleichen durchsucht werden. | ||
* Es ist darauf zu achten, dass der Doppelpunkt nicht verwendet wird. | * Es ist darauf zu achten, dass der Doppelpunkt nicht verwendet wird. | ||
=== Blöcke === | === Blöcke === | ||
Blockanweisungen werden durch { eingeleitet und mit } beendet. | Blockanweisungen werden durch { eingeleitet und mit } beendet. | ||
* Blöcke werden genutzt, um nach einem Test mehrere Anweisungen durchzuführen. | * Blöcke werden genutzt, um nach einem Test mehrere Anweisungen durchzuführen. | ||
== Anweisungen == | == Anweisungen == | ||
{| class="wikitable sortable" | {| class="options wikitable sortable" | ||
|- | |- | ||
! Option !! Beschreibung | ! Option !! Beschreibung | ||
|- | |- | ||
| stop || Beendet die Ausführung. Falls keine Regel zugetroffen hat, wird die Nachricht in der INBOX belassen (Impliziertes keep) | | stop || Beendet die Ausführung. Falls keine Regel zugetroffen hat, wird die Nachricht in der INBOX belassen (Impliziertes keep) | ||
|- | |- | ||
| keep || Speichert die Nachricht in der INBOX | | keep || Speichert die Nachricht in der INBOX | ||
|- | |- | ||
Zeile 134: | Zeile 251: | ||
| discard || Löscht die Nachricht. Der Absender erhält davon keine Nachricht. | | discard || Löscht die Nachricht. Der Absender erhält davon keine Nachricht. | ||
|- | |- | ||
| reject || Diese Anweisung sorgt dafür, dass die Nachricht abgelehnt wird. | | reject || Diese Anweisung sorgt dafür, dass die Nachricht abgelehnt wird. | ||
* Optional kann man einen Grund für die Ablehnung angeben. | * Optional kann man einen Grund für die Ablehnung angeben. | ||
* Es wird eine sogenannte "Message Delivery Notification" erstellt. | * Es wird eine sogenannte "Message Delivery Notification" erstellt. | ||
* Falls man "reject" nutzen will, muss man dies über den "require reject" am Anfang des Scriptes anfordern. | * Falls man "reject" nutzen will, muss man dies über den "require reject" am Anfang des Scriptes anfordern. | ||
|- | |- | ||
| fileinto || Die Nachricht kann in einen bestimmten Ordner verschoben werden. | | fileinto || Die Nachricht kann in einen bestimmten Ordner verschoben werden. | ||
* Dazu muss als Argument der Folder in der für den Server spezifischen Form angegeben werden. | * Dazu muss als Argument der Folder in der für den Server spezifischen Form angegeben werden. | ||
* Will man "fileinto" nutzen, muss man es als erstes über den "require" anfordern. | * Will man "fileinto" nutzen, muss man es als erstes über den "require" anfordern. | ||
|} | |} | ||
Zeile 147: | Zeile 264: | ||
Sieve gestattet auch zusätzliche Erweiterungen, die am Anfang des Skriptes mit dem Schlüsselwort '''require''' deklariert werden müssen. | Sieve gestattet auch zusätzliche Erweiterungen, die am Anfang des Skriptes mit dem Schlüsselwort '''require''' deklariert werden müssen. | ||
<noinclude> | |||
== | == Anhang == | ||
=== | === Siehe auch === | ||
{{Special:PrefixIndex/{{BASEPAGENAME}}}} | |||
=== | ==== Dokumentation ==== | ||
==== Links ==== | |||
== | ===== Projekt ===== | ||
=== | ===== Weblinks ===== | ||
=== | |||
= | |||
= | |||
== | |||
== | |||
# https://github.com/thsmi/sieve/ | # https://github.com/thsmi/sieve/ | ||
# https://wiki.ubuntuusers.de/Archiv/sieve/ | # https://wiki.ubuntuusers.de/Archiv/sieve/ | ||
Zeile 171: | Zeile 282: | ||
# https://de.wikipedia.org/wiki/Sieve | # https://de.wikipedia.org/wiki/Sieve | ||
[[Kategorie:E-Mail/Filter]] | |||
</noinclude> | |||
[[Kategorie:E-Mail | |||
Aktuelle Version vom 12. November 2024, 19:40 Uhr
Sieve - Sprache zur Konfiguration von Mailfiltern auf Mailservern durch Benutzer
Beschreibung
Sieve ist eine domänenspezifische Sprache, die zum Konfigurieren von Mailfiltern auf Mailservern durch Benutzer konzipiert wurde.
- Die genaue Spezifikation kann im RFC 5228 nachgelesen werden.
Sieve ist spezifiziert worden, um Nutzern die Möglichkeit zu geben, auf einfache Art eigene Regeln zum Filtern von E-Mails zu definieren.
- Dabei ist es jedoch nicht möglich, komplexere Programmstrukturen, die beispielsweise mit Schleifen oder Variablen arbeiten, zu benutzen oder externe Programme zu starten.
- Das Hauptaugenmerk von Sieve liegt auf Erweiterbarkeit, Einfachheit und Unabhängigkeit von der verwendeten Zugriffsart und Architektur und dem verwendeten Betriebssystem.
- Sieve-Scripts werden bereits während der Zustellung der E-Mail am Posteingangsserver ausgeführt.
- Verbreitung
Sieve-Skripte werden von vielen Mailservern und E-Mail-Clients direkt oder über Plugins unterstützt.
Darüber hinaus gibt es Libraries zum Parsen von Sieve-Skripten für die Programmiersprachen C, Ruby, Java, PHP, Perl und Python.
Anwendung
- Sieve ist ein skriptbasierter Mailfilter mit sehr umfangreichen Möglichkeiten.
- Obwohl mit websieve eine graphische Oberfläche installiert werden kann, hat die Vorgehensweise über eine Textdatei und Konsole entscheidende Vorteile.
- So kann man die Filterregeln auch zu einem späteren Zeitpunkt einfacher ordnen und hat mehr Kontrolle über die Syntax.
Installation
- Sieve wird bereits mit Cyrus IMAPD installiert.
- Die erfolgreiche Konfiguration und Inbetriebnahme von Cyrus IMAPD wird an dieser Stelle vorausgesetzt.
- Ansonsten ist Sieve natürlich auch mit Dovecot verwendbar - eine Möglichkeit über den pythonbasierten Sieve-Daemon pysieved 🇬🇧 findet man im Beitrag Pysieved on workaround mail.
Benutzerdefiniertes Regelwerk
- Sieve ist ein leistungsfähiger Mailfilter, der benutzerabhängig ist.
- Da jeder Nutzer eigene Filterregeln entsprechend seiner Bedürfnisse hat, ist dieses Vorgehen sinnvoll.
- Deshalb wird hier nur beispielhaft erläutert, welche Filterregeln existieren und wie diese in der Skriptsprache aufgestellt werden.
- Die Abfragen erfolgen mit if ... elsif ... else, so dass eine hierarchische Filterung möglich und sinnvoll ist.
- Die komplette Syntax und Erläuterungen sind unter den Links angegeben.
- Normalerweise erwartet sieve die Filterregeln im Verzeichnis /var/spool/sieve.
- Dieses Verzeichnis erfordert aber andere Rechte, deshalb bietet es sich an, eine versteckte Textdatei .sieve-mail-filter im Heimatverzeichnis zu erstellen [1], um sie vor versehentlichen Zugriffen zu schützen.
Hinweis:
Gewöhnlich ist man auf einem Server/ virtuellen Server als root eingeloggt.
In die shell des Benutzers wechseln.
su - Benutzername
Nach dem Einrichten von Sieve
exit
Dateiheader
Im Kopf der Textdatei wird sieve mitgeteilt, welche Module benötigt werden.
- Kommentare werden durch eine Raute (#) eingeleitet oder durch Slash und Asterisk (/* Kommentar */) eingeschlossen.
# Datum, User require "fileinto"; /* Modul zur Verschiebung der Mails, immer erforderlich */ require "reject"; /* Modul zur Zurückweisung, optional */ require "vacation"; /* Modul für Abwesenheitsbenachrichtigungen, optional */
Mails in Ordner verschieben
fileinto verschiebt Mails in die angegeben Unterordner.
- Filtern lässt sich nach verschiedenen Schlüsselwörtern.
- anyof stellt dabei eine ODER-Verknüpfung dar, allof eine UND-Verknüpfung.
# Mails verschieben if header :contains "from" ["ebay.de", "ebay.com"] { fileinto "INBOX.ebay"; } elsif header :contains "subject" "Ltsp-discuss" { fileinto "INBOX.mailinglisten.ltsp"; } elsif header :contains "subject" "Capisuite-users" { fileinto "INBOX.mailinglisten.capisuite"; } elsif allof (header :contains "from" "zitate.at", header :contains "subject" "Zitat des Tages") { fileinto "INBOX.mailinglisten.zitate"; } else { fileinto "INBOX"; }
Mails zurückweisen
Falls Mails ab einer bestimmten Größe zurückgewiesen werden sollen, verwendet man reject:
# mails zurückweisen if size :over 10M { reject;}
Um Mails von Spammern zurückzuweisen, empfiehlt sich ein Spamfilter oder das Löschen der Mails mit discard:
if header :contains "subject" "viagra" { discard; }
Ein tatsächliches Zurückweisen hätte zur Folge, dass der Spammer durch die Rückmeldung die Echtheit der Adresse bestätigt bekommt.
Damit reject keine Fehlermeldung produziert, muss in der Datei /etc/postfix/master.cf folgende Zeilen wie folgt geändert werden [1]:
#flags=R user=cyrus argv=/usr/sbin/cyrdeliver -e -m ${extension} ${user} #folgende zeile ersetzt obere zeile, um reject funktion zu ermöglichen flags= user=cyrus argv=/usr/sbin/cyrdeliver -r ${sender} -m ${extension} ${user}
Abwesenheitsnachrichten
Bei Abwesenheit (z. B. Urlaub), wenn man keine Mails beantworten kann, verschickt sieve automatisch eine Standardantwort.
- Ein bestimmter Absender erhält nur eine einzige Abwesenheitsbenachrichtigung, auch wenn er mehrere E-Mails schickt.
- Eine weitere Benachrichtigung erhält er erst wieder nach sieben Tagen.
- Will man diesen Wert ändern, so dass bis zur nächsten Benachrichtigung z. B. 14 Tage gewartet wird, so benutzt man dafür die Option :days <Anzahl Tage>, die vor der Option :addresses eingefügt wird.
Die Abwesenheitsfunktion erfordert im Dateikopf das Modul vacation:
# Abwesenheitsnachrichten vacation :days <Anzahl Tage> :addresses ["Adresse1", "Adresse2"] "Text";
Aktivierung von Sieve
Die Datei muss noch entsprechend aktiviert werden.
- Nach Aufruf von sieveshell im Terminal [2]
sieveshell -u BENUTZERNAME localhost
wird die Eingabe des IMAP-Kennworts des Nutzers verlangt.
- Danach kann man die Konfigurationsdatei hochladen:
put .sieve-mail-filter activate .sieve-mail-filter quit
Bei fehlerhafter Syntax erhält man eine Fehlermeldung mit einer Zeilenangabe, so dass sich die Fehlersuche einfach gestaltet.
- help listet die verfügbaren Kommandos und Erläuterungen zu sieveshell.
- Hinweis
Sollte die nachfolgende Fehlermeldung auftauchen:
unable to connect to server at /usr/bin/sieveshell line 179, <STDIN> line 1\\
und damit die Verbindung zur sieveshell scheitern, hilft folgendes:
adduser cyrus mail #(soweit noch nicht beim Einrichten von cyrus erfolgt) chown root:mail -R /var/spool/sieve chmod 770 -R /var/spool/sieve
Für jeden Nutzer muss das entsprechende benutzerspezifische Regelwerk aktiviert werden. Grafische Helfer zum Konfigurieren der Sieve-Skripte
Zumindest, wenn man pysieved verwendet - welcher als Daemon läuft - hat man den Vorteil, dass man clientseitig konfigurieren kann, ohne SSH-Zugriff oder dergleichen auf den Server haben zu müssen.
- Folgende E-Mail-Clients können zum konfigurieren genutzt werden (kein Anspruch auf Vollständigkeit):
Thunderbird
Unter Thunderbird ist das Sieve-Skript mit dem Sieve Plugin möglich (alternativ auch auf der Mozilla-Thunderbird-Plugin-Seite).
kMail
Ebenso kann es mit kMail verwendet werden
Squirrelmail (Webmailer)
Wenn man als Webmailer Archiv/Squirrelmail verwendet, gibt es auch ein sehr gutes Plugin namens AvelSieve, bei dem man wahlweise textbasiert, umgangssprachlich oder grafisch seine Sieve-Filter konfigurieren kann.
Roundcube
Beispielskript
# Beispielskript
#
require ["fileinto", "reject"];
# Nachrichten größer 100K werden abgewiesen mit einer Fehlermeldung
#
if size :over 100K {
reject "Bitte senden Sie mir das nächste Mal eine kleinere Mail.
* Bei großen Anhängen laden Sie bitte die Dateien auf einen Server und schicken Sie mir eine URL.
* Danke.";
}
# Eine Mailingliste soll in einen Ordner "mailinglist" verschoben werden
#
elsif address :is ["From", "To"] "mailinglist@example.com" {
fileinto "INBOX.mailinglist";
# Bei einigen Mailserver-Konfigurationen muss statt eines Punktes hierbei ein Schrägstrich verwendet werden.
}
# Spamregel: Nachricht enthält meine Adresse nicht im To, CC oder Bcc
# header, oder Subject ist irgendwas mit "money" beziehungsweise "Viagra".
#
elsif anyof (not address :all :contains ["To", "Cc", "Bcc"] "me@example.com",
header :matches "Subject" ["*money*","*Viagra*"]) {
fileinto "INBOX.spam";
}
# Alle anderen Mails behalten wir.
# Diese Regel wäre nicht nötig, da durch das "implicit keep"
# bereits abgedeckt.
else {
keep;
}
Aufruf
Anweisungen werden mit dem Semikolon abgeschlossen
Kommentare
Kommentare werden durch das Zeichen "#" eingeleitet.
- Diese Kommentare gelten immer bis zum Zeilenende.
- Mehrzeilige Kommentare werden wie in C mit dem String "/*" eingeleitet und mit dem String "*/" abgeschlossen.
Zahlen
Nur positive Ganzzahlen sind erlaubt.
- Optional gibt es die Möglichkeit, die Größe über Angaben wie "K" (KiB, 2^10), "M" (MiB, 2^20) und "G" (GiB, 2^30) anzugeben.
- Beispiel: 100K steht für eine Größe von 100 Kibibytes.
Strings
Strings (Zeichenketten) werden durch das Anführungszeichen " eingeleitet.
- Ein Backslash ("\") wird verwendet, um weitere Anführungszeichen oder Backslashes zu kennzeichnen, die noch zur aktuellen Zeichenkette gehören (sogenanntes "Escapen").
- String-Listen werden mit "[" eingeleitet und mit "]" abgeschlossen.
Kontrollstrukturen
Die wichtigste Anwendung beim Filtern von E-Mail besteht im Testen auf bestimmte Eigenschaften. Dazu gibt es auch in Sieve die wohlbekannten WENN-DANN-Möglichkeiten:
- if
- elsif
- else
Ein if leitet eine bedingte Anweisung ein.
- Nur wenn die zu testende Bedingung zutrifft, wird der nachfolgende Codeblock ausgeführt.
- Wenn nicht, dann können weitere Bedingungen mittels elsif abgefragt werden.
- Falls keine der Bedingungen aus den "if"- und "elsif"-Blöcken zutrifft, werden die Anweisungen des "else"-Blocks abgearbeitet, sofern er vorhanden ist.
Vergleiche von Zeichenketten
Es bestehen mehrere Möglichkeiten, einen String zu testen.
- Als Vergleichsoperatoren kommen hierbei zum Einsatz:
- contains
- prüft, ob eine bestimmte Zeichenkette in einem anderen String enthalten ist.
- is
- führt einen exakten Vergleich durch, d. h.
- die Inhalte der verglichenen Zeichenketten müssen exakt übereinstimmen.
- matches
- beinhaltet eine Möglichkeit, beim Vergleich Teile einer Zeichenkette ungeprüft zu belassen.
- Mit dem Symbol * können mehrere, mit dem Symbol ? genau ein Zeichen freigestellt werden.
- So wird beispielsweise G?n alle dreibuchstabigen Wörter mit einem großen G am Anfang und einem kleinen n am Ende finden, während G*n alle Wörter von Gin über Gasmann bis hin zu Gesundheitskartenevaluierungskommission und darüber hinaus adressieren wird.
Adressen-Matching
- E-Mail-Adressen prüft man mit dem Keyword address
- Natürlich ist es möglich, die Absender- oder die Empfängeradresse zu prüfen.
- Dabei wird generell nur auf die eigentliche Adresse verglichen, also alles was zwischen den spitzen Klammern geschrieben steht.
- Um den kompletten String zu vergleichen, sollte man auf Name "<" Adresse ">" prüfen.
- Die Anführungszeichen kennzeichnen hierbei Strings.
- Um Adressen auf den Teil vor dem @ oder nach dem @ zu prüfen, können die optionalen Argumente :localpart beziehungsweise :domain genutzt werden.
- Standardmäßig wird die komplette Adresse geprüft (entspricht :all).
Größenvergleiche
Die Größe einer Mail prüft man mit dem Keyword size.
- Vergleiche mit Zahlen kann man mit den Operatoren :over beziehungsweise :under durchführen.
Header-Felder
E-Mail Header können mit dem Keyword header geprüft werden.
- Header-Felder können ganz normal mit den oben beschriebenen Zeichenketten-Vergleichen durchsucht werden.
- Es ist darauf zu achten, dass der Doppelpunkt nicht verwendet wird.
Blöcke
Blockanweisungen werden durch { eingeleitet und mit } beendet.
- Blöcke werden genutzt, um nach einem Test mehrere Anweisungen durchzuführen.
Anweisungen
Option | Beschreibung |
---|---|
stop | Beendet die Ausführung. Falls keine Regel zugetroffen hat, wird die Nachricht in der INBOX belassen (Impliziertes keep) |
keep | Speichert die Nachricht in der INBOX |
redirect | Weiterleiten einer Nachricht. Als Argument wird eine E-Mail-Adresse angegeben. |
discard | Löscht die Nachricht. Der Absender erhält davon keine Nachricht. |
reject | Diese Anweisung sorgt dafür, dass die Nachricht abgelehnt wird.
|
fileinto | Die Nachricht kann in einen bestimmten Ordner verschoben werden.
|
Erweiterungen
Sieve gestattet auch zusätzliche Erweiterungen, die am Anfang des Skriptes mit dem Schlüsselwort require deklariert werden müssen.
Anhang
Siehe auch
Dokumentation
Links
Projekt
Weblinks
- https://github.com/thsmi/sieve/
- https://wiki.ubuntuusers.de/Archiv/sieve/
- offizielle Website
- c't-Special Linux Mailserver mit Spamfilter
- RFC 3028 Sieve: A Mail Filtering Language
- kommentierte Beispiele
- RFC 5228
- https://de.wikipedia.org/wiki/Sieve