wiesi200
Goto Top

E-Mail Anti Spam Proxy mit CentOS

back-to-topVorwort

Hallo,

Hier eine kleine Einleitung für den Grund des Projekts von mir.

Vor einiger Zeit sind wir zu der Idee gekommen "Webseite selber hosten".
Gut, Server gekauft, NGINX drauf installiert und in die DMZ gepackt und den auch gleich als Reverse Proxy für unseren Exchange zum OWA verwendet aus Mangel an öffentlichen IP's. Das ganze aber auch noch vorsichtshalber Virtualisiert, man weiß ja nie.

Nach einiger Zeit hat mich hier @Dani mit einer Anleitung darauf gebracht. Mit Squid könnte man auch noch Outlook Anywhere zum laufen bekommen.
Super Idee. Zweite VM und Squid drauf, läuft super.

Dann hat mich @Frank noch darauf gebracht Varnish einzusetzen. Ein paar Optimierungen + Memcache und unsere Typo3 Seite ist jetzt Pfeilschnell.

So, alles läuft Prima. Jetzt war ich in letzter Zeit mit unserm Spam Gateway nicht mehr so zufrieden.
Darum: "Wenn man im HTTP Bereich so was schönes Basteln kann, dann geht das bei SMTP doch auch.

Jetzt bin ich auf diese Anleitung gestoßen, hat aber leider nicht 1:1 Funktioniert.
http://dokuwiki.nausch.org/doku.php/centos:mail_c6:start

Deshalb schreibe ich jetzt mal wieder eine eigene
Ich habe mich von Anfang an mit CEntOs beschäftigt da hier die Support Laufzeiten relativ hoch sind.
Auch wenn hier die Verbreitung nicht so hoch ist wie bei Ubuntu.

back-to-topInstallation

als erstes installieren wir CentOS als Minimalinstallation (aktuell 6.5) der Hostname sollte so gelegt werden wie sich der Mailserver im Internet melden soll.
Also z.B. entsprechend auch dem Reverse DNS Eintrag.


gleich im Anschluss machen wir noch ein paar kleinere Grundanpassungen
yum install wget
yum update

back-to-topRPMForge einbinden
Hier die Anleitung von CentOS
http://wiki.centos.org/AdditionalResources/Repositories/RPMForge

wget http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm
rpm --import http://apt.sw.be/RPM-GPG-KEY.dag.txt
rpm -i rpmforge-release-0.5.3-1.el6.rf.*.rpm


jetzt können wir mit der Konfiguration Anfangen
back-to-topAnpassung Firewall IPTables
es muss eigentlich nur der Port 25 freigegeben werden

vi /etc/sysconfig/iptables
-A INPUT -m state --state NEW -m tcp -p tcp  -dport 25 -j ACCEPT

Anschließen starten wir IPTables neu

service iptables restart

back-to-topGrundeinstellungen Postfix

Die Postfix Einstellungen kann man sehr schön mit dem Befehl "postconf" bearbeiten.
eine vollständige Übersicht der Möglichkeiten ist auf
http://www.postfix.org/postconf.5.html
dokumentiert

Hier mal die meiner Meinung nach wichtigsten Grundregeln.

# wird benötigt da Postfix bei CentOS erst mal nur auf sich selbst, also Localhost hört 
postconf -e "inet_interfaces = all"  
# hier definieren wir die Domains die Postfix verarbeiten darf 
postconf -e "relay_domains = example1.de, example2.de"  
# hier sagen wir Postfix wo wir die Domain - Mailserver Zuordnung hinterlegen 
postconf -e "transport_maps = hash:/etc/postfix/transport"  
#erste Prüfung bei der Kontaktaufnahme zum Mailserver
postconf -e "smtpd_helo_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_invalid_hostname, reject_unauth_pipelining, reject_non_fqdn_hostname"  
permit_sasl_authenticated: hier erlauben wir den zugriff Clients die sich per sasl am Mailserver anmelden
http://de.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer

permit_mynetworks: Hiermit erlauben wir den Zugriff für das Lokale Netz. Der Parameter für "mynetworks" kann man auch über Postconf einstellen.

reject_invalid_hostname: Dadurch blockieren wir alle die sich bei der Kontaktaufnahme nicht richtig melden

