E-Mail Content Policies mit amavis steuern

In der Open Source Welt ist amavis der defacto Standard um Content Policies bei der Verarbeitung von E-Mail umzusetzen. Egal ob eine Nachricht ein Virus, Spam, unerwünschte Dateien oder fehlerhafte Header enthält oder - für Postmaster meist überraschend - frei von Makel ist, amavis stellt eine Vielzahl von Optionen zur Verfügung, um gewünschte und gesetzlich notwendige Aktionen in Form einer Content Policy präzise zu steuern.

Kenner schätzen das Perl-Programm, weil es nicht nur mächtig, sondern auch zuverlässig, schnell und wenn alle Stricke reissen sogar über Custom-Klasse erweiterbar ist.

Weniger geschätzt wird amavis Dokumentation. Die Integration in den SMTP-Server der Wahl ist weitestgehend behandelt, aber es mangelt an klärenden Worten über die zugrundeliegenden Konzepte des Filters und vor allem daran wie Content Policies individualisiert werden können.

Bemerkung

Böse Zungen behaupten sogar, die einzig brauchbare Methode sich amavis zu nähern sei die aktuell 12240 Zeilen der RELEASE_NOTES von unten nach oben zu lesen. So lerne der ausdauernde Leser zumindest welche Parameter es mal gab und wodurch sie abgelöst wurden.

Selbst dann wenn alle Parameter bekannt sind, betreiben Viele amavis immer noch mit nur einer Content Policy, die alle Sender und Empfänger über einen Kamm schert. Dabei ist gerade die Individualisierung eine der Stärken des Content Filter Frameworks; sie ermöglicht auf die individuellen Bedürfnisse und Notwendigkeiten im Unternehmensalltag einzugehen.

In mehreren Posts möchte ich die Grundlagen der Individualisierung in amavis behandeln. Im diesem, ersten Teil werden Voraussetzungen für Individualisierung erarbeitet und dann auf die Möglichkeiten für lokale (lies: interne) Sender eingegangen. Der zweite Teil befaßt sich mit der umgekehrten Senderichtung und der Frage was amavis für fremde (lies: externe) Sender und interne Empfänger tun kann. Integration in den SMTP-Server wird an dieser Stelle vorausgesetzt. Wer noch nicht am Start ist, findet zumindest für Postfix offizielle amavis Dokumentation.

Grundlagen der Individualisierung

Was ist eigentlich das Problem, das es zu lösen gilt? Es beginnt früh und wirkt sich in Folge weit aus. amavis ist ein E-Mail Content Filter. Es wird über SMTP, LMTP oder ein Milter-Interface in die Mailverarbeitung eingebunden und - hier kommt das Problem - es hat ohne entsprechende Konfiguration keine Ahnung welche der vorbeifliegenden Mails eingehend oder ausgehend sind und ob der Sender der Nachricht dem Mailsystem in irgendeiner Weise zugehörig ist oder ob es sich um einen beliebigen fremden Sender handelt.

Dabei ist gerade das Wissen über Senderichtung und Legitimation grundlegend für das weitere Verhalten von amavis. Weiß amavis nicht, welche Mails ein- und ausgehend sind, wird es bei Bedarf keine Benachrichtigungen über den Status einer Nachricht senden. Ein Empfänger, für den eine an ihn gerichtete Nachricht in Quarantäne genommen wurde, erfährt nicht vom Eingriff in den Mailtransport. Ebenso wird keine Scan-Ergebnisse in Header:-Zeilen vermerken und ohne legitimierte Sender keine Disclaimer und schon gar nicht DKIM-Signaturen für ausgehende Nachrichten anbringen.

Senderichtungen!

Prinzipiell gibt es vier Senderichtungen: extern nach intern, intern nach extern, intern nach intern und extern nach extern. Letztere will kein Postmaster in den Logs finden, denn handelt es sich wirklich um extern nach extern, bedeutet dies, dass der SMTP-Server ein offenes Relay ist - Fremde dürfen an Fremde senden.

   +                                   ^
   |                                   |
   |                |                  |
   |                |                  |
e  |                |                  | a
i  |    extern      |   extern         | u
n  |                |                  | s
g  |                |                  | g
e  |   -------------|-------------     | e
h  |                |                  | h
e  |                |                  | e
n  |                |                  | n
d  |    intern      |   intern         | d
   |                |                  |
   |                |                  |
   |                                   |
   v                                   +

Wer nun in den Logs stöbert und dort auf amavis-Vermerke stößt, die den Wortlaut Open relay? Nonlocal recips but not originating tragen muss nicht gleich in operative Hektik verfallen und ausziehen um sein System vor weiterem Mißbrauch zu retten. Es kann gut sein, dass amavis einfach noch nicht weiß was intern und damit „originating“ ist und deshalb - auf Basis fehlender Konfiguration - zu irreführenden Schlüssen gelangt.

