Kapitel 1. Postfix und amavisd-new Howto

Inhaltsverzeichnis

1.1. Voraussetzungen
1.1.1. Welche Postfix-Version wird benötigt?
1.1.2. Fehler während der Integration abfangen
1.2. Postfix und amavisd-new Basiskonfiguration
1.2.1. amavisd-new für Postfix konfigurieren
1.2.2. Transport von Postfix zu amavisd-new einrichten
1.2.3. Dedizierten Postfix SMTP-Server für rückkehrende Nachrichten einrichten
1.2.4. Neue Funktionalitäten testen
1.3. Filter-Beispiele
1.3.1. E-Mails global filtern
1.3.2. E-Mails service-bezogen global filtern
1.3.3. E-Mails pro Empfänger-Domain filtern
1.3.4. E-Mails pro Sender-Domain filtern
1.3.5. E-Mails auf Content-Basis filtern
1.4. Erweiterte Postfix und amavisd-new Konfiguration
1.4.1. Architektur mit mehreren cleanup-Daemonen
1.4.2. Zwei cleanup-Daemonen konfigurieren
1.5. Optimierung
1.5.1. Anzahl maximaler Content Filter Prozesse
1.5.2. Weitere Optimierungs-Tipps

Zusammenfassung

Dieses Dokument beschreibt die Integration von amavisd-new in den Postfix SMTP-Zustellprozess. Es zeigt die notwendigen Voraussetzungen auf, erklärt wie Postfix und amavisd grundsätzlich füreinander konfiguriert werden müssen und liefert Beispiele für unterschiedliche Filter-Szenarien.

1.1. Voraussetzungen

Folgende Voraussetzungen müssen vor Beginn der Integration gegeben sein:

  1. amavisd-new ist bereits installiert und seine Lauffähigkeit wurde getestet.

  2. Postfix ist bereits installiert, für den Basisbetrieb konfiguriert und wurde in dieser Konfiguration erfolgreich getestet.

[Tipp]Tipp

Unabhängig von den hier beschriebenen Konfigurationen, ist es grundsätzlich ratsam strict_rfc821_envelopes = yes in /etc/postfix/main.cf zu setzen. Dies sorgt dafür, dass Postfix E-Mails von Sender-Adressen, auf die nicht geantwortet werden kann, kategorisch ablehnt.

So wird verhindert, dass E-Mails mit fehlerhaften Sender-Adressen zuerst angenommen und dann ggf. nicht zurückgesendet werden können und so letztlich gelöscht werden, obwohl Postfix dem sendenden Client eine erfolgreiche Zustellung signalisiert hatte.

1.1.1. Welche Postfix-Version wird benötigt?

Die Integration von amavisd-new in den Postfix Zustellprozess setzt voraus, dass Postfix externe Content Filter einbinden kann. Die früheste Postfix-Version, die den content_filter-Parameter unterstützt, ist Postfix release-20010228.

1.1.2. Fehler während der Integration abfangen

Treten während der Integration von amavisd-new Fehler in der Konfiguration von Postfix auf, kann es schnell passieren, dass Postfix diese Fehler als endgültig klassifiziert. Postfix bricht die Zustellung ab, sendet eine Fehlermeldung an den Absender (bounce) und eine weitere, nach Korrektur des Fehlers, möglicherweise erfolgreiche Zustellung wird nicht stattfinden.

Die Aktivierung des soft_bounce-Parameters verhindert, dass E-Mails bei Zustellungsfehlern sofort gebounced werden. Der Parameter kann mit einem Editor in /etc/postfix/main.cf eingetragen werden oder mit Hilfe des postconf-Kommandos. Anschließend wird die neu Konfiguration mit postfix reload aktiviert:

# /usr/sbin/postconf -e "soft_bounce = yes"
# postfix reload

Postfix wird jetzt alle Fehler als temporäre Fehler behandeln und im Fehlerfall die E-Mails in seiner Mailqueue behalten, damit weitere Zustellversuche nach Korrektur evtueller Fehler vorgenommen werden können.

[Wichtig]Wichtig

Nach der Integration von amavisd-new muss soft_bounce wieder deaktiviert werden, sonst wird Postfix keine Zustellfehler an die Absender von E-Mails melden!

1.2. Postfix und amavisd-new Basiskonfiguration

Postfix kann amavisd-new zu überprüfende E-Mails auf verschiedene Arten (vor der Annnahme einer E-Mail oder erst danach) und auf Basis verschiedener Kriterien (global, selektiv, per Interface, etc.) übergeben. Die Methoden, also der Transport der E-Mail zu amavisd-new hin und der Weg zurück in das Postfix Mailsystem, sind jedoch immer gleich.

In diesem Abschnitt wird deshalb zuerst beschrieben, wie Postfix und amavisd-new konfiguriert werden müssen, damit Hin- und Rückweg der E-Mails gewährleistet sind. Die verschiedenen Arten und auslösenden Kriterien für die Übergabe einer E-Mail werden im anschließenden Abschnitt erläutert.

[Anmerkung]Vorgehensweise bei der Integration

Oft genug wird amavisd-new erst nachträglich in ein bereits in Betrieb befindliches System eingebunden. Die Abfolge der folgenden Integrationsschritte ist deshalb darauf abgestimmt, ein in Betrieb befindliches System möglichst wenig zu unterbrechen.

Funktionstests können bei laufendem Betrieb im Hintergrund durchgeführt werden und stellen im Regelfall sicher, dass die aktivierte amavisd-new Integration sofort fehlerfrei funktioniert.

1.2.1. amavisd-new für Postfix konfigurieren