reject_unauth_pipelining: Beim Pipelining werden SMTP Kommandos nicht 100% regelkonform verwendet um eine schnellere Übertragung zu erreichten. Bei Spamsendern bedeutet ja Zeit ist Geld.

reject_non_fqdn_hostname: Wenn beim HELO Command kein FQDN Hostname verwendet wird blocken wir auch gleich mal
#Überprüfung bei der Eingabe des Empfängers
postconf -e "smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_invalid_hostname, reject_non_fqdn_hostname, reject_unknown_recipient_domain, reject_non_fqdn_recipient, reject_non_fqdn_sender, reject_unknown_sender_domain, reject_unauth_destination, reject_rbl_client ****"  
reject_unknown_recipient_domain: Wenn die Empfänger Domain nicht bekannt ist hat der Sender bei uns auch nichts verloren.

reject_non_fqdn_recipient: Wenn die Empfängeradresse nicht mit einem FQDN angeben wird, dann blockieren wir auch.

reject_non_fqdn_sender: Der Absender sollte dann natürlich auch mit einem FQDN angegeben sein.

reject_unknown_sender_domain: Wenn die Absender Domain keinen gültigen DNS-A oder MX Eintrag hat schmeißen wir ihn natürlich auch raus.

reject_unauth_destination: Hier wird das Ziel noch mal zu unseren Relay Domain abgeglichen.

reject_rbl_client: Dieser Parameter bedarf eine etwas genauere Erklärung und es sollte gut überlegt werden wie man ihn einsetzt. Im Internet gibt es Zahlreiche Anbieter von Blacklist. Die Geschäftsmodelle und die Aggressivität wie hier gefiltert wird ist unterschiedlich.
Als extremes Negativbeispiel will ich hier http://www.uceprotect.net/de/ nennen. Wer selber mal auf einer Blacklist gelandet ist (ich leider auch) wird die kennen. Auf der Webseite keinerlei Impressum oder andere Angaben für Kontaktaufnahmen und man wird erst nach 7 Tagen entfernt außer man zahlt.
Nach anfänglicher Verwendung von Spamhaus (bis zu einem gewissen Volumen kostenlos) habe ich zu Baracuda gewechselt. Hier war auch eine Warnung von Lonesome Walker, hatte hier aber auch einige Falschmeldungen bzw. viel Ausländische Mail's sind durchgekommen.

Diese Einstellungen sind sehr stickt. Hier gibt es nur "entweder / oder".
Anders würde es mit
http://www.policyd-weight.org/
gehen hier wird anhand von ähnlichen Parametern gewichtet und ab einer gewissen Anzahlt von Verstößen wird als Spam bewertet.

# Hier die Überprüfung wenn der Mailinhalt übertragen wird
postconf -e "smtpd_data_restrictions = reject_unauth_pipelining permit"  
permit: alles durch die vorherigen Prüfungen durch gegangen ist wird erlaubt

Dann bearbeiten wir die Datei transport
vi /etc/postfix/transport
example1.de smtp:[mailserver1.intern]
example2.de smtp:[mailserver2.intern]

Hier stellen wir ein auf welche Empfänger Postfix weiterleiten darf
vi /etc/postfix/relay_recipients
# Hier eine Wildcard für die kpl. Domain. Geht aber auch auf einzelne Adressen
@example1.de OK
@exampel2.de OK

# Erstellen einer Transport DB für Postfix
postmap /etc/postfix/transport
# Erstellen einer relay_recipients DB
postmap /etc/postfix/relay_recipients
#Postfix config neu laden
service postfix start
# und festlegen das Postfix automatisch gestartet wird.
chkconfig postfix on

Wenn eine der beiden Dateien geändert wird muss die DB durch den Befehl postmap neu erstellt werden

Und schon müsste Postfix als "einfaches" SMTP Gateway funktionieren.
Das ganze können wir jetzt per Telnet testen.
Aber das ganze ist uns ja noch zu wenig, deshalb geht's gleich weiter.