Basiskonfiguration

Die einfachste Methode, um amavis zu sagen wer denn hier nun legitimiert sendet und welcher Empfänger zum Mailsystem gehört, besteht darin die Parameter @mynetworks und @local_domains_maps entsprechend der eigenen Netztopologie zu setzen.

@mynetworks

@mynetworks legt interne Sender fest. Das Array definiert eine Liste von IPv4- und IPv6-Adressen bzw. Netzwerkbereichen, die amavis als "dem System zugehörig" betrachten soll.

Sendet ein Client von einer in @mynetworks vermerkten IP-Adresse weiß amavis, es handelt sich um einen internen Sender. Das funktioniert einwandfrei für statische IP-Adressen ist aber nicht für mobile Sender geeignet denn die haben stetig wechselnde IP-Adressen. Wie amavis dieses Aufgabe löst, findet sich an späterer Stelle.

@local_domains_maps

@local_domains_maps legt systemzugehörige Empfängerdomains fest. Geht einen Nachricht an einen oder mehrere Empfänger deren Domains in @local_domains_maps definiert sind, weiß amavis die Senderichtung ist für sie intern.

@local_domains_maps = (
    ".$mydomain",
    read_hash('/etc/postfix/virtual_domains')
);

Aus dem Zusammenspiel von @mynetworks und @local_domains_maps kann amavis nun schon viel Nützliches herauslesen. Wird eine Mail beispielsweise aus @mynetworks gesendet und hat das Ziel @local_domains_maps hat sie die Senderichtung intern nach intern. Ist das Ziel nicht in @local_domains_maps geht sie an externe Empfänger.

Es geht!

Damit funktionieren schlagartig viele Dinge, die manch Postmaster zu debuggen schon lange aufgegeben hatte. Ganz oben auf der Liste rangiert ein für Endanwender eher unbedeutendes Detail. amavis soll die SpamAssassin-Analyseergebnisse in den Headern verewigen, damit in der Mail steht welche Filter wie gegriffen haben und der Postmaster bei Bedarf schnell herausfinden kann was zur Zustellung beziehungsweise Unterbindung geführt hat.

Ahnungslose Admins aktivieren einfach die Option $sa_spam_report_header in dem Glauben, dass damit bereits alles erledigt ist. Derart tiefe Einblicke in sein Innenleben gewährt amavis allerdings nur internen Empfängern. Sobald @local_domains_maps korrekt gesetzt ist, funktioniert dieses Feature wie gewünscht.

DKIM-Signaturen

Ähnliches gilt für DKIM-Signaturen, die nicht angebracht werden, obwohl die DKIM-Konfiguration doch mehrfach erfolreiche mit dem Kommando amavisd-new testkeys <DOMAIN> getestet wurde. DKIM-Signaturen werden eben nur für legitime Sender angebracht. Brächte der Server Signaturen für nicht-legitimierte Sender an, nur weil sie zu einer DKIM-Senderdomain gehören, könnte er leicht Opfer eines Adressmißbrauchs werden.

Da wäre der gute Ruf des Servers schnell ruiniert und reputationsbasierte Anti-Spam-Systeme würden ihm bald die Tür weisen - die deliverability rate sänke signifikant. Deshalb signiert amavis Nachrichten nur, wenn die Absenderdomain DKIM-signiert werden soll und der Client des Senders anhand eines belastbaren Kriteriums eindeutig identifiziert werden konnte. Ist er in @mynetworks gelistet, ist ein hinreichend belastbares Kriterium gegeben und amavis schreitet erwartungsgemäß zur Tat.

policy banks

Was aber können Sender zu ihrer Legitimation vorbringen wenn ihre Clients keine statische IP-Adresse besitzen? Eine gesonderte Vertrauensstellung über @mynetworks ist in diesem Fall nicht möglich. Für diesen und auch für andere Fälle stellt amavis das Konzept der $policy_banks zur Verfügung.

$policy_banks
$policy_banks schaffen einen Namensraum in dem andere, eigene Filter-Regeln gelten können. Hier kann der Administrator neue Optionen setzen und globale, bereits bestehende Regeln überschreiben. Eine Policy Bank hört auf einen eigenen Namen und kann auf verschiedene Arten angesprochen werden.

Interface Policies

Bei ihre Einführung stellte Mark Martinec, der Mann hinter amavis, zuerst eine Methode zur Ansprache über TCP-Ports vor. Die sogenannten Interface Policies funktionieren indem amavis zusätzlich zu seinem Standard-TCP-Port 10024, ein oder mehrere weitere Ports zugewiesen werden. Per Konfigurationsanweisung wird der zusätzliche Port einer $policy_bank zugeordnet. Jeder Client, der amavis fortan über den dedizierten Port anspricht, landet in der zugeordneten $policy_bank in der eigene, spezielle Regeln und Ausnahmen gelten.