Die Postfix-spezifische Anpassung einer amavisd-new-Konfiguration beantwortet die folgenden zwei Fragestellungen:

  1. Auf welchem Port soll der amavisd-new-Daemon eingehende Verbindungen von Postfix erwarten?

  2. An welche IP-Adresse und welchen Port soll der amavisd-new interne SMTP-Client E-Mails (und ggf. Benachrichtigungen) zur Rückführung in das Postfix-Mailsystem senden?

1.2.1.1. amavisd-new-Daemon für eingehende Nachrichten konfigurieren

Der $inet_socket_port-Parameter in /etc/amavisd.conf legt fest, auf welchem Port amavisd-new (E)SMTP- und/oder LMTP-Verbindungen entgegennimmt. Das folgende Beispiel gibt explizit Port 10024 (Standard-Einstellung) in /etc/amavisd.conf an:

$inet_socket_port = 10024;

Damit ist der Port für eingehende Nachrichten in amavisd-new festgelegt und IP-Adresse und Port für den Postfix Rückführungs-Dienst können konfiguriert werden.

1.2.1.2. amavisd-new-Daemon für Postfix Rückführungs-Dienst konfigurieren

Zwei Parameter, $forward_method und $notify_method, werden (in der Regel identisch) für eine Rückführung von E-Mails in das Postfix-Mailsystem konfiguriert.

Der erste, $forward_method-Parameter gibt an, wohin der amavisd-new SMTP-Client überprüfte E-Mails senden soll, während der zweite, $notify_method-Parameter festlegt, wohin der amavisd-new SMTP-Client Benachrichtigungen (zu überprüften E-Mails) senden soll.

In seiner Standard-Einstellung gibt amavisd-new geprüfte E-Mails oder Benachrichtigungen an die IP-Adresse 127.0.0.1 auf Port 10025 weiter und eine Konfiguration dieser Einstellungen in /etc/amavisd.conf ist nicht notwendig wenn amavisd-new und Postfix auf demselben Server betrieben werden.

Für den Fall, dass der Postfix Rückführungs-Dienst aber auf einer anderen IP-Adresse oder einem anderen Port betrieben wird, kann dies dem amavisd-new-Daemon wie folgt in /etc/amavisd.conf mitgeteilt werden:

$notify_method  = 'smtp:[192.0.2.1]:20025';
$forward_method = 'smtp:[192.0.2.1]:20025';

1.2.2. Transport von Postfix zu amavisd-new einrichten

Als erstes gilt es, einen dedizierten Transport einer E-Mail von Postfix zum amavisd-new-Daemon hin einzurichten. Der amavisd-Server ist in der Lage, Postfix sowohl eine SMTP- als auch eine LMTP-Session zur Übermittlung von E-Mail anzubieten.

Postfix kann, entweder mit dem smtp-Client oder dem lmtp-Client, beide Arten der Übermittlung nutzen. Dieser Abschnitt beschreibt die notwendigen Konfigurationsschritte für beide Arten.

[Anmerkung]Anmerkung

Postfix benötigt für den Transport zu amavisd-new entweder einen dedizierten smtp-Service oder einen dedizierten lmtp-Service. Aufgrund der erweiterten Fähigkeiten des LMTP-Protokolls - es kann bei einer Mail an mehrere Empfänger, einen Empfänger getrennt von allen anderen Empfängern über einen Fehler bei der Zustellung unterrichten - ist der Einsatz des lmtp-Clients vorzuziehen.

Warum überhaupt einen dedizierten Client einrichten?

Grundsätzlich wäre es möglich einen, der in /etc/postfix/master.cf bereits vorkonfigurierten, lmtp-, smtp- oder relay-Services für den Transport von E-Mails von Postfix zu amavisd-new hin zu nutzen.

Für den Einsatz eines solchen Clients mit amavisd-new müssen jedoch einige, besondere Konfigurationseinstellungen vorgenommen werden, die für diese global genutzten Clients von Nachteil hinsichtlich Performance und Skalierbarkeit wären.

[Anmerkung]Anmerkung

Es ist z.B. notwendig, die Anzahl der maximalen, gleichzeitig betriebenden Prozesse des dedizierten Clients auf die maximale Anzahl gestarteter amavisd-new-Daemon Kind-Prozesse abzustimmen.

Wäre die Anzahl der Postfix Client-Prozesse höher als die der amavisd-new-Daemon Kind-Prozesse, würde es unter Last zu einer Abweisung des Postfix-Clients kommen, weil der amavisd-new-Daemon keine weiteren Verbindungen mehr annehmen kann und Postfix würde dies als (temporären) Fehler bei der Zustellung werten und die Absender der verzögerten Nachricht unnötigerweise davon in Kenntnis setzen.

1.2.2.1. Dedizierten lmtp-Client einrichten

Das folgende Listing fügt einen dedizierten lmtp-Client mit dem Namen amavisfeed in /etc/postfix/master.cf hinzu. Eine Erläuterung der Konfiguration folgt im Anschluss:

# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================

...

amavisfeed unix  -       -       n       -       2       lmtp
    -o lmtp_data_done_timeout=1200
    -o lmtp_send_xforward_command=yes
    -o disable_dns_lookups=yes
[Wichtig]Wichtig

Service-spezifische Optionen werden in master.cf zeilenweise und eingerückt (leading whitespace) angegeben. Parameter und Werte müssen ohne Leerzeichen mit einem Ist-Gleich-Zeichen „=“ verbunden werden. Mehr dazu in master(5) oder master.cf selbst.

Hier ist eine Erläuterung der, vom Standard abweichenden Einstellungen:

maxproc

Die maximale Anzahl gleichzeitiger Postfix-amavisfeed-Service-Prozesse ist auf 2 (Standard: default_process_limit = 100) eingeschränkt. Dies ein guter Anfangswert, für eine Basiskonfiguration. Der Wert kann später angehoben werden, wenn das Gesamtsystem die damit steigende Last verarbeiten kann.

