Variable Spamchecks mit Postfix trotz content_filter

In den letzten Tagen hatte ich Gelegenheit meine Postfix-Konfiguration neu aufzubauen. Bisher hatte ich amavisd-new als Frontend-Filter für Spamassassin benutzt, in Ubuntu 8.04 funktioniert die Installation allerdings nicht mehr:

Starting amavisd: ERROR: MISSING REQUIRED BASIC MODULES:
  Compress::Zlib
BEGIN failed--compilation aborted at /usr/sbin/amavisd-new line 171.
(failed).
invoke-rc.d: initscript amavis, action "start" failed.
WARNING: Starting amavisd-new failed. Please check your configuration.

Das CPAN-Modul respektive libcompress-zlip-perl ist installiert, vielleicht weis ein Leser ja Rat.

Auf jeden Fall muss eine Alternative her. Im Spamassassin-Wiki ist eine Methode beschrieben, wie man Spamassassin als globalen content_filter in Postfix einbindet. Prinzipiell ganz gut, allerdings werden so alle Mails gefiltert, die Postfix passieren. Ich möchte aber einige User und auch ganze Domains ausschließen.

Installation

Zu allererst muss sichergestellt sein, dass Spamassassin auch installiert ist, auf Debian-Systemen reicht ein apt-get install spamassassin. Starte den Dämon mittels /etc/init.d/spamassassin start.

In der /etc/postfix/master.conf wird ein neuer Transport spamcheck hinzugefügt:

spamcheck unix -     n       n       -       -       pipe
    user=nobody argv=/usr/bin/spamc -f -e /usr/sbin/sendmail -oi -f ${sender} ${recipient}

In die /etc/postfix/main.conf werden zwei Änderungen vorgenommen. Das Recipient-Limit für den genannten Spamassassin-Transport auf 1 setzen, damit jeweils nur eine E-Mail durchgereicht wird. Und als vorletzten Parameter -- vor dem abschließenden permit -- wird ein access_check auf die Datei /etc/postfix/access_spamassassin hinzugefügt.

spamcheck_destination_recipient_limit = 1

smtpd_recipient_restrictions = 
    reject_non_fqdn_recipient, 
    reject_non_fqdn_sender,  
    permit_mynetworks,        
    # ... RBL Listen, etc
    reject_unauth_destination,
    # Hier werden die Empfänger geprüft
    check_recipient_access hash:/etc/postfix/access_spamassassin,
    permit

Zu guter letzt lege die Datei /etc/postfix/access_spamassassin an. Ihr ihr wird penibel definiert, welche Empfänger letztendlich durch Spamassassin geprüft werden:

example.org       FILTER spamcheck:dummy
user@example.com  OK
example.com       FILTER spamcheck:dummy

Der Aufbau ist einfach, an erster Stelle steht die Empfängeradresse oder Domain gefolgt von einem Leerzeichen oder Tab und dem Wort FILTER spamcheck:dummy. spamcheck ist unser oben definierter Transport, dummy gibt den nächsten Hop an, den die Mail nehmen soll. In unserem Fall ist es ja der localhost, in diesem Fall reicht einfach dummy. Wenn einzelne Benutzer ausgeschlossen werden sollen, setze ein OK dahinter, achte aber auf die Reihenfolge.

Nicht vergessen, danach ein postmap hash:/etc/postfix/access_spamassassin auszuführen.

Was passiert bei diesem Setup?

Ein fremder Mailserver liefert die E-Mail ein, sofern sie alle Checks besteht passiert sie den Spamassassin-Recipient-Check und wird weitergeleitet zu spamc (rote Linie), einem Helferprogramm dass den Mailbody mit Spamassassin prüft. spamc schickt danach die Nachricht über das lokale sendmail Programm wieder an Postfix (blaue Linie).

Da die Nachricht diesmal vom lokalen System kommt, durchläuft sie nicht alle Checks sondern wird schon bei der Prüfung auf lokale IPs permit_mynetworks an den Haupttransport (virtual_transport, local_transport, etc.), wie zum Beispiel Procmail, abgegeben.

Steht die Zieladresse erst garnicht in der access-Datei, wird sie auch nicht mit Spamassassin geprüft und mittels des abschließenden permit an den originalen Haupttransport weitergeleitet (graue Linie).

Nachteile

Der große Nachteil bei diesem Setup ist, dass die Mail, bevor die spamc zugestellt wird, die Postfix-Queue verlässt. Es ist danach nicht mehr möglich, die Mail zu rejecten -- jedenfalls nicht ohne Backscatter zu erzeugen.

Gerade das ist der große Vorteil von Amavis, wenn er als smtpd_proxy_filter eingebunden ist. So lassen sich dort alle oder bestimmte Mails ab einer gewissen Score rejecten. Da ich aber recht aggressiv Blacklisten einsetze ist die False-Positive Rate bei Spamassassin-erkannten Mails recht hoch, so dass ich damit leben kann, alle Mails letztendlich anzunehmen.

In der nächsten Zukunft werde ich mir mal Gedanken machen (sprich Google fragen), ob man das oben gezeigte Schema nicht auch als smptd_proxy_filter verbauen kann.

Meine Postfix-Konfiguration

Konfigurationsdateien sind ja mindestens so spannend wie Screenshots. Da ich keine Sicherheitsbedenken habe sie zu veröffentlichen und sie dazu noch kommiertiert ist; hier ist meine komplette Postfix-main.conf. Vielleicht findet noch jemand Ideen darin.

# --------------------------------------------------------------------
# Base Server Config
# --------------------------------------------------------------------