Beispiel: Mobile Clients

Mobile Clients lassen sich leicht und verläßlich identifizieren, wenn sie gezwungen werden ihre E-Mails über den submission-Port 587 einzuliefern. Postfix Postmaster werden sich mittlerweile mit diesem speziellen SMTP-Port beschäftigt haben, denn der in Version 2.8 veröffentlichte postscreen-Daemon, läßt kein gutes Haar an Clients, die sich nicht RFC-konform verhalten oder jene die geblacklistet sind.

Bemerkung

Gerade Letzteres trifft bei mobilen Clients häufig zu. Die Reputation der IP, über die man sendet, kann man sich bei Dial-In Netzwerken eben nicht aussuchen…

Deshalb sind die, die postscreen auf Port 25 nutzen, förmlich gezwungen für Clients mit dynamischer IP auf Port 587 auszuweichen. Das besondere am submission-Port ist die RFC 4409 Anforderung, Clients vor dem Senden zwingend mit SMTP-Authentifizierung zu identifizieren, denn der SMTP-Server agiert an dieser Stelle als MSA und hat die Aufgabe sicherzustellen, dass wirklich nur berechtigte Sender Nachrichten in den Umlauf bringen. Angenehmer Nebeneffekt dieser Prüfung ist, erfolgreich authentifizierte Clients haben sich wie solche mit statische IP durch ein belastbares Kriterium als lokale Sender legitimiert und können für die Zeit ihres Aufenthalts im Mailsystem eine besondere Vertrauensstellung geniessen.

Dieses besondere Vertrauen kann der SMTP-Server weitergeben, indem er Mails an amavis auf einem speziellen Port übergibt. Dort gilt eine spezielle Policy für interne Sender, die alle Nachrichten als ORIGINATING markiert und somit dieselben Verhältnisse schafft, wie sie für Clients aus @mynetworks gelten.

$interface_policy{'10026'} = 'MYSUBMITTERS';

$policy_bank{'MYSUBMITTERS'} = {
    originating              => 1,
    final_spam_destiny       => D_BOUNCE,
    final_virus_destiny      => D_REJECT,
    final_banned_destiny     => D_PASS,
    final_bad_header_destiny => D_PASS,
    banned_filename_maps     => ['MYNETS-DEFAULT'],
    warnbadhsender           => 1
};

Sendern aus @mynetworks weist amavis im übrigen von selbst eine $policy_bank mit dem Namen MYNETS zu. Die läßt sich für die eigenen Sender um einige Servicemerkmale erweitern, die von fremden Sendern nicht gerne gesehen werden. So können beispielsweise Besitzer von Clients, die Nachrichten mit fehlenden oder fehlerhaften Headern senden, über diesen Missstand benachrichtigt werden und ihn abstellen.

Zusatzservice für lokale Sender

In einer spamhysterischen Welt - in der zunehmend zuerst geschossen und dann gefragt wird - trägt diese Header-Überprüfung angenehm qualitätssichernd zur deliverability und somit zum Seelenheil des Postmasters bei. Richtig angekündigt nehmen interne Sender diese Maßnahme erfahrungsgemäß als Service in ihrem Sinne und nicht als Gängelung durch RFC-besessene Postmaster wahr.

IP-Address Policies

Wer auf Clients mit statischer IP unterschiedliche Policies anwenden möchte, kann bereits seit amavisd-new-2.6.3 auf @client_ipaddr_policy zurückgreifen. Einzelne Adressen, ganze Netzbereiche egal ob IPv4 oder IPv6 können mit @client_ipaddr_policy auf $policy_banks verteilt werden.

@client_ipaddr_policy = (
  [qw( 0.0.0.0/8 127.0.0.1/8 [::] [::1] )] => 'LOCALHOST',
  [qw( !172.16.1.0/24 172.16.0.0/12 192.168.0.0/16 )] => 'PRIVATENETS',
  [qw( 192.0.2.0/25 192.0.2.129 192.0.2.130 )] => 'PARTNER',
  [qw( 141.42.206.35/32 )] => 'CUSTOMERS',
  \@mynetworks => 'MYNETS',
);

Beispiel: DMZ

Von der Aufteilung profitieren selbst kleine Netze, weil sie so unterschiedliche Policies für exponierte Dienste wie den Webserver (strikt) und geschützte Bereiche wie das LAN (tendenziell permissiv) oder gar unterschiedliche Nutzergruppen etablieren können. Über die @banned_filename_maps und Verweise auf %banned_rules ist es beispielweise möglich Sets verschiedener Dateitypen zu definieren, die Sender einer Gruppe in Umlauf bringen dürfen.