Das ganze könnte man hier schon ausbauen:
Anlegen von Blacklist's.
E-Mail Adressen rewriting.
Das ganze z.b. auch mit SQL Anbindung
Puffern von E-Mails
Adressgenau definieren was weitergeleitet werden darf, durch manuelle Eingabe/LDAP Abfrage
Genauer werde ich hier aber nicht darauf eingehen, das es doch den Umfang sprengen würde.
Aber es geht so ziemlich alles was das Herz begeht.

back-to-topSpam/Virenschutz


back-to-topEmpfängeradressüberprüfung
Viele Mails gehen an Adressen die nicht mal existieren. Um hier nicht den kpl. Check durchführen zu müssen lassen wir das Postfix überprüfen. Da es aber grundsätzlich alle Mail's weiterleiten soll kennt es gültige Adressen nicht und mit der Hand pflegen ist auch nicht so toll. Dafür gibt es aber das Modul Verify.

Postfix fragt dadurch beim Backend System kurz nach ob es die Adresse gibt und vermerkt das in einer Datenbank und puffert das für einen gewissen Zeitraum
Hierzu sind die Parameter:
address_verify_positive_refresh_time - Wann positive Adressen bestätig werden
address_verify_positive_expire_time - Wann positive Adressen ablaufen
address_verify_negative_refresh_time - Wann negative Adressen bestätig werden
address_verify_negative_expire_time - Wann negative Adressen ablaufen
address_verify_sender und double_bounce_sender - Wie abgefragt wird
zuständig

Damit das ganze funktioniert müssen wir folgendes ändern
#Anlegen eines Verzeichnisses für die Datenbank
mkdir /var/spool/postfix/data
#Rechte einsellen
chown postfix.root /var/spool/postfix/data
chmod 700 /var/spool/postfix/data
# sagen wo sich die Datenbank befinden soll
postconf -e "address_verify_map = btree:/var/spool/postfix/data/verify"  
# und die vorher angelegeten grundüberprüfungen erweitern
postconf -e "smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_invalid_hostname, reject_non_fqdn_hostname, reject_unknown_recipient_domain, reject_non_fqdn_recipient, reject_non_fqdn_sender, reject_unknown_sender_domain, reject_unauth_destination, reject_unverified_recipient,, reject_rbl_client ****"  
Bei den smtpd recipients ist nur der Parameter "reject_unverified_recipient," hinzugekommen. Und besagt nur das wir eben eine Empfängerüberprüfung durchführen sollen.
Eigentlich funktioniert das ganze schon nur unser Backend Exchange sag zu allem erst mal "Ja und Amen". Somit wird hier auch jede Mail bestätig.
Hier muss ab Exchange 2007 die Antispam Funktion per PowerShell aktiviert werden. Das dazu gehörige Script findet man im Installverzeichniss unter Script
Anbei auch noch die MS Anleitung
http://technet.microsoft.com/de-de/library/bb201691(v=exchg.150).aspx

Jetzt finden wir in der Management Console beim Hubtransport ein zusätzlich Registerkarte

9d04b0195e35fe6bd86375a83cd98aa9

Hier müssen wir bei den Blockierten Empfängern der Empfängerfilterung den Punt "Nachrichten Blockern, die an Empfänger gesendet wurden, die es im Verzeichnis nicht gibt" aktivieren.

Im Betrieb können wir dann denn Inhalt der Postfix Empfängerdatenbank mit folgendem Befehl überprüfen:
postmap -s btree:/var/spool/postfix/data/verify

