SMTP Dialog Restriktionen

Aus
Version vom 12. September 2010, 12:24 Uhr von Jahlives (Diskussion | Beiträge) (→‎Tipp)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)

About

Postfix, der SMTP Part der Mailstation, erlaubt es sehr detailliert auf allen Stufen des SMTP Dialogs Prüfungen anzulegen und darauf basierend Emails resp Clients abzulehnen. Dazu bietet Postfix in der Konfigurationsdatei /usr/syno/mailstation/etc/main.cf diverse Einstellungsmöglichkeiten und Prüfungen der verschiedenen SMTP "Stationen". Zusätzlich - und das macht Postfix so flexibel - wird die Möglichkeit geboten bei jeder Stufe des SMTP Dialogs userspezifische reguläre Ausdrücke zu verwenden und entsprechend deren Resultaten zu reagieren. Die Konfiguration von SMTP und den verschiedenen Stufen der Prüfung ist sehr umfangreich (gibt ganze Foren zu diesem Thema). Im folgenden möchte ich auch zwei sehr gute Beiträge zum Thema verweisen: Beitrag bei jimsun.linxnet.com (englisch) und eine gute deutsche Zusammenfassung bei chains.ch. Auch kann es nicht schaden sich den Ablauf des SMTP Dialogs nochmals vor Augen zu führen. Denn an diesem Ablauf orientiert sich die Reihenfolge der Prüfungen. So ist es z.B. schlecht wenn eine HELO Prüfung nach der Sender Adress Prüfung gesetzt wird, denn angekommen bei der Senderdirektive ist das HELO bereits Geschichte: Das heißt also die Reihenfolge der Direktiven und ihrer Optionen (zumindest im 2. Abschnitt) ist wichtig für ein korrektes Alaufen der Prüfungen

Sinn und Zweck

Viele werden sich fragen, warum man überhaupt so einen Aufwand betreiben sollte. Kurs und bündig: Verminderung von Spam. Wiederum könnte man fragen: Aber warum denn man kann ja spamassassin einfach mit Postfix koppeln und der Spam fliegt raus. Wiederum kurze Antwort: Verminderung der Serverlast. Was so offensichtlich Spam ist, dass es von den Postfix Regeln erkannt werden kann, sollte man dem Spamassassin gar nicht servieren. Neben dem Spamassassin wird so auch die Last auf dem Postfix vermindert. Denn die Emails werden so verworfen bevor auch nur eine Zeile in die Mailwarteschlange (und damit dem Dateisystem) geschrieben wurde. Ausserdem sind die regulären Ausdrücke von Postfix nicht so ressourcenhungrig wie diejenigen vom Spamassassin. Der SA kann u.U. tausende von regulären Ausdrücken habe und das geht auf die Zeit. Ich habe das bei mir zu Hause getestet (ein Postfix Port mit Spamassassin und einer ohne). Die Verarbeitung ohne Spamassassin war in dem Moment wo ich auf Senden geklickt habe bereits abgeschlossen und die Email in der Inbox. Beim Versand via SA Port kann das bis zu 2 Sekunden dauern, ehe die Email im Eingang ist

Beispiel aus der main.cf

Nachfolgend findet ihr die Konfiguration, so wie ich sie bei meinem Postfix Server einsetze. Das soll ganz klar nicht "die Lösung" sein, sondern einfach zeigen wie man es machen kann. Dazu habe ich die Konfiguration in drei Abschnitte eingeteilt und werde die nacheinander abarbeiten und kommentieren. Dabei ist wie obenerwähnt die Reihenfolge beim 2. Abschnitt sehr wichtig! smtpd_delay_reject = no
smtpd_helo_required = yes

smtpd_client_restritions = check_client_access regexp:/opt/etc/postfix/check_client, permit_mynetworks, reject_unknown_client, reject_rbl_client, reject_rhsbl_client
smtpd_helo_restrictions = check_helo_access regexp:/opt/etc/postfix/check_helo, permit_mynetworks,reject_unknown_hostname, reject_invalid_hostname, reject_non_fqdn_hostname
smtpd_sender_restrictions = reject_unknown_sender_domain, check_sender_access regexp:/opt/etc/postfix/sendermaps
smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_rbl_client pbl.spamhaus.org, reject_unauth_destination
smtpd_data_restrictions = reject_unauth_pipelining


body_checks = regexp:/opt/etc/postfix/body_check
mime_header_checks = regexp:/opt/etc/postfix/mime_check