lmtp_data_done_timeout

Während der Überprüfung hält amavisd-new grundsätzlich die Verbindung zum Postfix amavisfeed-Service offen. amavisd-new beendet die Verbindung erst, wenn die E-Mail oder eine durch die Untersuchung ausgelöste Benachrichtigung, über den Rücktransport erfolgreich im Postfix System angelangt sind.

Es könnte sein, dass amavisd-new sehr lange benötigt, um eine E-Mail zu überprüfen. Damit der Postfix amavisfeed-Service während dieser Wartezeit nicht in einem timeout gerät, wird der timeout-Zeitraum verdoppelt (Standardwert: 600 [Sekunden]) und somit auf den Timeout-Wert von amavisd-new gesetzt.

lmtp_send_xforward_command

amavisd-new bzw. SpamAssassin können die IP-Adresse und den hostnamen des anliefernden Clients mit in die Beurteilung der Spamhaftigkeit einer E-Mail einbeziehen. Im Normalfall "sieht" amavisd-new nur die IP-Adresse und den Clientnamen des Postfix lmtp-Clients, wenn dieser sich mit amavisd-new verbindet.

Der aktivierte lmtp_send_xforward_command-Parameter instruiert Postfix den ursprünglichen Clientnamen und dessen IP-Adresse an amavisd-new über XFORWARD an amavisd-new weiterzugeben, sodass dieser den echten Hostnamen nutzen und loggen kann. Die Postfix man-Page lmtp(8) und das XFORWARD_README dokumentieren diese Erweiterung von Postfix.

disable_dns_lookups

Der Transportweg von Postfix zu amavisd-new, er wird später in Abschnitt 1.3, „Filter-Beispiele“ definiert, ist immer derselbe. Er wird sich - wahrscheinlich - nur bei einer Rekonfiguration des ganzen Systems ändern.

Weil der Transportweg sich nicht ändert, kann er (statisch) als IP-Adresse angegeben werden und muss nicht jedesmal „teuer“ über DNS-Abfragen aufgelöst werden. Dies spart drei DNS-Abfragen und somit Zeit und Ressourcen.

1.2.2.2. Dedizierten smtp-Client einrichten

Die Einrichtung eines dedizierten smtp-Clients ist nahezu identisch mit der Einrichtung eines dedizierten lmtp-Clients. Im Detail tragen die Parameternamen das Präfix smtp_ und nicht lmtp_ und das Kommando („command“) lautet smtp anstatt lmtp. Ansonsten gelten dieselben Gründe für die Parameter, wie sie im Absatz zuvor angeführt wurden.

Hier ist Beispielkonfiguration für einen dedizierten smtp-Client mit dem Service-Namen amavisfeed:

# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================

...

amavisfeed unix  -       -       n       -      2        smtp
    -o smtp_data_done_timeout=1200
    -o smtp_send_xforward_command=yes
    -o disable_dns_lookups=yes

1.2.3. Dedizierten Postfix SMTP-Server für rückkehrende Nachrichten einrichten

Der zweite Dienst, den es noch einzurichten gilt, schafft einen dedizierten SMTP-Server, dessen Aufgabe einzig und allein darin besteht, E-Mails, die von amavisd-new überprüft wurden, anzunehmen und in den Postfix Zustellprozess zurückzuführen.

Dazu wird eine weitere, dedizierte Instanz des Postfix smtpd-Daemon in master.cf hinzugefügt. Diese Instanz unterscheidet sich vor allem dadurch, dass sie den content_filter-Parameter ohne einen Wert setzt und damit bestehende Delegationen an externe Content Filter aufhebt.

[Wichtig]Wichtig

Die Delegation von E-Mails an amavisd-new wird über den content_filter-Parameter konfiguriert. Fehlt der leere content_filter-Parameter, wird die aus amavisd-new rückkehrende E-Mail sofort wieder an amavisd-new delegiert und die E-Mail befindet sich somit in einem Endlos-Kreislauf.

Das folgende Beispiel greift die Standard-Einstellungen der amavisd-new $forward_method- und $notify_method-Parameter auf und konfiguriert deshalb einen dedizierten smtpd-Daemon, der auf localhost (127.0.0.1) und Port 10025 eingehende Verbindungen entgegennimmt.

Dazu müssen folgende Angaben in master.cf hinzugefügt werden:

# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================

...

127.0.0.1:10025 inet n  -       n       -       -       smtpd
    -o content_filter=
    -o local_recipient_maps=
    -o relay_recipient_maps=
    -o smtpd_delay_reject=no
    -o smtpd_restriction_classes=
    -o smtpd_client_restrictions=
    -o smtpd_helo_restrictions=
    -o smtpd_sender_restrictions=
    -o smtpd_recipient_restrictions=permit_mynetworks,reject
    -o smtpd_data_restrictions=reject_unauth_pipelining
    -o smtpd_end_of_data_restrictions=
    -o mynetworks=127.0.0.0/8
    -o smtpd_error_sleep_time=0
    -o smtpd_soft_error_limit=1001
    -o smtpd_hard_error_limit=1000
    -o smtpd_client_connection_count_limit=0
    -o smtpd_client_connection_rate_limit=0
    -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks

Hier ist eine Erläuterung der, vom Standard smtpd-Daemon, abweichenden Einstellungen:

content_filter

Der leere content_filter hebt bestehende, globale content_filter-Delegationen auf.

..._maps

Die leeren ..._maps heben die Überprüfung auf gültige Empfänger auf - diese Überprüfungen haben bereits einmal zuvor stattgefunden, als Postfix die rückkehrende E-Mail zum erstem Mal angenommen hatte. Weil die E-Mail diese Überprüfung bereits bestanden hat, ist ein weiterer Test überflüssig und würde nur Ressourcen verschwenden.