Zu erwähnen ist hier noch das in so einem Fall der Fehlercode 450 (The requested command failed because the user's mailbox was unavailable.) zurück gegeben wird.
Da der Fehlercode sich im 400er Bereich bewegt handelt es um einen temporären Fehler somit wird der Zustellende Mailserver es immer wieder versuchen.
Wenn man sich den nächsten Punkt (Greylisting) ansieht wird man zwar verstehen das es für Spamsender in der Regel uninteressant ist da die wenigsten einen Zweiten versuch starten aber, reguläre Absender die sich bei der E-Mailadresse vertippt haben bekommen in der Regel sehr spät eine Reaktion das sie einen Fehler gemacht haben.
Aber es kann auch ein gewünschter Effekt sein, und zwar dann die Verbindung zwischen Gateway und internen Mailserver relativ schlecht ist und der Empfänger nicht sofort bestätigt werden kann.

Ändern kann man das mit der Codezeile:
postconf -e "unverified_recipient_reject_code = 550"  

Fehlercode 550 - The requested command failed because the user's mailbox was unavailable

Da ja die Empfänger "gepuffert" werden, würde selbst bei schlechter Verbindung die Falschbenachrichtigung nur am Anfang auftreten, bzw wenn der Empfänger selten angeschrieben wird.

back-to-topGreylisting
Graylisting funktioniert einfach unter der Annahme das Spam Versender möglichst Schnell so viele Mail's wie möglich zustellen wollen. Graylisting verweigert deshalb den ersten Zustellversuch einer Mail mit einem temporären Fehler und merk sich 3 Parameter

  • Absender-IP-Adresse
  • eMail-Adresse des Absenders
  • eMail-Adresse des Empfängers

Ein sauber Konfigurierter Mailserver wird erneut versuchen diese Mail Zuzustellen und kommt dann leicht Zeitverzögert durch. Bekommt man von dem gleichen Absender öfter E-Mail werden die dann, da ja bekannt, gleich durchgereicht.

Das einrichten ist hier sehr leicht.
# Paket installieren
yum install postgrey
# Dienst Starten
service postgrey start
# und dafür sorgen das er immer gleich beim Booten des Servers startet
chkconfig postgrey on

Jetzt müssen wir wieder die "smtpd_recipient_restrictions" um den Parameter "check_policy_service unix:postgrey/socket" erweitern
postconf -e "smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_invalid_hostname, reject_non_fqdn_hostname, reject_unknown_recipient_domain, reject_non_fqdn_recipient, reject_non_fqdn_sender, reject_unknown_sender_domain, reject_unauth_destination, check_recipient_access btree:/etc/postfix/access_recipient-rfc, check_policy_service unix:postgrey/socket, reject_rbl_client ****"  

Da wir im Haus sehr viele "Stammkunden" haben und ich das Verfahren etwas beschleunigen wollte haben ich noch zwei kleine Änderungen an den Postfix Einstellungen gemacht.
1. Absendende Mailserver werden ab der 5ten erfolgreichen Zustellung automatisch in eine White List aufgenommen
2. Die Wartezeit bis ein Mailserver erfolgreich zustellen darf habe ich auf 60 Sekunden runter gesetzt, versucht er es früher wird mit einem Temporären Fehler abgewiesen.

Hierzu erstellen wir eine config Datei
vi /etc/sysconfig/postgrey

und fügen folgenden Inhalt ein
OPTIONS="--unix=/var/spool/postfix/postgrey/socket --delay=60 --auto-whitelist-clients=5"  

back-to-topAMaVis
AMaVis ist eine Schnittstelle zwischen dem Mailserver und der Scansoftware, diese Software kann mit sehr vielen verschiedenen Virenscanner zusammenarbeiten und die Config Datei ist auch entsprechend vorbereitet man muss nur den entsprechenden Abschnitt aktiv setzen

Hier kann man noch das Temp Verzeichniss in eine RAM-Disk zur Beschleunigung legen.
https://www.kernel-error.de/postfix/amavis-tuning

yum install amavisd-new 

vi /etc/postfix/master.cf
Hier hängen wir am Schluss diesen abschnitt an.
# define amavis service for postfix
# maxproc column here must match the $max_servers in /etc/amavisd.conf
amavisfeed unix    -       -       n        -      4     lmtp
    -o lmtp_data_done_timeout=1200
    -o lmtp_send_xforward_command=yes
    -o disable_dns_lookups=yes
    -o max_use=20
 
# define a service to inject mail back into Postfix
127.0.0.1:10025 inet n    -       n       -       -     smtpd
    -o content_filter=
    -o smtpd_delay_reject=no
    -o smtpd_client_restrictions=permit_mynetworks,reject
    -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 smtpd_restriction_classes=
    -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,no_milters,no_address_mappings
    -o local_header_rewrite_clients=
    -o smtpd_milters=
    -o local_recipient_maps=
    -o relay_recipient_maps=


Jetzt müssen wir noch mit postconf ein kleine Anpassung erledigen
postconf -e "content_filter=amavisfeed:[127.0.0.1]:10024"  

Jetzt sendet Postfix Mails zum überprüfen an amavisd, da jedoch noch nicht definiert ist was und wie geprüft wird werden E-Mail im Betreff mit der kenn *Unchecked* gekennzeichnet.

back-to-topClamAV

yum install clamd clamav clamav-db

Die Virenpattern von ClamAV läst sich durch den Befehl freshclam aktualisieren, passiert aber nicht automatisch.
Unpraktisch deshalb erstellen wir einen CronJob der das für uns erledigt

vi /etc/cron.hourly/freshclam
#!/bin/sh
 ### A simple update script for the clamav virus database.
 
### fix log file if needed
LOG_FILE="/var/log/clamav/freshclam.log"  
if [ ! -f "$LOG_FILE" ]; then  
    touch "$LOG_FILE"  
    chmod 644 "$LOG_FILE"  
    chown clamav.clamav "$LOG_FILE"  
fi
 
/usr/bin/freshclam \
    --quiet \
    --datadir="/var/clamav" \  
    --log="$LOG_FILE" \  
    --daemon-notify="/etc/clamd.conf"  


#geben die Berechtigung das die Datei ausgeführt werden darf
chmod +x /etc/cron.hourly/freshclam
#starten AVClam
service clamd on
#Aktualisieren mal manuell
freshclam
#und sorgen dafür das der Dienst beim booten automatisch startet
chkconfig clamd on

vi /etc/amavisd.conf
# hier suchen wir den Abschnitt zu ClamAV und entfernen die # Zeichen

#und starten amavis neu
service amavisd restart
# und nehmen den ClamAV Benutzer in die AMAVIS Gruppe auf
usermod -a -G amavis clamav

back-to-topSpamassassin

ein Installation erübrigt sich hier da Spamassassin als Abhängigkeit zu amavis geladen wird. Es muss nur in amavis eingebunden werden. Dazu passen wir wieder die entsprechende Config Datei an.

vi /etc/amavisd.conf
Direkt über der Zeile "@av_scanners = (" fügen wir folgenden Code ein.
@bypass_spam_checks_maps = (
   \%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re);

Jetzt starten wir das ganze durch.
service spamassassin start
chkconfig spamassassin on
service amavisd restart

back-to-topExchange Anpassung
Bei unserem Exchange Server hinterlegen wir eine Transportregel die wenn in der Betreffzeile der Ausdruck *Spam* enthalten ist, die SCL Bewertung auf 9 gesetzt wird.
Damit Spam Mail's auch im Outlook Junkmail Ordner landen.

back-to-topAbschluss

Um die Funktion sicher zustellen kann man das ganze mit den Testfiles von EICAR überprüfen.
http://www.eicar.org/

Content-Key: 237956

Url: https://administrator.de/contentid/237956

Printed on: April 19, 2024 at 10:04 o'clock

Mitglied: 108012
108012 May 19, 2014 updated at 23:26:29 (UTC)
Goto Top
Hallo wiesi200,

gute Idee so etwas kann fast jeder gebrauchen, ob nun im
Betrieb oder zu Hause. Und man hat in der Regel immer
die selben Ansprüche.
- Squid als HTTP Proxy
- SuidGuard für den HTTP Content
- ClamAV für die Email AV-Scanns
- Spamassassin für den Spam
- HAVP für die HTTP AV-Scanns

Ich werde das das Ganze vermutlich noch in einer
zweiten Anleitung etwas ausbauen.
Ich würde alles in eine setzen wollen so kann man schön
Step by Step alles abtippen und auch besser nachvollziehen.
(Ist ja nur meine Meinung)

Aber toll gemacht nur weiter so.

HAVP + ClamAV


Gruß ♪
Dobby♬
Member: wiesi200
wiesi200 May 20, 2014 at 07:11:08 (UTC)
Goto Top
Danke,

hab auch noch ein paar Tipps von @lonesome Walker bekommen, werd das ganze noch etwas ausbauen.
Das mit dem Aufteilen war ein Grundgedanke das die Anleitung nicht zu lang wird und an Übersichtlichkeit verliert.
Aber ich glaub ich mach's jetzt wirklich in einer.