1. Abschnitt

Hier setze ich zwei grundlegende Werte

  • smtpd_delay_reject = no/yes
    Legt fest wann Postfix bei einer Regelverletzung reagieren soll. NO heisst ohne Delay also sofort bei der Feststellung und YES erst am Ende, wenn wie Empfängeradresse im SMTP Dialog ebenfalls übermittelt wurde
  • smtpd_helo_required = yes/no
    Legt fest ob bei einer Verbindungsaufnahme durch den Client, das durch das RFC vorgeschriebene HELO resp EHLO Kommando verlangt wird oder eben nicht. Mailserver und Emailclients verwenden das immer, aber bei "Eigengewächsen" kann es sein, dass erwünschte Emails deswegen nicht ankommen. YES ist jedoch ein guter Wert, weil auch viele Spambots schlampig programmiert sind und das HELO häufig unterlassen

2. Abschnitt

Hier kommen also die entscheidenen Anweisungen für den Postfix und wie bereits erwähnt ist die Reihenfolge wichtig. Neben Standartchecks (z.B. reject_unknown_sender_domain) sieht man mehrere Anweisungen die ein regexp:/ beinhalten. Dabei handelt es sich um Files mit regulären Ausdrücken, die Postfix beim SMTP Dialog ebenfalls verwenden soll.

Wichtig ist es im Hinterkopf zu behalten, dass die einzelnen Direktiven von oben nach unten und die Optionen der Direktiven von links nach rechts ausgeführt und geprüft werden. Dabei wird eine Prüfung einen der drei Stati (OK, REJECT oder DUNNO) zurückgeben. Ein OK oder REJECT bricht die Prüfung der ganzen Direktive ab. Ein DUNNO ist wie NULL und bei einem solchen Wert wird die Direktive nicht abgebrochen sondern die nächste Option geprüft.

Ein OK führt zur nächsten Direktive und ein REJECT je nach Konfiguration von smtpd_delay_reject auch. Denn ist dieser Wert auf YES dann kommt auch bei REJECT die nächste Direktive dran. Aber auch wenn die dann ein OK zurückgibt wird die Email nach Erhalt der Empfänger Adresse in JEDEM Fall abgelehnt werden (einmal REJECT immer REJECT). Wenn der Wert in der Config NO ist, dann wird sofort und ohne Prüfung der nächsten Direktive die Verbindung zum Client mit einer Fehlermeldung gekappt (natürlich nur wenn eine Option einer Direktive ein REJECT zurückgegeben hat)


  • smtpd_client_restrictions
    Bevor der Server überhaupt einen SMTP Dialog für den Client öffnet wird diese Direktive ausgeführt. Dabei werden Prüfungen auf IP Basis des Clients ausgeführt (der Hostname kommt erst im HELO zum Zug)
    Zuerst lege ich über ein userspezifisches File einen oder mehrere reguläre Ausdrücke fest, bei denen der weitere Zugriff verboten wird. Hier kann man IP Adressen von bekannten Spammern einbauen
      /^.213\.76\.24\.12$/  REJECT  You're not allowed to connect to this system!
      

Dann erlaube ich Clients aus dem gleichen Netzwerk grundsätzlich den Zugriff (permit_mynetworks). Diese Konfig erlaubt allen IPs aus dem gleichen Subnetz (siehe mynetworks-Konfig Variable in main.cf) den Zugriff. Wenn der Server direkt im Inet hängt (ohne Router mit NAT) dann sollte diese Variable sehr genau definiert werden. Für ein LAN ist es jedoch okay dem Subnetz den Zugriff zu gewähren.
Dann werden ungültige Clients verworfen (ungültige IP Adressen) und dann erfolgt eine Prüfung ob die Client IP in einer Blacklist steht

  • smtpd_helo_restrictions
    Dies ist die erste Stufe des SMTP Dialogs (der Server hat den Client grundsätzlich aktzeptiert)
    Wiederum prüfe ich zuerst mit einem RegExp File auf bekannte Spammer. Diesmal aber auf Domainnamen, da eigentlich im HELO Kommando der Hostname des sendenden Systems angegeben werden sollte
      /^.*mymainserver.com$/  REJECT  You're not allowed to connect to this system!
      