..._restrictions_...

Restriktionen müssen ebenfalls nicht mehr angewendet werden. Auch diese Tests hatte die aus amavisd rückkehrende E-Mail bereits erfolgreich bestanden.

mynetworks_...

Der dedizierte smtpd-Daemon wird so konfiguriert, dass er nur von localhost Nachrichten annimmt.

restliche Optionen

Alle anderen angegebenen Optionen machen den smtpd-Daemon möglichst fehlertolerant und versuchen Ressourcen durch Vermeidung bereits durchgeführter Prüfungen zu vermeiden.

Nach der Konfiguration stellen das postfix-Kommando, zusammen mit der Option reload ausgeführt, und ein Blick in die Maillog-Datei sicher, dass Postfix keine syntaktischen Probleme der neuen Konfiguration bemängelt:

# postfix reload && tail -f /var/log/maillog

Meldet das Maillog keine Fehler, kann mit dem Test der neuen Funktionalitäten begonnen werden.

1.2.4. Neue Funktionalitäten testen

Der Test der neuen Funktionalitäten besteht aus drei Einzeltests, die den Zustellprozess sozusagen „von hinten aufrollen“ und dabei folgende Fragen beantworten:

  1. Ist amavisd-new wie konfiguriert erreichbar?

  2. Ist der dedizierte smtpd-Daemon erreichbar?

  3. Kann eine Test-E-Mail nach einer Überprüfung von amavisd-new an den dedizierten Postfix-smtpd-Daemon übergeben und in das Postfach des Empfängers zustellt werden?

1.2.4.1. amavisd-new-Daemon-Port für eingehende Nachrichten testen

Ein Test mit dem telnet-Kommando stellt fest, ob amavisd-new auf dem konfigurierten Port erreichbar ist. Ein erfolgreicher Verbindungsaufbau sieht in etwa so aus:

$ telnet localhost 10024
220 [127.0.0.1] ESMTP amavisd-new service ready
EHLO localhost
250-[127.0.0.1]
250-VRFY
250-PIPELINING
250-SIZE
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250 XFORWARD NAME ADDR PROTO HELO
QUIT
221 2.0.0 [127.0.0.1] amavisd-new closing transmission channel

Gelingt kein Verbindungsaufbau, sollten folgende Dinge überprüft werden:

  • Ist der amavisd-new-Daemon in Betrieb?

  • Protokolliert amavisd-new Fehler beim Start und beendet sich anschliessend?

  • Protokolliert amavisd-new Fehler beim Verbindungsaufbau und beendet sich anschliessend?

  • Stimmen konfigurierte IP-Adresse und Port mit den Testdaten überein?

  • Verhindert ggf. eine Firewall einen Verbindungsaufbau?

1.2.4.2. Dedizierten smtpd-Daemon testen

Mit der Aktivierung der neuen Konfiguration, sollte Postfix die separate Instanz des smtpd-Daemons (127.0.0.1:10025) eingebunden haben. Ein erfolgreicher Verbindungsaufbau mit dem telnet-Kommando sieht in etwa so aus:

$ telnet 127.0.0.1 10025
220 mail.example.com ESMTP Postfix
EHLO localhost
250-mail.example.com
250-PIPELINING
250-SIZE 40960000
250-ETRN
250-STARTTLS
250-AUTH PLAIN CRAM-MD5 LOGIN DIGEST-MD5
250-AUTH=PLAIN CRAM-MD5 LOGIN DIGEST-MD5
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
QUIT
221 2.0.0 Bye

Gelingt kein Verbindungsaufbau, sollten folgende Dinge überprüft werden:

  • Ist der Postfix-master-Daemon in Betrieb?

  • Protokolliert Postfix Fehler beim Start und beendet sich anschliessend?

  • Protokolliert Postfix Fehler beim Verbindungsaufbau und beendet sich anschliessend?

  • Stimmen konfigurierte IP-Adresse und Port mit den Testdaten überein?

  • Verhindert ggf. eine Firewall einen Verbindungsaufbau?

1.2.4.3. E-Mail über amavisd an Postfix senden

Dieser Test weist nach, dass der amavisd-new-Daemon eine E-Mail auf dem in Abschnitt 1.2.1.1, „amavisd-new-Daemon für eingehende Nachrichten konfigurieren“ definierten Port entgegennimmt, sie überprüft und anschließend über die in Abschnitt 1.2.1.2, „amavisd-new-Daemon für Postfix Rückführungs-Dienst konfigurieren“ konfigurierte Zieladresse erfolgreich an den Postfix Rückführungs-Dienst übergeben kann.

Als Test-Nachricht wird in folgendem Beispiel ein kurzer Text versendet:

$ telnet localhost 10024
220 [127.0.0.1] ESMTP amavisd-new service ready
HELO localhost
250 [127.0.0.1]
MAIL FROM: <>
250 2.1.0 Sender  OK
RCPT TO: <postmaster>
250 2.1.5 Recipient postmaster OK
DATA
354 End data with <CR><LF>.<CR><LF>
From: virus-tester
To: undisclosed-recipients:;
Subject: amavisd test - simple - no spam test pattern

This is a simple test message from the amavisd-new test-messages.
.
250 2.6.0 Ok, id=30897-02, from MTA([127.0.0.1]:10025): 250 2.0.0 Ok: queued as 079474CE44
QUIT
221 2.0.0 [127.0.0.1] amavisd-new closing transmission channel

Die Log-Einträge der Maillog-Datei zeigen den Weg der Nachricht auf. Hier ein Auszug einer erfolgreich zugestellten Nachricht:

Nov  1 11:28:10 mail postfix/smtpd[30986]: connect from localhost[127.0.0.1] 1
Nov  1 11:28:10 mail postfix/smtpd[30986]: 079474CE44: client=localhost[127.0.0.1]
Nov  1 11:28:10 mail postfix/cleanup[30980]: 079474CE44: message-id=<20061101102810.079474CE44@mail.example.com>
Nov  1 11:28:10 mail postfix/qmgr[20432]: 079474CE44: from=<>, size=822, nrcpt=1 (queue active)
Nov  1 11:28:10 mail amavis[30897]: (30897-02) Passed BAD-HEADER, <> -> <postmaster>, quarantine: badh-le5gjszxowBk, mail_id: le5gjszxowBk, Hits: -1.76, queued_as: 079474CE44, 39505 ms 2
Nov  1 11:28:10 mail postfix/smtpd[30986]: disconnect from localhost[127.0.0.1]
Nov  1 11:28:10 mail postfix/local[30987]: 079474CE44: to=<postmaster@example.com>, relay=local, delay=0.27, delays=0.14/0.05/0/0.08, dsn=2.0.0, status=sent (delivered to mailbox: postmaster) 3
Nov  1 11:28:10 mail postfix/qmgr[20432]: 079474CE44: removed

1

Der amavisd-new-Daemon verbindet sich mit dem Postfix Rückführungs-Dienst und übergibt ihm die gesendete E-Mail. Als Queue-ID hat der smtpd-Daemon den Wert 079474CE44 vergeben.

2

Der amavisd-new-Daemon vermerkt im Maillog, dass es eine E-Mail an <postmaster> überprüft und weitergeben hat.

3

Der Postfix local-Dienst vermerkt, dass es die E-Mail mit dem Queue-ID 079474CE44 in der mailbox von postmaster abgelegt hat.

1.3. Filter-Beispiele

Postfix kann verschiedene Kriterien verwenden, um festzulegen ob eine E-Mail zur Überprüfung an amavisd-new gesendet werden soll oder nicht. Je nach Kombination der Kriterien lassen sich unterschiedliche Konfigurationen verwirklichen. Dieser Abschnitt beschreibt folgende Konfigurationen:

  • E-Mails global filtern

  • E-Mails service-bezogen global filtern

  • E-Mails pro Empfänger-Domain filtern

  • E-Mails pro Sender-Domain filtern

  • E-Mails auf Content-Basis filtern

1.3.1. E-Mails global filtern

In den meisten Fällen wird global - jede ein- und ausgehende E-Mail - gefiltert. Globale wirkende Einstellungen werden in Postfix in main.cf vorgenommen. Dort muss der content_filter-Parameter, der ein Versenden einer E-Mail an amavisd-new veranlaßt, eingefügt werden.

Der content_filter-Parameter verlangt die Angabe eines triplets, das aus service-Name (Name des in Abschnitt 1.2.2, „Transport von Postfix zu amavisd-new einrichten“ eingerichteten Dienstes), IP-Adresse und Port des Ziel-Dienstes besteht. Den Daten der vorhergenden Beispiele folgend, ergibt sich folgender Eintrag in main.cf:

content_filter=amavisfeed:[127.0.0.1]:10024

Nach einen postfix reload ist der externe Content Filter aktiviert und mit einer Test-E-Mail kann geprüft werden, ob sie bis in die Mailbox des Empfängers zugestellt wird.

1.3.2. E-Mails service-bezogen global filtern

Postfix kann E-Mails service-bezogen filtern. Der content_filter-Parameter, der E-Mails an amavisd-new delegiert, muss dazu - nicht wie in Abschnitt 1.3.1, „E-Mails global filtern“ angegeben - global in main.cf gesetzt werden, sondern service-bezogen in master.cf.

Das folgende Beispiel geht davon aus, dass der Postfix-Server über mehrere, konfigurierte Ethernet-Interfaces mit den IP-Adressen 192.0.34.166 (WAN), 127.0.0.1 (localhost) und 10.0.0.254 (LAN) verfügt.

Zuerst wird der globale Service smtp, der den smtpd-Daemon (command) aufruft, ausser Betrieb genommen. Anschließend werden drei separate Dienste, für jede IP-Adresse einer, erstellt. Der Service 192.0.34.166:25, für das WAN-Interface, erhält zusätzlich die Option content_filter:amavisfeed:[127.0.0.1]:10024, damit alle eingehenden E-Mails zur Überprüfung an amavisd-new delegiert werden.

# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================
# smtp      inet  n       -       n       -       -       smtpd

...

192.0.34.166:25 inet n  -       n       -       -       smtpd
    -o content_filter=amavisfeed:[127.0.0.1]:10024
    -o receive_override_options=no_address_mappings

10.0.0.254:25   inet n  -       n       -       -       smtpd

127.0.0.1:10025 inet n  -       n       -       -       smtpd
    -o content_filter=
    -o local_recipient_maps=
    -o relay_recipient_maps=
    -o smtpd_restriction_classes=
    -o smtpd_client_restrictions=
    -o smtpd_helo_restrictions=
    -o smtpd_sender_restrictions=
    -o smtpd_recipient_restrictions=permit_mynetworks,reject
    -o mynetworks=127.0.0.0/8
    -o strict_rfc821_envelopes=yes
    -o smtpd_error_sleep_time=0
    -o smtpd_soft_error_limit=1001
    -o smtpd_hard_error_limit=1000
    -o smtpd_client_connection_count_limit=0
    -o smtpd_client_connection_rate_limit=0
    -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks

1.3.3. E-Mails pro Empfänger-Domain filtern

Postfix kann E-Mails je nach eingehender Empfänger-Domain filtern. Dazu wird der content_filter-Parameter nicht, wie in Abschnitt 1.3.1, „E-Mails global filtern“ angegeben, global in main.cf gesetzt, sondern eine Map erstellt, die die zu prüfenden Empfänger-Domains zusammen mit der FILTER-Aktion listet.