%banned_rules = (
  'NO-MS-EXEC'=> new_RE( qr'^\.(exe-ms)$' ),
  'PASSALL'   => new_RE( [qr'^' => 0] ),
  'ALLOW_EXE' => new_RE( qr'.\.(vbs|pif|scr|bat)$'i, [qr'^\.exe$' => 0] ),
  'ALLOW_VBS' => new_RE( [qr'.\.vbs$' => 0] ),
  'NO-VIDEO'  => new_RE( qr'^\.movie$', qr'.\.(asf|asx|mpg|mpe|mpeg|avi|mp3|wav|wma|wmf|wmv|mov|vob)$'i, ),
  'NO-MOVIES' => new_RE( qr'^\.movie$', qr'.\.(mpg|avi|mov)$'i, ),
  'MYNETS-DEFAULT' => new_RE( [ qr'^\.(rpm|cpio|tar)$' => 0 ], qr'.\.(vbs|pif|scr)$'i, ),
  'DEFAULT' => $banned_filename_re,
);

Den Software-Entwicklern wird so gestattet EXE-Dateien zu verteilen, während die Spaßfraktion der Witz-Programmversender leider aussen vor bleiben muss. Das gilt für große Netze selbstverständlich ebenso. Hier können die Postmaster mit @client_ipaddr_policy schnell und flexibel auf die unterschiedlichen Anforderungen der Kunden reagieren oder Produktgestaltung betreiben, indem sie bezahlbare Dienstleistungen nur bei Buchung in die $policy_bank aufnehmen.

Virus-basierte Policies

Apropos große Netze! Große Netze sehen sich in der Regel stärker Viren ausgesetzt. Oft genug sind sie sogar gezielt Opfer einer Virenattacke. Wer jedes Virus in Quarantäne wegschreibt und notifiziert kann da schnell in Nöte geraten. Da ist es hilfreich mit amavis in solchen Situationen derartige Störenfriede von Standardmaßnahmen auszunehmen und sie gezielt der rückstandslosen Entsorgung zuzuführen.

Über @virus_name_to_policy_bank_maps werden sie anhand ihres Virusnamens identifiziert und einer geeigneten $policy_bank zugeführt, die D_DISCARD als Ziel angibt und Quarantäne sowie Empfängerbenachrichtigung aufhebt. Zeigt der über amavisd-snmp-subagent generierte Graph ein Abklingen der Attacke an, kann das Virusnamenpattern aus @virus_name_to_policy_bank_maps entfernt werden und der Content Filter nimmt nach einem reload wieder Normalbetrieb auf.

Details zur Konfiguration dieser Funktionalität finden sich - alles andere würde zu Irritiationen bei langjährigen amavis-Nutzern führen - in den RELEASE_NOTES zu amavisd-new-2.7.0. Bleibt noch zu sagen, das amavis das Konzept der $policy_banks auch für eigene Zwecke einsetzt. Das Kommandozeilen-Tool amavisd-release kommuniziert mit dem amavis Server über einen dedizierten Port im eigenen Policy Delegation Protcol und weist den Server so zum Beispiel an in Quarantäne befindliche Nachrichten freizusetzen.

Mit den $policy_banks und unterschiedlichen Methoden diese anzusprechen hat Mark Martinec ein mächtiges Konzept bereitgestellt, um das Content Filter Framework amavis flexibel an die Bedürfnisse seiner Nutzer anzupassen.

In diesem Post lag der Schwerpunkt auf dem Konzept selbst und den Maßnahmen, die für lokale Sender ergriffen werden können. amavis kann auch von extern eingehende Nachrichten eigenen Policies zurouten. Welche Möglichkeiten Postmaster damit an der Hand haben, wird im nächsten Post Gegenstand sein.


Kommentare

  1. Jörg

    Jörg (1 Jahr, 7 Monate) # Reply

    $sa_spam_report_header -> obsolet
    --
    # %allowed_added_header_fields = ...; # built-in default

    Auszug aus den Release Notes:
    - retired a setting $sa_spam_report_header, it was obsoleted in
    amavisd-new-2.4.3 with the introduction of %allowed_added_header_fields.
    To enable insertion of X-Spam-Report header field, please use instead:
    $allowed_added_header_fields{lc('X-Spam-Report')} = 1;
    The variable is still declared for compatibility with old config files,
    but its value is ignored. An attempt to set its value to a non-default
    value produces a warning.

    Grüsse
    Jörg

  2. Jan

    Jan (8 Monate, 4 Wochen) # Reply

    amavis kann auch von extern eingehende Nachrichten eigenen Policies zurouten. Welche Möglichkeiten Postmaster damit an der Hand haben, wird im nächsten Post Gegenstand sein.

    Kommt das noch irgendwann? Ich fange gerade damit an, unsere Mailstruktur neu aufzusetzen, da könnte ich das gut gebrauchen.

Leave a comment.
Your Comment

×