Alles was von mymainserver.com kommt wird gleich verweigert
Dann wiederum erlaube ich lokalen Clients den Zugriff.
Danach kommt eine Prüfung ob der Hostname vorhanden ist, wenn nein und tschüss
Dann eine Prüfung auf ungültige Hostnamen und darauf dass ein FQDN (fully qualified domain name) verwendet wurde

  • smtpd_sender_restrictions
    Hier kann man eigentlich nicht furchtbar viel prüfen.
    Ich prüfe hier auf gültige Domainnamen. Also solche die einen DNS Record besitzen.
    Mittels eines reguläres Ausdrucks in einem File mache ich dann weitere Prüfungen auf den Sender
      if /^.*MY_DYNDNS_NAME\.MY_DYNDNS_DOMAIN\.net/
      !/^(user1|postmaster|root)@MY_DYNDNS_NAME\.MY_DYNDNS_DOMAIN\.net$/ 550 Forbidden Sender
      endif
      /(.*\.cn|.*\.sg|.*\.co|.*\.tw)$/ 550 Forbidden Top Level Domain
      /@MyMainServer.com/ 550 Go Home, Jerk!
      

Für eine Emailadresse, die vorgibt vom meinem Server zu sein prüfe ich ob die Accounts lokal existieren und wenn nicht dann tschüss
Zusätzlich prüfe ich auf verbotene TLDs bei Absender Adressen

  • smtpd_recipient_restrictions
    Das ist eine sehr wichtige Konfigurationsvariable. Ein Fehler hier und euer System wird zum offenen Relay Server.
    Zuerst wird einem Client dessen User sich mit einem lokalen Account anmelden konnte, der Zugriff (auch auf den Relay) erlaubt.
    Dann das gleiche für Clients aus meinem Subnet.
    Nun kommt eine Prüfung der Adresse mittels einer Blacklist.
    Die letzte Anweisung sollte immer reject_unauth_destination lauten. Damit erlaubt der Postfix eine Email nur dann wenn der Account lokal existiert (natürlich nur wenn davor kein permit die Prüfung bereits abgebrochen hat). Setzt ihr die Var nicht, dann kann ein Sender, der beide permits nicht erfüllt, dessen Empfangsadresse aber auch nicht auf einer Blacklist steht JEDE Email Adresse als Empfänger angeben und der Server wird nicht-lokale Emails via Relay zustellen (offener Relay Server). Das bringt Euch dann, sobald ein Spammer das bemerkt hat, ganz schnell auf die schwarzen Listen der Provider.

    Anbei ein Ausschnitt aus dem SMTP Dialog meines Postfix mit einem Spammer von heute
      Transcript of session follows.
       Out: 220 MY_DNS_HOST ESMTP Postfix
           (2.5.5)
       In:  HELO mailer
       Out: 250 MY_DNS_HOST
       In:  MAIL FROM:<john34@gmail.com>
       Out: 250 2.1.0 Ok
       In:  RCPT TO:<donald.presario@maximumlist.com>
       Out: 554 5.7.1 Service unavailable; Client host [117.66.194.98] blocked using
           pbl.spamhaus.org; http://www.spamhaus.org/query/bl?ip=117.66.194.98

In diesem Beispiel hat also die Blacklist Regel in recepient_restrictions zugeschlagen. Dies zeigt schön, dass die Optionen von links nach rechts abgearbeitet werden. Hätte der Client nicht auf der Backlist gestanden, dann hätte das reject_unauth_destination diese Email verworfen. Ohne diesen reject würde die Email ausgeliefert!!

Ein ganz aufmerksamer Leser könnte jetzt rufen: "Hei deine Config scheint nicht zu funzen, sonst hätte obige Email bereits beim HELO Check verworfen werden müssen. Kein FQDN als Name!" So ist es mir zumindest ergangen als ich dieses Beispiel eingefügt habe. Aber nur Beruhigung ich habe den HELO check bei mir auskommentiert, da ich mal ein bissl mehr Spam kriegen möchte, um die regulären Ausdrücke zu verfeinern

  • smtpd_data_restrictions
    Viele Spambot Schreiber ersparen sich die Mühe den SMTP Dialog ihrer Bots korrekt gemäss RFC zu implementieren oder reagieren/warten nicht korrekt auf Anworten des Servers. Häufig gesehen bei Spambots ist es, dass sie bereits direkt nach dem DATA Client Kommando mit der Datenübertragung anfangen wollten, bevor der Server sein "okay to send data" (unauthorized pipelining) schicken konnte. Solche Clients können bedenkenlos knallhart abgewürgt werden.