[Achtung]Diese Filtermethode arbeitet nicht selektiv!

Jede E-Mail, die eine in der Map gelistete Empfänger-Domain enthält wird an amavisd-new gesendet werden. Auch dann, wenn die E-Mail weitere Empfänger benennt, deren Adresse das Filtern nicht auslösen oder möglicherweise ausdrücklich nicht gefiltert werden sollen.

Wenn vollständig selektiv wirkende Filter-Methoden erforderlich sind, sollten E-Mails global an amavisd-new gesendet werden und die amavisd-new eigenen Regelsätze herangezogen werden, um ein präzises Filtern zu ermöglichen.

Die folgende Beispiel-Map /etc/postfix/filter_recipient_domains legt fest, dass für die Domain example.com E-Mails an den Filter amavisfeed gesendet werden sollen:

example.com               FILTER amavisfeed:[127.0.0.1]:10024

Mit dem Kommando postmap wird die Datei /etc/postfix/filter_recipient_domains anschließend in eine indizierte Map umgewandelt:

# postmap /etc/postfix/filter_recipient_domains

Ein weiterer Aufruf des postmap-Kommandos testet die Map, indem es nach der Domain example.com fragt. Findet postmap den Domain-Namen, listet es die damit verbundene Aktion auf:

# postmap -q "example.com" /etc/postfix/filter_recipient_domains
FILTER amavisfeed:[127.0.0.1]:10024

Die getestete Map wird anschließend in die Liste der smtpd_recipient_restrictions in main.cf eingebunden. Als Auslöser für die Prüfung der Map dient dabei der Postfix check_recipient_access-Parameter - er spricht auf den envelope-recipient an, den ein SMTP-Client in einer SMTP-Session an Postfix übergeben hat.

Das folgende Beispiel bindet die Map so ein, dass sie auf alle Clients angewendet wird:

smtpd_recipient_restrictions =
    ...
    check_recipient_access hash:/etc/postfix/filter_recipient_domains
    ...
    permit_mynetworks
    reject_unauth_destination
    ...

E-Mails pro Empfänger-Domain nur von externen Clients filtern

Dieses Beispiel bindet die Map so ein, dass nur Inhalte fremder (externer) Clients, die eine zu überprüfende Empfänger-Domain angegeben haben, an amavisd-new übergeben werden. Dies geschieht, indem vorher alle bekannte (interne) Clients durch die permit_mynetworks-Restriktion, von einer weiterer Auswertung der smtpd_recipient_restrictions ausgenommen werden:

smtpd_recipient_restrictions =
    ...
    permit_mynetworks
    reject_unauth_destination
    check_recipient_access hash:/etc/postfix/filter_recipient_domains

1.3.4. E-Mails pro Sender-Domain filtern

Generell macht es wenig Sinn, E-Mails anhand der Sender-Domain zu filtern, denn die Angabe der Sender-Domain im envelope-sender während einer SMTP-Session kann auf das Einfachste gefälscht werden.

Sinnvoll ist Filter pro Sender-Domain nur dann, wenn nicht global gefiltert wird, aber sichergestellt werden soll, dass alle ausgehenden E-Mails der eigenen Domain viren- und spamfrei sind.

[Anmerkung]Anmerkung

Die Konfiguration folgt im Wesentlichen den Angaben in Abschnitt 1.3.3, „E-Mails pro Empfänger-Domain filtern“, nur dass zum Filtern pro Sender-Domain der check_recipient_access-Parameter durch den check_sender_access-Parameter ausgetauscht wird.

Eine Map, z.B. /etc/postfix/filter_sender_domains, die das Filtern der Sender-Domain example.com veranlassen soll, sieht wie folgt aus:

example.com               FILTER amavisfeed:[127.0.0.1]:10024

Nach der Konvertierung der map mit postmap /etc/postfix/filter_sender_domains, wird die Map wie folgt in die smtpd_recipient_restrictions eingebaut:

smtpd_recipient_restrictions =
    ...
    check_sender_access hash:/etc/postfix/filter_sender_domains
    ...
    permit_mynetworks
    reject_unauth_destination
    ...
[Wichtig]Wichtig

Die Map muss vor permit_mynetworks geprüft werden, denn nur dann findet sie auch Anwendung auf jene Clients, die aus mynetworks stammen.

1.3.5. E-Mails auf Content-Basis filtern

Postfix kann, mit bewußten Einschränkungen (siehe Postfix: BUILTIN_FILTER_README), den Inhalt von header, body und auch MIME-header durchsuchen und bei einem Treffer Aktionen wie z.B. den Aufruf einers Filters veranlassen.

Das folgende Beispiel zeigt wie Postfix, wenn es den String offer im Subject:-Header einer E-Mail findet, diese zur Überprüfung an amavisd-new delegiert. Dazu wird eine Map /etc/postfix/filter_header erstellt, die ein passendes regexp-Suchmuster und die dazugehörige Aktion enthält:

/^Subject:*.offer/   FILTER amavisfeed:[127.0.0.1]:10024
[Anmerkung]regexp- oder pcre-Map indizieren?

regexp- oder pcre-Map sind und bleiben reine Text-Dateien. Sie müssen und können auch nicht mit dem postmap-Kommando in ein indiziertes Datenbankformat überführt werden. Tests der regexp- oder pcre-Maps mit dem postmap-Kommando und der Option -q sind allerdings möglich und sinnvoll.

Anschließend wird die Map in main.cf eingebunden. Weil in diesem Beispiel der Header einer E-Mail geprüft werden soll, wird dazu der header_checks-Parameter (und nicht body_checks oder mime_header_checks) verwendet:

header_checks = regexp:/etc/postfix/filter_header