myhostname = schwammkopf.mahner.org
mydestination = localhost # myhostname steht in den virtual domains
myorigin = /etc/mailname
mynetworks = 127.0.0.0/8, 88.198.109.76, [::ffff:127.0.0.0]/104, [::1]/128 
inet_interfaces = all
smtpd_banner = $myhostname ESMTP - Der schwammige Mailserver
append_dot_mydomain = no

# Biff Tannen? Niemals!
biff = no

# foo+bar@example.com, brauch ich nicht
recipient_delimiter =

# Deutsche Bounce-Files
bounce_template_file = /etc/postfix/bounce-templates/bounce.de-DE.cf

# Systembenutzer
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases

# --------------------------------------------------------------------
# SMTP Errorlimits
# --------------------------------------------------------------------

# Maximale E-Mail Größe (TODO: auf 2kb setzen) 50MB
message_size_limit = 52428800

# Wann soll eine Warnung erfolgen, wenn die Mail
# nicht zugestellt werden kann?
delay_warning_time = 1h

# Wie lange soll die Mail in der Queue bleiben,
# wenn keine Zustellung möglich ist?
maximal_queue_lifetime = 1d 
bounce_queue_lifetime = 1d

# Max und Min Zeit wenn der Connect fehlschläft (auch 4xx)
# Greylisting ist typischerweise auf 5min eingestellt
minimal_backoff_time = 330s 
maximal_backoff_time = 8000s

# Wie lange nach dem HELO warten?
smtp_helo_timeout = 60s

# Wie viele Adressen in einer Nachricht maximal?
# Mailman ftw!
smtpd_recipient_limit = 16

# Wie viele Fehler bis wir müde werden und wie viele,
# bis komplett blockiert wird
smtpd_soft_error_limit = 3 
smtpd_hard_error_limit = 12
smtpd_error_sleep_time = 1s

# Ein nettes Hallo beim Connect bitte 
smtpd_helo_required = yes

# Spammerzeit vergeuden 
smtpd_delay_reject = no 
disable_vrfy_command = yes

# --------------------------------------------------------------------
# SMTP Checks & Restrictions
# --------------------------------------------------------------------

smtpd_client_restrictions =       
smtpd_helo_restrictions =                               
smtpd_sender_restrictions = 
smtpd_data_restrictions =
smtpd_recipient_restrictions =  check_client_access hash:/etc/postfix/access/client,
                                check_helo_access hash:/etc/postfix/access/helo,
                                check_sender_access hash:/etc/postfix/access/sender,
                                check_recipient_access hash:/etc/postfix/access/recipient,
                                # Blocken wenn Pipelining nicht angefragt wurde
                                reject_unauth_pipelining,
                                # Auf anständige Syntax prüfen
                                reject_non_fqdn_recipient, 
                                reject_non_fqdn_sender,  
                                # DNS Checks
                                reject_unknown_recipient_domain,
                                reject_unknown_sender_domain,
                                # Eigene Nutzer erlauben
                                permit_mynetworks,        
                                permit_sasl_authenticated,          
                                # RBL Blacklisten
                                reject_rbl_client zen.spamhaus.org,
                                reject_rbl_client ix.dnsbl.manitu.net,
                                reject_rbl_client bl.spamcop.net,
                                reject_rbl_client blackhole.securitysage.com,
                                # Greylisting   
                                check_policy_service inet:127.0.0.1:60000,
                                # Relaying
                                reject_unlisted_recipient,
                                reject_unauth_destination,
                                # Spamassassin Content Filter
                                check_recipient_access hash:/etc/postfix/access/spamassassin,
                                # Wer nicht in spamassassin steht, ist durch                       
                                permit

# --------------------------------------------------------------------
# TLS Empfang/Versand
# --------------------------------------------------------------------

# smptd (Mailempfang)
smtpd_tls_security_level=may
smtpd_tls_cert_file=/etc/postfix/certs/cert.pem
smtpd_tls_key_file=/etc/postfix/certs/key.pem
smtpd_tls_CAfile = /etc/postfix/certs/CAcert.pem
smtpd_tls_loglevel = 1

# Bei SSL-Verbindung diese im received-Header markieren
smtpd_tls_received_header = yes

# smtp (Mailversand)
smtp_tls_security_level=may
smtp_tls_cert_file=/etc/postfix/certs/cert.pem
smtp_tls_key_file=/etc/postfix/certs/key.pem
smtp_tls_CAfile = /etc/postfix/certs/CAcert.pem
smpt_tls_loglevel = 1

# --------------------------------------------------------------------
# SASL (SMTP-Auth)
# --------------------------------------------------------------------

smtpd_sasl_type=dovecot
smtpd_sasl_path=private/auth
smtpd_sasl_auth_enable=yes
smtpd_sasl_security_options = noanonymous

# --------------------------------------------------------------------
# Transport and Mapping
# --------------------------------------------------------------------

# Dovecot transport
virtual_transport = dovecot
dovecot_destination_recipient_limit = 1

# Spamassassin Transport in den recipient restrictions
spamassassin_destination_recipient_limit = 1

virtual_uid_maps=static:5000
virtual_gid_maps=static:5000

virtual_mailbox_domains = mysql:/etc/postfix/mysql/virtual-mailbox-domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql/virtual-mailbox-maps.cf
virtual_alias_maps = mysql:/etc/postfix/mysql/virtual-alias-maps.cf,
                     mysql:/etc/postfix/mysql/email2email.cf

Comments closed

Sorry, new comments are no longer allowed for this entry.

Write me an email if you have feedback or any questions regarding this post. If you found this post useful and just want to say thank you then don't forget that I have an Amazon Wishlist. :-)


↑ to the elevators

© 2001—2010 Martin Mahner. This is an I ♥ Django Project.

Admin | Generated: Sat, 24 Jul 2010 20:10:05 +0200