Die letzte Direktive muss man ein bisschen abgetrennt von den anderen beachten (man könnte sie auch in den 3. Abschnitt verfachten). Denn bei allen bis auf die letzte Direktive weiß der Client oder Spammer nicht ob die Empfangsadresse überhaupt existiert resp. akzeptiert wurde. Meist probieren Spammer bei einer Domain mehrere Emailadressen aus, bis sie eine finden die aktzeptiert wird. Bei einer Fehlermeldung bei der letzten Direktive weiss der Client oder Spammer aber bereits, dass die Adresse akzeptiert wurde. Und kann eine erneute Zustellung mit einem besseren Benehmen versuchen.

3. Abschnitt

Wie bereits oben erwähnt weiß der Client oder Spammer zu diesem Zeitpunkt bereits, dass die Emailadresse okay ist. Trotzdem ist Postfix noch in der Lage vor dem finalen "Message Accepted" auf den Inhalt der Email zu reagieren und den Empfang ggf zurückzuweisen. Dazu werden 3 Direktiven verwendet, wovon ich selber aber nur zwei benutze. Erwähnen möchte ich trotzdem alle drei

  • header_checks (in meinem Bsp nicht vorhanden)
    Hier habt ihr die Möglichkeit die Header Daten einer Email mit regulären Ausdrücken zu filtern (ja die Header einer Email gehören zu DATA)
      /^Subject:.*(viagra|casino).*/ REJECT I newer win something and already got a huge one, so piss off
      

In dem Moment wo eine Betreffzeile mit viagra oder casino daherkommt, macht der Server mit der Meldung hinter REJECT dicht. Dies noch bevor der Client auch nur eine weitere Zeile schicken konnte

  • mime_header_checks
    Dieses File ist dafür zuständig die einzelnen MIME Teile einer Email, die Attachments also anzuzeigen. Auch ein Plain Text ist ein Attachment in diesem Sinne, er wird einfach inline angezeigt.
      /name=[^>]*\.(lnk|asd|hlp|ocx|reg|bat|c[ho]m|cmd|exe|dll|vxd|pif|scr|hta|jse?|sh[mbs]|vb[esx]|ws[fh]|wmf)/ REJECT A part of this email contains a MIME type which is not allowed on this server
      

Obiger regulärer Ausdruck wird die einzelnen MIME Bestandteile durchsuchen und bei angegebenen Fileextensions blockieren. Dabei werden nur die Header Daten eines MIME Bestandteils durchsucht (jau die Header eines Email Bestandteils gehören in den Body der Email und nicht in den globalen Headerereich)

  • body_checks
    Hier geht es jetzt um den Inhalt der einzelnen MIME Bestandteile (man kann zwar auch hier auf die Header des Bestandteils zugreifen, ist jedoch in der mime_header_checks besser aufgehoben
      /.*(<a.*href=|http:\/\/|ftp:\/\/|mailto:).*(\.cn|\.sg|\.tw).*/ REJECT Found forbidden TLD in a link in body of this email!
      

Obiger RegExp such nach Links mit verbotenen TLDs. Das sind in diesem Beispiel nicht nur HTML Links sondern auch Text Links, die mit http://,ftp:// oder mailto: anfangen.
Auch hier wird wiederum noch während dem Empfang die Verbindung gekappt und der Client fliegt mit de hinter REJECT angegebenen Meldung raus

Tipp

Wenn ihr nicht riskieren wollt, dass alle Eure manuellen Änderungen an der main.cf eim nächsten Update der FW wieder weg sind, empfehle ich folgenden Weg

  1. /usr/syno/mailastation/etc/main.cf in ein Verzeichnis unter /volume1/ kopieren
  2. main.cf unter /usr/syno/mailstation/etc editieren und ziemlich weit oben folgenden Eintrag einfügen
alternate_config_directories = /opt/etc/postfix

dann könnt ihr die main.cf unter dem angegebenen Pfad nach Herzenslust bearbeiten und habt immer eine funktionierende Ursprungsversion im Default Verzeichnis. Nach einem FW Update müsst ihr einzig obige Zeile wieder in die Haupt-Konfig eintragen und den Postfix neustarten. Kopiert auch gleich die master.cf in das Verzeichnis auf /volume1 und legt alle RexExp Files ebenfalls unter diesem neuen Pfad an.

So ist der Aufwand den Postfix nach einem Firmware Update wieder einzurichten minimal.