Nach einem postfix reload wird Postfix jede E-Mail mit dem Wort offer im Subject:-Header zur Überprüfung an amavisd-new delegieren.

1.4. Erweiterte Postfix und amavisd-new Konfiguration

In einem post-queue Setup passiert eine Nachricht die Postfix-Dienste smtpd und cleanup zweimal. Einmal auf dem Weg zum content filter und ein zweites Mal wenn eine zugelassene Nachricht wieder in das Postfix-Mailsystem zurückgeschleift wird.

Global in main.cf konfigurierte Tests und Transformationen werden dabei zweimal durchgeführt. Postfix verbraucht dadurch unnötig, möglicherweise entscheidende Ressourcen. Wer die standardmäßig global wirksamen Einstellungen aus main.cf entfernt und sie stattdessen selektiv in master.cf anwendet spart Ressourcen und gewinnt ggf. sogar mehr Kontrolle beim Spamschutz.

Wie kann gespart werden?

smtpd-Daemon

Tests und Transformationen wie Access-Prüfungen, Empfänger-Valdierung oder eingebundene Milter können dort z.B. selektiv mit der Option -o (siehe auch: Abschnitt 1.2.3, „Dedizierten Postfix SMTP-Server für rückkehrende Nachrichten einrichten“) das Laufzeitverhalten ausgewählter smtpd-Daemonen verändern, anstatt global von allen laufenden Postfix smtpd-Daemonen durchgeführt zu werden.

cleanup-Daemon

Tests und Transformationen, die im cleanup-Daemon stattfinden, sind etwas schwieriger ressourcenschonend zu verteilen, denn anders als beim smtpd-Daemon betreibt ein normales Postfix Mailsystem nur einen cleanup-Daemon. Manche der wichtigeren cleanup-Einstellungen können dynamisch über receive_override_options beeinflusst werden, aber das reicht eventuell nicht aus.

[Tipp]Checks und Transformationen

Idealerweise werden Test und Transformationen nur einmal, entweder vor oder nach dem content filter, durchgeführt. Wann eine Transformation (z.B. Adressumschreibung) durchgeführt werden soll, hängt vom beabsichtigten Effekt ab, z.B. ob der content filter Empfänger-Adressen unverändert oder bereinigt (z.B. Alias-Name in Systemname umgeschrieben) sehen soll. Typische Transformationen sind:

  • Adressen umschreiben

  • BCC-Empfänger hinzufügen

  • Header-Angaben der E-Mail verändern

Das Prinzip der Sparsamkeit gilt auch für Tests. Ein Test sollte z.B. nur einmal, dann wenn die Nachricht das System betritt, durchgeführt werden. Eine unerwünschte Nachricht kann so früh identifziert und von der weiteren Verarbeitung und späteren, wiederholten Tests ausgenommen werden. Nachgelagerte Systemressourcen werden so nicht in Anspruch genommen und darüberhinaus verhindert das frühzeitige Ausfiltern Bounces, die zu einem späteren Zeitpunkt auftreten könnten.

1.4.1. Architektur mit mehreren cleanup-Daemonen

Wer mehr Kontrolle über den cleanup-Daemon haben möchte, als mit den receive_override_options möglich ist, muss mehrere Instanzen des cleanup-Daemon nutzen. Das ist entweder mit einem Multiple-Instance-Postfix (ab Postfix 2.6.) möglich oder indem mehrere cleanup-Dienste in master.cf mit entsprechenden Optionen konfiguriert und betrieben werden.

Das folgende Diagramm zeigt ein Setup mit zwei cleanup-Daemonen in einer einzigen Postfix-Instanz:

      .......................................
      :                Postfix              :
   ----->smtpd \                            :
      :         -pre-cleanup-\       /local---->
   ---->pickup /              -queue-       :
      :             -cleanup-/   |   \smtp----->
      :     bounces/    ^        v          :
      : and locally     |        v          :
      :   forwarded   smtpd  amavisfeed     :
      :    messages   10025      |          :
      ...........................|...........
                        ^        |
                        |        v
            ............|...............................
            :           |   $inet_socket_port=10024    :
            :           |                              :
            : $forward_method='smtp:[127.0.0.1]:10025' :
            : $notify_method ='smtp:[127.0.0.1]:10025' :
            :                                          :
            :    amavisd-new                           :
            ............................................

Prozedur 1.1. Nachrichtenfluß mit zwei cleanup-Diensten

  1. Nachrichten betreten das Postfix-System regulär über den smtpd- oder pickup-Daemon

  2. Der (zusätzliche) pre-cleanup-Daemon führt Transformationen und Tests durch

  3. Der qmgr-Daemon routet die Nachricht zum amavisd-new content filter

  4. amavisd-new filtert die Nachricht

  5. Nachrichten werden über den dedizierten, lokalen smtpd-Daemon in das Postfix-System zurückgeführt

  6. Der cleanup cleanup-Daemon führt zu diesem Zeitpunkt sinnvolle Transformationen und Tests durch aber läßt jene aus, die in Schritt 2 schon durchgeführt worden waren.

1.4.2. Zwei cleanup-Daemonen konfigurieren

Folgende Schritte sind notwendig, um zwei unabhängige und dedizierte cleanup-Daemonen für zwei smtpd-Daemonen bereit zu stellen:

  1. Erstellen eines zweiten cleanup-Dienstes

  2. Modifizieren des bestehenden cleanup-Dienstes

  3. smtpd-Daemonen so konfigurieren, dass sie jeweils ihren dedizierten cleanup-Daemon nutzen

1.4.2.1. Erstellen eines zweiten cleanup-Dienstes

Das folgende Beispiel fügt einen weiteren cleanup-Daemon mit dem Dienstnamen pre-cleanup in master.cf hinzu. Diese Instanz wird später für Nachrichten vor dem content filter zuständig sein:

# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================
# smtp      inet  n       -       n       -       -       smtpd

...

pre-cleanup unix    n       -       n       -       0       cleanup
    -o virtual_alias_maps= 

Die obige Konfiguration beläßt kanonische Adressumschreibung aktiviert, damit der content filter kanonische (externe) E-Mail-Adressen zur Bearbeitung vorfindet. Gleichzeitig wird etwaig global vorgegebene virtual alias Transformation deaktiviert. Später, nach dem content filter, wird die Adressumschreibung wieder aktiviert. Hier, an dieser Stelle, soll der content filter mit den Original Zieladressen arbeiten.

1.4.2.2. Modifizieren des bestehenden cleanup-Dienstes

Der originäre cleanup-Dienst mit dem Servicenamen cleanup ist in diesem Beispiel für Nachrichten zuständig, die nach dem content filter wieder in das Postfix-Mailsystem zurückgeschleift werden sollen.

Aufgaben, die bereits der pre-cleanup-Service durchgeführt hat, sollen jetzt nicht ein weiteres Mal durchgeführt werden. Das folgende Beispiel deaktiviert Tests, die ein pre-cleanup-Service typischerweise schon absolviert hat:

# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================
# smtp      inet  n       -       n       -       -       smtpd

...

cleanup unix    n       -       n       -       0       cleanup
    -o mime_header_checks= 1
    -o nested_header_checks= 2
    -o body_checks= 3
    -o header_checks= 4

1 2 3 4

Diese Angaben deaktivieren für pre-cleanup-Dienste typische Header- und Body-Checks.

[Anmerkung]always_bcc-Parameter

Diese, nachgelagerte cleanup-Instanz ist auch die richtige, um always_bcc-Optionen zu setzen. Würde die Option stattdessen global in main.cf gesetzt, beträfe sie beide cleanup-Dienste und es würden jeweils zwei Kopien einer Nachricht an den BCC:-Empfänger gesendet.

1.4.2.3. cleanup-Dienste smtpd-Daemonen zuordnen

Das neue, interne Mail-Routing wird aktiviert, indem smtpd-Dienste auf Port 25, der submission-Dienst auf port 587 und der pickup-Dienst angewiesen werden, fortan den pre-cleanup-Dienst zu nutzen:

# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================
# smtp      inet  n       -       n       -       -       smtpd

...

pickup    fifo  n       -       n       60      1       pickup
    -o cleanup_service_name=pre-cleanup
smtp      inet  n       -       n       -       -       smtpd
    -o cleanup_service_name=pre-cleanup
submission inet n       -       n       -       -       smtpd
    -o cleanup_service_name=pre-cleanup

1.5. Optimierung

1.5.1. Anzahl maximaler Content Filter Prozesse

Die wichtigste Stellschraube beim Abstimmen und Optimieren von Postfix und amavisd-new aufeinander ist die Anzahl maximaler Content Filter Prozesse:

  • Ist der Wert zu gering, werden die vorhandenen Hardware-Ressourcen des Host-Systems nicht optimal genutzt und wertvolle Zeit im Zustellprozess verschwendet.

  • Ein hoher Wert, steigert vielleicht nicht die Performance des Zustellprozesses, belastet aber die Verwaltung des Arbeitsspeichers des Host-Systems unnötig.

  • Ein viele zu hohe Anzahl maximaler Content Filter Prozesse widerum sorgt dafür, dass die Ressourcen des Systems völlig überlastet sind - der E-Mail-Durchsatz sinkt, weil die Prozesse aufeinander warten müssen. Schlimmstenfalls können E-Mails nicht mehr sicher zugestellt werden.

Ein in der Praxis erprobter, konservativer Startwert ist eine Anzahl von maximal 2 Content Filter Prozessen. Im Alltag kann dieser Wert oft bis auf maximal 10 Content Filter Prozesse gesteigert werden. Der genaue Wert hängt davon ab, welche Ressourcen das Host-System bereitstellen kann und welche Anforderungen die in amavisd-new eingebundene Anti-Virus und Anti-Spam-Software an das System stellen.

Auf jeden Fall ist es unbedingt notwendig, die Anzahl maximaler Content Filter Prozesse beider Dienste, Postfix und amavisd-new, aufeinander abzustimmen. In amavisd-new steuert der $max_servers-Parameter der Konfigurationsdatei amavisd.conf die Anzahl maximaler Content Filter Prozesse; in Postfix regelt dies der Feld-Eintrag maxproc in master.cf des dedizierten Transports zu amavisd.

Diese Werte sollten immer gleich sein. Bietet amavisd-new mehr Prozesse an, als von Postfix genutzt werden, werden Ressourcen verschwendet. Andersrum, wenn Postfix mehr dedizierte Transporte gleichzeitig startet als amavisd-new Verbindungen annehmen kann, wird der dedizierte Postfix Client abgewiesen und Fehler melden.

[Anmerkung]Anzahl maximaler Content Filter Prozesse in main.cf steuern

Anstatt die Anzahl maximaler Content Filter Prozesse in master.cf für den dedizierten Transport zu amavisd-new hin festzulegen, kann der Standardwert (100) mit „-“ in notiert werden und stattdessen folgender Parameter in main.cf gesetzt werden:

amavisfeed_destination_concurrency_limit = 2

Der Name des Parameters beginnt mit dem Namen des Services in master.cf, hier amavisfeed, und setzt sich mit der Endung _destination_concurrency_limit fort. Als Vorgabe wird auch hier der konservative Wert 2 verwendet.

1.5.2. Weitere Optimierungs-Tipps

Weitere Optimierungs-Tipps finden Sie in der amavisd-new Dokumentation README.performance und den Folien des Vortrags amavisd-new, advanced configuration and management von Mark Martinec.