Postfix mit MySQL-Support unter Debian

- webserver
Guten Morgen,
seit zwei Stunden verzweifle ich nun schon schier daran, Postfix als MTA mit MySQL-Support aufzusetzen.
Zuerst habe ich auf meinem Debian-System mit apt-get die Packete mysql-server-4.1, mysql-client-4.1, postfix und postfix-mysql installiert. Nach langem rumprobieren und unendlichen Fehlern habe ich den Verdacht bekommen, dass die Kombination von Packeten nicht möglich ist.
Das Packet postfix-mysql basiert auf libmysqlclient10, was für meinen Augen der Client für MySQL 3.x ist. Ich hatte jedoch MySQL 4.1 installiert. Ein Downgrade auf 3.x oder auch "nur" auf 4.0 kommt für mich wegen fehlender Funktionen auf keinenfall in Frage.
Nun habe ich weitergeschaut und den testing-Zweig von Debian mal etwas genauer unter die Lupe genommen. Dort habe ich dann mysql-server in der Version 5.0 gefunden, sowie postfix-mysql basierend auf libmysqlclient15off - was für meine Augen der MySQL-Client für Version 5.0 ist. Also habe ich diese Packete aus dem testing-Zweig installiert.
Der entscheidende Abschnitt meiner main.cf sieht so aus:
virtual_mailbox_maps = mysql:/etc/postfix/mysql-acc/virtboxes
virtual_maps = mysql:/etc/postfix/mysql-acc/virtual
transport_maps = mysql:/etc/postfix/mysql-acc/transport
virtual_mailbox_base = /var/spool/virtboxes
virtual_uid_maps = mysql:/etc/postfix/mysql-acc/uid
virtual_gid_maps = mysql:/etc/postfix/mysql-acc/gid
virtual_minimum_uid = 500
Die Dateien für den MySQL Zugriff sehen allesamt so aus (natürlich mit unterschiedlichen Tabellen- und Spaltennamen):
user=mailer
password=abc
dbname=system
table=mail_transport
select_field=transport
where_field=domain
hosts=localhost
Der User mailer existiert und das gesetzte Passwort ist korrekt, wie mir ein Login über mysql -u mailer -p
gezeigt hat.
Nun bin ich auf einen anderen Server (bei einem anderen Provider) gegangen, und habe folgendes probiert (bevor ich MySQL integriert habe hat das geklappt, ich konnte erfolgreich eine Mail versenden):
driehle@v-10040 ~ $ telnet 0.0.0.0 25
Trying 0.0.0.0...
Connected to 0.0.0.0.
Escape character is '^]'.
220 meinserver.example.org ESMTP
helo meinserver.example.org
250 meinserver.example.org
mail from: email@another.example.com
An dieser Stelle hängt sich die Verbindung auf - Postfix antwortet nichts mehr und spammt dafür /var/log/mail.log voll:
Sep 11 05:42:20 localhost postfix/smtpd[19015]:
connect from v-10040[...]
Sep 11 05:42:36 localhost postfix/trivial-rewrite[18875]: warning:
connect to mysql server localhost: Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
Sep 11 05:42:36 localhost postfix/trivial-rewrite[18875]: fatal:
mysql:/etc/postfix/mysql-acc/virtual(0,100): table lookup problem
Sep 11 05:42:37 localhost postfix/smtpd[19015]: warning:
premature end-of-input on private/rewrite socket while reading input attribute name
Sep 11 05:42:37 localhost postfix/smtpd[19015]: warning:
problem talking to service rewrite: Success
Sep 11 05:42:37 localhost postfix/master[18871]: warning:
process /usr/lib/postfix/trivial-rewrite pid 18875 exit status 1
[... hier wiederholen sich die Meldungen teilweise ...]
Sep 11 05:42:39 localhost postfix/master[18871]: warning:
/usr/lib/postfix/trivial-rewrite: bad command startup -- throttling
Mein Problem ist, dass ich nicht so genau weiß, was ich falsch mache - es handelt sich hierbei um mein erstes Postfix, dass ich aufsetze. Ich gehe hierbei ziemlich strikt nach der Anleitung aus dem Buch "Dezidierte Webserver - einrichten und administrieren" von Michael Hilscher vor.
Die eigentliche Einrichtung hat ja auch schon geklappt, der Server hat funktioniert, sämtliche Versuche meinerseits ihn als Spam-Relay zu benutzen sind erfolgreich gescheitert. Aber ich will für meine Userverwaltung eben die E-Mail Accounts über MySQL verwalten und benötige deshalb einen MySQL-Support in Postfix.
Liegt es einfach nur daran, dass irgendwo ein Versions-Konflikt vorliegt? Kann ich das Problem lösen indem ich mir die Mühe machen Postfix selber zu kompilieren?
Ich werde auch nicht ganz schlau aus der Fehlernummer 2 - ich konnte über Google irgendwie keine Beschreibung finden, was denn nun Fehler 2 bedeutet. Den grundsätzlichen Tipps des MySQL-Handbuches zu diesem Fehler bin ich nachgegangen, der Server läuft auch:
18280 pts/0 00:00:00 mysqld_safe
18341 pts/0 00:00:00 mysqld
Allerdings macht mich das pts/0 etwas stutzig... Gestartet habe ich ihn über /etc/init.d/mysql start
.
Viele Grüße aus Kanada,
~ Dennis.
echo $begrüßung;
Das Packet postfix-mysql basiert auf libmysqlclient10, was für meinen Augen der Client für MySQL 3.x ist. Ich hatte jedoch MySQL 4.1 installiert.
Das macht erstmal grundsätzlich gar nichts. Die Client-API-Version muss nicht unbedingt die gleiche Versionsnummer wie der Server haben. Es gibt nur ein Problem beim Übergang von der Server-Version 4.0 auf 4.1 und das ist das geänderte Passwort-Format, wofür es aber eine Lösung gibt: Client does not support authentication protocol.
Doch das scheint nicht das Problem zu sein.
Sep 11 05:42:36 localhost postfix/trivial-rewrite[18875]: warning:
connect to mysql server localhost: Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
Diese Meldung sieht mir nach einem Fehlerzustand noch vor dem Passwort-Austausch aus. Der Rest sind Folgefehler. Dazu fällt mir nicht wirklich mehr ein als Can't connect to [local] MySQL server.
Probier doch mal statt localhost den vollen Servernamen zu verwenden. Dann versucht der Client eine Verbindung über TCP/IP statt über eine Unix-Socket-Verbindung.
echo "$verabschiedung $name";
Hi dedlfix,
Das macht erstmal grundsätzlich gar nichts. Die Client-API-Version muss nicht unbedingt die gleiche Versionsnummer wie der Server haben.
Achso - ok, dessen war ich mir nicht bewusst.
Probier doch mal statt localhost den vollen Servernamen zu verwenden. Dann versucht der Client eine Verbindung über TCP/IP statt über eine Unix-Socket-Verbindung.
Ich habe jetzt in Postfix sämtlich hosts=localhost Zeilen durch hosts=127.0.0.1 ersetzt - und siehe da, es funktioniert! Ich kann mir zwar nicht erklären warum, aber es funktioniert! :-)
driehle@v-10040 ~ $ telnet 0.0.0.0 25
Trying 0.0.0.0...
Connected to 0.0.0.0.
Escape character is '^]'.
220 mail.example.com ESMTP
helo mail.example.com
250 mail.example.com
mail from: anywhere@any.example.org
250 Ok
rcpt to: spam@web.de
554 spam@web.de: Recipient address rejected: Relay access denied
rcpt to: webmaster@dennisriehle.de
250 Ok
quit
221 Bye
Connection closed by foreign host.
Jetzt muss ich zwar noch gucken, wo die Mail letztendlich gelandet ist, aber die Kommunikation mit Postfix zu MySQL klappt nun wie es aussieht einwandfrei. Danke dedlfix!
MfG, Dennis.
Hi again,
Jetzt muss ich zwar noch gucken, wo die Mail letztendlich gelandet ist, aber die Kommunikation mit Postfix zu MySQL klappt nun wie es aussieht einwandfrei.
Das keine Mail ankam lag natürlich nur daran, dass ich kein data mit übergeben hatte - aber daran hatte ich heute morgen nicht gedacht. Jetzt kann ich mich also daran machen, Courier-IMAP aufzusetzen - bin mal gespannt wie mehr oder weniger glatt das verläuft ;-)
MfG, Dennis.
Hi noch einmal,
Mein Postfix Server läuft jetzt und ich bin eigentlich auch ganz zufrieden - trotzdem bin ich mir natürlich nicht ganz sicher, ob ich alles korrekt konfiguriert habe und ob man meinen Mailserver nicht doch noch für Spam mißbrauchen könnte. Aus diesem Grund würde ich mich darüber freuen, wenn mal jemand über die wichtigsten Teile meiner Konfiguration drüberfliegt:
myhostname = mailserver.example.com
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = $myhostname
mydestination = mailserver.example.com, localhost.localdomain, localhost.localdomain, localhost
relayhost =
relay_domains = $mydestination, mysql:/etc/postfix/mysql-acc/transport
smtpd_helo_restrictions = reject_invalid_hostname, reject_non_fqdn_hostname
smtpd_recipient_restrictions = reject_unknown_hostname, reject_unknown_sender_domain, reject_non_fqdn_sender, check_relay_domains
mynetworks = 127.0.0.1
mailbox_command = procmail -a "$EXTENSION"
mailbox_size_limit = 0
recipient_delimiter =
inet_interfaces = all
[... hier der bereits gepostete Block für MySQL-Zugriff ...]
qmgr_fudge_factor = 70
qmgr_site_hog_factor = 40
qmgr_message_active_limit = 3000
Derzeit ist es so, dass wenn man eine Nachricht an eine E-Mail Adresse einer Domain schickt die NICHT in der Transport-Tabelle eingetragen ist, man ein relay access denied erhält - so sollte es ja auch sein. Schickt man eine E-Mail an eine nicht existierende E-Mail Adresse einer Domain die in der Transport-Tabelle eingetragen ist, erhält man eine Bounce Nachricht. Das gefällt mir nicht so gut - kann man das nicht auch irgendwie so einstellen, dass die Mail direkt abgelehnt wird?
Ich dachte, dies ginge mit
smtpd_recipient_restrictions reject_unlisted_recipient
allerdings scheint diese Prüfung auf die mail from Adresse zu wirken und es werden E-Mails abgelehnt, deren mail from Adresse nicht in der Transport-Tabelle eingetragen ist.
MfG, Dennis.
Moin!
Aus diesem Grund würde ich mich darüber freuen, wenn mal jemand über die wichtigsten Teile meiner Konfiguration drüberfliegt:
Ist definitiv verbesserungsfähig. Ob auch -würdig, mußt du selbst entscheiden.
relay_domains = $mydestination, mysql:/etc/postfix/mysql-acc/transport
Brauchst du wirklich Relay-Domains?
smtpd_helo_restrictions = reject_invalid_hostname, reject_non_fqdn_hostname
smtpd_recipient_restrictions = reject_unknown_hostname, reject_unknown_sender_domain, reject_non_fqdn_sender, check_relay_domains
Alle Restrictions sollten unter smtpd_recipient_restrictions zusammengelegt werden. Postfix sollte sowieso erst dann prüfen, ob die Bedingungen eingehalten sind, wenn der SMTP-Dialog vor dem Versand der Mailinhalte steht.
Und was die tatsächlichen Restrictions angeht, kannst du noch deutlich kräftiger rangehen. Die Konfig auf selfhtml.org ist beispielsweise (zusammengestückelt aus vielen anderen Konfigurationen, die man bei der Suche nach Spambekämpfung so findet):
smtpd_client_restrictions =
smtpd_helo_restrictions =
smtpd_sender_restrictions =
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_invalid_hostname,
reject_unknown_hostname,
reject_non_fqdn_hostname,
reject_non_fqdn_sender,
reject_unknown_sender_domain,
reject_non_fqdn_recipient,
reject_unauth_destination,
reject_unauth_pipelining,
check_helo_access pcre:/etc/postfix/helo_access,
check_sender_access pcre:/etc/postfix/sender_access,
check_recipient_access pcre:/etc/postfix/recipient_checks.pcre,
check_policy_service unix:private/postgrey,
check_recipient_access hash:/etc/postfix/spamfilter-lookup
Die wichtigste Zeile für dich, um das Bouncen abzustellen, dürfte reject_unauth_destination sein.
Die restlichen Begriffe solltest du alle mal recherchieren (Handbuch, Google) und entscheiden, ob sie für dich von Bedeutung sein könnten. Denn beispielsweise bei
mynetworks = 127.0.0.1
ist ein permit_mynetworks relativ schwachsinnig, ein permit_sasl_authenticated hingegen ist heutzutage überlebensnotwendig, wenn man die Maildienste im Internet anbietet.
- Sven Rautenberg
Hi Sven,
relay_domains = $mydestination, mysql:/etc/postfix/mysql-acc/transport
Brauchst du wirklich Relay-Domains?
Der Server soll für unterschiedliche Domains E-Mails in Empfang nehmen - die Angaben aus meinem schlauen Buch dazu habe ich so verstanden, dass relay_domains die Angabe dafür ist, was der Server alles anehmen soll - genauso habe ich das hier verstanden.
Dabei soll die Konfiguration, für welche Domains Postfix jetzt zuständig ist, und für welche Domains ausschließlich er E-Mails annehmen soll aus einer MySQL-Datenbank kommen - gehört diese Angabe vielleicht eher unter mydestination? Kann man bei mydestination die Daten aus der MySQL-Datenbank holen?
Alle Restrictions sollten unter smtpd_recipient_restrictions zusammengelegt werden. Postfix sollte sowieso erst dann prüfen, ob die Bedingungen eingehalten sind, wenn der SMTP-Dialog vor dem Versand der Mailinhalte steht.
Warum alles unter recipient zusammenfasen? Zumal Postfix die Fehler durch stmpd_delay_reject eh erst nach dem Erhalt von rcpt to zurückweist...
Und was die tatsächlichen Restrictions angeht, kannst du noch deutlich kräftiger rangehen.
Das habe ich fast schon befürchtet ;-) Vielen Dank für die Beispielkonfiguration - ich werde diese mal durcharbeiten und entsprechend bei mir einbauen. Diese beiden Zeilen sehen mir stark nach einer entsprechenden Grey-/Blacklist aus:
check_policy_service unix:private/postgrey,
check_recipient_access hash:/etc/postfix/spamfilter-lookup
So etwas habe ich derzeit aber noch nicht implementiert - da muss ich mal schauen, was ich da noch mache. Ich hätte soweiso gerne, dass sich diese Features Postfach-individuell aktivieren oder deaktivieren lassen...
MfG, Dennis.
Moin!
Brauchst du wirklich Relay-Domains?
Der Server soll für unterschiedliche Domains E-Mails in Empfang nehmen - die Angaben aus meinem schlauen Buch dazu habe ich so verstanden, dass relay_domains die Angabe dafür ist, was der Server alles anehmen soll - genauso habe ich das hier verstanden.
Naja, die Doku sagt: "What destination domains (and subdomains thereof) this system will relay mail to."
"will relay mail to." Also Weiterleitung mit diesem Mailserver als Zwischenstation. Mag vielleicht auf das gleiche hinauslaufen, hat aber die Absicht, die Mails auch wieder per SMTP loszuwerden.
Schlauer scheint mir mydestination. "The list of domains that are delivered via the $local_transport mail delivery transport."
Kann man bei mydestination die Daten aus der MySQL-Datenbank holen?
Klar kann man.
Alle Restrictions sollten unter smtpd_recipient_restrictions zusammengelegt werden. Postfix sollte sowieso erst dann prüfen, ob die Bedingungen eingehalten sind, wenn der SMTP-Dialog vor dem Versand der Mailinhalte steht.
Warum alles unter recipient zusammenfasen?
Weil die Wirkungsweise der Filter dann, wenn es aufgeteilt ist, unübersichtlicher wird, und u.U. dadurch unerwünschte Nebenwirkungen auftreten.
Postfix prüft nacheinander die Bedingungen der Gruppen smtpd_client_restrictions, *_helo_*, *_sender_*, *_recipient_* (und *_data_*, header_checks, body_checks als Inhaltskontrolle - die anzuwenden solltest du allerdings nach Möglichkeit vermeiden, weil das bedeutet, dass der Spam empfangen werden muß, um ihn zu prüfen).
Tritt in einer der Bedingungsgruppen eine Ablehnung auf (REJECT), wird der Test der weiteren Bedingungen abgebrochen, und die Mail abgelehnt. Tritt in einer der Bedingungen eine Akzeptanz (OK) auf, der der Test der weiteren Bedingungen dieser Gruppe abgebrochen, und mit der nächsten Gruppe weitergemacht.
Dadurch kann es passieren, dass du zwar weiter vorne in der Prüfungskette den Empfang erlaubst, dir aber in einer späteren Gruppe der Mailempfang trotzdem verweigert wird, weil eine ganz andere Bedingung es zufällig verbietet.
Steckst du alle Bedingungen in nur eine einzige (schlauerweise eben die letzte) Gruppe, wird in dieser schön der Reihenfolge nach alles geprüft. Und wenn ein Text OK ergibt, dann ist das wirklich endgültig OK und führt zum Empfang.
Natürlich gibt es Szenarien und Filterkonfigurationen, die eine Aufteilung auf verschiedene Gruppen erfordern. Aber sowas setzt du besser erst ein, wenn du weißt, was in Postfix intern abläuft. :)
Zumal: Man kann Spam eben auch filtern, wenn man sowas nicht einsetzt.
Zumal Postfix die Fehler durch stmpd_delay_reject eh erst nach dem Erhalt von rcpt to zurückweist...
Das ist zwar richtig, aber eben nur ein Randdetail.
Diese beiden Zeilen sehen mir stark nach einer entsprechenden Grey-/Blacklist aus:
check_policy_service unix:private/postgrey,
Greylisting erkennst du korrekt. Dazu gibts diverse Policy-Daemons, dieser hier ist der bei Gentoo verfügbare "mail-filter/postgrey" (erhältlich unter http://isg.ee.ethz.ch/tools/postgrey/).
Greylisting ist eine der zwei erfolgreichsten Waffen gegen blöden Spam. Die andere Waffe ist eine strenge Prüfung der Angabe HELO.
Intelligenteren Spam kriegt man leider so einfach nicht weg, da benötigt man dann schon etwas härtere Dinge wie Blacklisten etc. Weil dafür meist echte Mailserver eingesetzt werden, die Greylisting einfach durch erneuten Versand überwinden, und logischerweise auch sinnvolle HELO-Angaben machen.
check_recipient_access hash:/etc/postfix/spamfilter-lookup
Das ist der benutzerabhängige Teil weiterer Filterungen. Da habe ich vier unterschiedlich harte Filter definiert, die abhängig von der Zieladresse noch zusätzlich zum Einsatz kommen. Mal auszugsweise (die anderen Klassen schalten ein oder mehrere Zeilen inaktiv durch Vorsetzen von "warn_if_reject"):
smtpd_restriction_classes = sammeladdr, userlevel3, userlevel2, userlevel1
sammeladdr = check_client_access hash:/etc/postfix/ip-domain-whitelist,
check_policy_service unix:private/spf2policy,
reject_rbl_client relays.ordb.org,
reject_rbl_client sbl-xbl.spamhaus.org,
check_client_access hash:/etc/postfix/ip-domain-blacklist,
check_sender_access hash:/etc/postfix/mailfrom-blacklist,
check_sender_access hash:/etc/postfix/sammeladdr-blacklist
So etwas habe ich derzeit aber noch nicht implementiert - da muss ich mal schauen, was ich da noch mache. Ich hätte soweiso gerne, dass sich diese Features Postfach-individuell aktivieren oder deaktivieren lassen...
Da du den Lookup, welche der definierten Filterklassen eingesetzt werden soll, auch aus einer Datenbank auslesen kannst, sollte das kein großes Problem sein. Bei mir steht die Angabe in einer schlichten Postfix-Hashdatei, weil ich seinerzeit das nicht ins LDAP integrieren wollte. Und so häufig ändert sich das auch nicht.
- Sven Rautenberg
Moin!
Schlauer scheint mir mydestination. "The list of domains that are delivered via the $local_transport mail delivery transport."
Noch wahrscheinlicher aber ist, dass du virtuelle Domains haben willst. Da ist Postfix etwas aufwendiger zu konfigurieren. Man kann sehr leicht die Namespaces der Maildomains kombinieren (mail1@example.com und mail1@example.org gehen in die gleiche Mailbox) - die Trennung und insbesondere der Betrieb als POP-Toaster ist ein klein wenig aufwendiger zu konfigurieren, aber wenn das erst mal läuft, hat man das Problem nie wieder.
- Sven Rautenberg
Hi Sven,
Noch wahrscheinlicher aber ist, dass du virtuelle Domains haben willst. Da ist Postfix etwas aufwendiger zu konfigurieren. Man kann sehr leicht die Namespaces der Maildomains kombinieren (mail1@example.com und mail1@example.org gehen in die gleiche Mailbox) - die Trennung und insbesondere der Betrieb als POP-Toaster ist ein klein wenig aufwendiger zu konfigurieren, aber wenn das erst mal läuft, hat man das Problem nie wieder.
Na ja - als aufwendig würde ich das jetzt nicht bezeichnen ;-) Ich habe (seltsamerweise? *g*) auf Anhieb das gemacht, was ich wollte und jetzt erst im Nachinein noch das von dir beschriebene Konzept der shared_domains gefunden, meine Konfiguration, welche diesem Beispiel der virtual domains folgt, funktioniert gut einwandfrei :-)
So siehts aus:
# virtual maildomains and mailboxes
virtual_mailbox_domains = mysql:/etc/postfix/virtual/domains
virtual_mailbox_maps = mysql:/etc/postfix/virtual/boxes
virtual_alias_maps = mysql:/etc/postfix/virtual/aliases
virtual_mailbox_base = /var/spool/virtboxes
virtual_uid_maps = mysql:/etc/postfix/virtual/uid
virtual_gid_maps = mysql:/etc/postfix/virtual/gid
virtual_minimum_uid = 500
Dabei existieren nun drei MySQL Tabellen:
mail_domains: domain, transport
Jede Domain habe ich hier unter domain eingetragen,
für Transport steht überall "virtual:"
mail_aliases: old, new
Wie meine Tests bestätigen funktioniert es einwandfrei,
wenn ich hier bei old eine vollständige Adresse eingebe,
dass diese auf die vollständige Adresse bei new
umgeleitet wird.
mail_boxes: address, dir, uid, gid, password
Die vollständige E-Mail Adresse steht in address, dir ist
der Speicherpfad als Ergänzung zu virtual_mailbox_base.
UID und GID sind dann noch die Benutzerangaben, und das
Feld password ist für Curier-PO3/IMAP.
Courier läuft nun auch schon prima, mein Buch meinte, der Pfad zu den Mailboxen (virtual_mailbox_base in Postfix) ließe sich in Courier in der Konfiguration nicht fest angeben und riet dazu den Pfad für jeden Datensatz mit in der Datenbank zu speichern - das ist falsch! Es geht, und zwar so:
MYSQL_HOME_FIELD "/var/spool/virtboxes"
Einfach also Zeile in der Courier Konfigurations-Datei, welche auch die restlichen MYSQL_* Konfigurationen enthält.
Viele Grüße aus Kanada,
~ Dennis.
Hi Sven,
Mag vielleicht auf das gleiche hinauslaufen, hat aber die Absicht, die Mails auch wieder per SMTP loszuwerden.
Ok, das ist mir mittlerweile klar geworden ;-) Du sprachst mydestination an - ich hab die Doku mal etwas auf den Kopf gestellt und das hier gefunden:
"NEVER list a virtual MAILBOX domain name as a mydestination domain!"
Leider steht keine Begründung dabei, stattdessen benutzen die jedoch virtual_mailbox_domains, sodass ich meine Konfiguration nun so angepasst habe:
mydestination = $myhostname, localhost.localdomain, localhost
relayhost =
relay_domains =
virtual_mailbox_domains = mysql:/etc/postfix/mysql-acc/transport
Die mit mysql-acc/transport angesprochene Tabelle sieht so aus:
domain | transport
-------------+-----------
example.com | virtual:
example.org | virtual:
Soweit ich weiß, ist die zweite Spalte allerdings nur ein Platzhalter...
Steckst du alle Bedingungen in nur eine einzige (schlauerweise eben die letzte) Gruppe, wird in dieser schön der Reihenfolge nach alles geprüft. Und wenn ein Text OK ergibt, dann ist das wirklich endgültig OK und führt zum Empfang.
OK - vielen Dank für die ausführliche Erklärung :-) Das erscheint mir sinnvoll.
Greylisting ist eine der zwei erfolgreichsten Waffen gegen blöden Spam. Die andere Waffe ist eine strenge Prüfung der Angabe HELO.
Ich habe mir gerade mal Greylisting in Wikipedia durchgelesen, ich werde demnächst sicherlich mal versuchen dieses Greylisting zu implementieren.
Wie funktioniert die strengere Prüfung der Angabe HELO? Was soll ein Server eigentlich in der HELO Angabe übermitteln? Bei meinen Tests ist es relativ egal, was ich da rein schreibe...
check_recipient_access hash:/etc/postfix/spamfilter-lookup
Das ist der benutzerabhängige Teil weiterer Filterungen. Da habe ich vier unterschiedlich harte Filter definiert, die abhängig von der Zieladresse noch zusätzlich zum Einsatz kommen.
An dieser Stelle hänge ich wieder ein bisschen - ich kann grade nicht ganz nachvollziehen, wie die spamfilter-lookup Tabelle aussehen soll. Das Postfix Handbuch sagt zu check_repipient_access:
"Search the specified access(5) database for the resolved RCPT TO address, domain,
parent domains, or localpart@, and execute the corresponding action."
Die von dieser Tabelle zurückgelieferte "action" soll also ausgeführt werden, doch wie hat diese action auzusehen? Einfach der Name der Restriktions-Klasse? Sähe eine Tabelle also so aus:
adresse | action
----------------+------------
foo@example.org | userlevel1 <- Nach deiner Definition niedriger Spamschutz
bar@example.com | sammeladdr <- Nach d.D. hoher Spammschutz
Wäre da mal noch für ein Beispiel dankbar :-) Ich sehe grade, dass du noch eine Antwort geschrieben hast, also werde ich die jetzt gleich mal lesen ;-)
MfG, Dennis.
Moin!
"NEVER list a virtual MAILBOX domain name as a mydestination domain!"
Leider steht keine Begründung dabei
Weil Postfix die Mails sonst in den falschen Hals^WTransport kriegt, vermute ich.
Die mit mysql-acc/transport angesprochene Tabelle sieht so aus:
domain | transport
-------------+-----------
example.com | virtual:
example.org | virtual:Soweit ich weiß, ist die zweite Spalte allerdings nur ein Platzhalter...
Richtig, weil Postfix immer Hash-Lookups macht und dafür zusätzlich zu dem Hash (der Domain) auch irgendwas braucht, was man uplooken kann, auch wenn es in der Beziehung irrelevant ist.
Wobei deine Tabelle doch eher so aussieht, als könne man sie auch als transport_map nutzen.
Greylisting ist eine der zwei erfolgreichsten Waffen gegen blöden Spam. Die andere Waffe ist eine strenge Prüfung der Angabe HELO.
Ich habe mir gerade mal Greylisting in Wikipedia durchgelesen, ich werde demnächst sicherlich mal versuchen dieses Greylisting zu implementieren.
Ist, wie erwähnt, recht simpel. Die Arbeit übernimmt ein Fertigmodul, welches über eine TCP- oder Unix-Socket ansprechbar ist, und Postfix bindet das einfach nur ein in den *_restrictions. Das Modul kann dann noch passend konfiguriert werden (Standardwerte von postgrey waren aber schon sinnvoll gewählt).
Wie funktioniert die strengere Prüfung der Angabe HELO? Was soll ein Server eigentlich in der HELO Angabe übermitteln? Bei meinen Tests ist es relativ egal, was ich da rein schreibe...
Der SMTP-Standard schreibt vor, dass hinter HELO ein FQDN kommt, also ein vollständiger Domainname. Der Standard schreibt nicht vor, dass dieser Domainname in irgendeiner Weise mit dem sendenden SMTP-Server zusammenhängen muß.
reject_invalid_hostname und reject_non_fqdn_hostname prüfen auf die Einhaltung dieser Forderung. Damit werden Scherzkeksprogramme, die eben "HELO friend" oder "HELO 1.1.1.1" (IP-Adressen, falsch konstruiert) nutzen, abgewiesen. Das sind schon eine ganze Menge.
reject_unknown_hostname verweigert den Empfang, wenn der bei HELO angegebene Hostname nicht im DNS auffindbar ist. Ist ebenfalls hilfreich, aber schon einen Schritt weg von der SMTP-Norm, d.h. es könnte legitime Mailer geben, die damit ausgefiltert werden. Allerdings halten sich alle verbreiteten Mailserver an die Übereinkunft, als HELO ihren EIGENEN Domainnamen zu senden.
Das wiederrum ist der Ansatzpunkt für check_helo_access pcre:/etc/postfix/helo_access - dort prüfe ich, ob die Domain im HELO meine eigene ist. Denn das kann ja auch nicht sein, meine eigene Domain im HELO darf nur mein eigener Mailserver verwenden, und der würde mit sich selbst nicht SMTP sprechen (und vorher sowieso schon durch permit_mynetworks durchgelassen werden). Ebenso ist meine eigene IP im HELO extrem ablehnungswürdig.
Und das war es dann auch schon - und bringt fast 50% der abgelehnten Mails.
Was einem auf der anderen Seite auch wieder Angst machen sollte: Wenn die Spambot-Autoren demnächst etwas besser hingucken in die Standards, und auch aktiv auswerten, wie auf ihre Zustellversuche reagiert wird, könnte direkt schon die nächste Spamwelle kommen.
Ich meine: HELO-Checks und Greylisting sind ja nur deshalb so erfolgreich, weil die Spambot-Autoren schludrig gearbeitet haben. Nicht auszudenken, was passiert, wenn da jemand mit Sachverstand rangehen würde.
Die von dieser Tabelle zurückgelieferte "action" soll also ausgeführt werden, doch wie hat diese action auzusehen? Einfach der Name der Restriktions-Klasse? Sähe eine Tabelle also so aus:
adresse | action
----------------+------------
foo@example.org | userlevel1 <- Nach deiner Definition niedriger Spamschutz
bar@example.com | sammeladdr <- Nach d.D. hoher Spammschutz
Ganz genau.
Diese Postfix-Tabellen, egal ob sie nun als Hash oder in MySQL abgelegt sind, haben immer das gleiche Schema: Lookup-Wert => Ergebnis. Problem 1: Was ist der Lookup-Wert? Problem 2: Was ist das Ergebnis? :)
Das Ergebnis ergibt sich hier fast von alleine. Die Lookup-Werte müssen bei dir allerdings nicht nur komplette Mailadressen sein, sondern wie dokumentiert auch Domains und Domainteile, oder Adressteile.
- Sven Rautenberg
Hi Sven,
Richtig, weil Postfix immer Hash-Lookups macht und dafür zusätzlich zu dem Hash (der Domain) auch irgendwas braucht, was man uplooken kann, auch wenn es in der Beziehung irrelevant ist.
Wobei deine Tabelle doch eher so aussieht, als könne man sie auch als transport_map nutzen.
Hm, in meinem Buch war sie ursprünglich auch als Transport-Map vorgesehen - verstehe ich das richtig, dass transport_maps dafür da sind, E-Mails für bestimmte Domains an andere Mails-Server weiterzuleiten? Oder anders formuliert: Transport-Maps brauche ich nicht? ;-)
Ist, wie erwähnt, recht simpel. Die Arbeit übernimmt ein Fertigmodul, welches über eine TCP- oder Unix-Socket ansprechbar ist, und Postfix bindet das einfach nur ein in den *_restrictions. Das Modul kann dann noch passend konfiguriert werden (Standardwerte von postgrey waren aber schon sinnvoll gewählt).
Ich hab nun mal Postgrey installiert, was dank apt-get install postgrey
sehr schnell ging *g* Entsprechend angepasst hab ich die main.cf:
# restrictions for receiving emails
smtpd_recipient_restrictions = permit_sasl_authenticated, reject_invalid_hostname, reject_non_fqdn_hostname, reject_non_fqdn_sender, reject_unknown_sender_domain, reject_non_fqdn_recipient, reject_unauth_destination, reject_unauth_pipelining, check_recipient_access mysql:/etc/postfix/virtual/spamfilter
# different restrictions classes
smtpd_restriction_classes = normal, medium, hard
# normal - only check validity
normal = reject_unknown_hostname
# medium - use greylisting additionally
medium = reject_unknown_hostname, check_policy_service inet:127.0.0.1:60000
# hard - use blacklists additionally
hard = reject_unknown_hostname, check_policy_service inet:127.0.0.1:60000, reject_rbl_client relays.ordb.org, reject_rbl_client sbl-xbl.spamhaus.org
Postgrey scheint auch gut zu funktionieren - ich hab grade (immer noch per Telnet) eine E-Mail an eine mit 'medium' versehene Adresse geschickt und es kam eine Verweigerungs-Meldung von wegen Postgrey, jetzt grade nochmal eine E-Mail geschickt und sie ist angekommen. An ein Postfach mit 'normal' kam die E-Mail direkt beim ersten Versuch an :-)
Grade hab ich dann auch noch zufrieden festgestellt, dass Postfix keinen Fehler bringt, wenn man für ein Mailkonto die Angabe der Restriktions-Klasse einfach leer lässt - sieht mir so aus, als ob dann ganz einfach keine Klasse durchgeführt wird.
Jetzt stellt sich nur noch die Frage, ob und wie man die Spamfilter noch weiter ausfeilen kann...
Das wiederrum ist der Ansatzpunkt für check_helo_access pcre:/etc/postfix/helo_access - dort prüfe ich, ob die Domain im HELO meine eigene ist. Denn das kann ja auch nicht sein, meine eigene Domain im HELO darf nur mein eigener Mailserver verwenden, und der würde mit sich selbst nicht SMTP sprechen (und vorher sowieso schon durch permit_mynetworks durchgelassen werden). Ebenso ist meine eigene IP im HELO extrem ablehnungswürdig.
Hm, das könnte ich auch noch versuchen in 'normal' zu implementieren - wie muss die helo_access denn aussehen? Einfach so:
mail.example.com irgendwas
123.456.789.0 irgendwas
Was einem auf der anderen Seite auch wieder Angst machen sollte: Wenn die Spambot-Autoren demnächst etwas besser hingucken in die Standards, und auch aktiv auswerten, wie auf ihre Zustellversuche reagiert wird, könnte direkt schon die nächste Spamwelle kommen.
Gabs da nicht noch so ein schönes Tool, was einem eine hübsche grafische Auswertung der mail.log erzeugt und auflistet, wie viel % E-Mails abgewiesen wurden?
Das Ergebnis ergibt sich hier fast von alleine. Die Lookup-Werte müssen bei dir allerdings nicht nur komplette Mailadressen sein, sondern wie dokumentiert auch Domains und Domainteile, oder Adressteile.
Das verstehe ich jetzt wiederrum nicht - ich frage also mal ganz dumm: Warum die Werte Domains, Domainteile und Adressteile aufsplitten? So wie es jetzt ist funktioniert doch alles (ja, ich teste bereits mit zwei verschiedenen Domains).
MfG, Dennis.
Moin!
Oder anders formuliert: Transport-Maps brauche ich nicht? ;-)
Nein, vermutlich nicht.
Grade hab ich dann auch noch zufrieden festgestellt, dass Postfix keinen Fehler bringt, wenn man für ein Mailkonto die Angabe der Restriktions-Klasse einfach leer lässt - sieht mir so aus, als ob dann ganz einfach keine Klasse durchgeführt wird.
Mutmaßlich dürfte dann keine der drei Klassen am Ende greifen. Sozusagen also eine "light"-Klasse, die nur die bereits aufgelisteten Restrictions ausführt.
Hm, das könnte ich auch noch versuchen in 'normal' zu implementieren - wie muss die helo_access denn aussehen? Einfach so:
mail.example.com irgendwas
123.456.789.0 irgendwas
Als irgendwas ist die Angabe von SMTP-Fehlercode und einer zugehörigen Textnachricht empfehlenswert, alternativ auch nur schlicht REJECT.
Sicherlich nicht verkehrt ist, wenn du alternativ zu einer ausführlichen Auflistung aller denkbaren falschen Domains mit regulären Ausdrücken arbeitest.
Gabs da nicht noch so ein schönes Tool, was einem eine hübsche grafische Auswertung der mail.log erzeugt und auflistet, wie viel % E-Mails abgewiesen wurden?
Es ist in jedem Fall sinnvoll, die Wirksamkeit der Filtermaßnahmen durch Statistiken zu kontrollieren. Es gibt "mailgraph" zur grafischen Auswertung (siehe SELFHTML Blog: http://aktuell.de.selfhtml.org/weblog/sober_rollt_an), es gibt auch pflogsumm. Beide Tools (und sicher noch eine ganze Zahl andere) geben dir aus, was in den Logfiles gesammelt drinsteht hinsichtlich Mailereignissen.
Und das sollte man von Zeit zu Zeit mal auswerten, um informiert zu bleiben, welche der Abwehrlinien, die man errichtet hat, denn wirksam sind.
Das Ergebnis ergibt sich hier fast von alleine. Die Lookup-Werte müssen bei dir allerdings nicht nur komplette Mailadressen sein, sondern wie dokumentiert auch Domains und Domainteile, oder Adressteile.
Das verstehe ich jetzt wiederrum nicht - ich frage also mal ganz dumm: Warum die Werte Domains, Domainteile und Adressteile aufsplitten? So wie es jetzt ist funktioniert doch alles (ja, ich teste bereits mit zwei verschiedenen Domains).
Hängt davon ab, was du willst. Wenn du beispielsweise für alle Domains, die du hast, für alle "info@"-Adressen einen scharfen Spamfilter willst, und dafür nur eine einzige Zeile in der Datei, mußt du die Domains ja nicht alle aufzählen.
Und wenn alle Mailadressen einer gesamten Domain einen Filter kriegen sollen (oder einen Standardfilter, der bei explizit genannten Mailadressen durch Überschreiben mit einem anderen Wert auch geändert werden kann), dann wird halt nur die Domain als Schlüssel eingetragen, nicht die gesamte Mailadresse. Sozusagen "Wildcards".
- Sven Rautenberg
Hi Sven,
Als irgendwas ist die Angabe von SMTP-Fehlercode und einer zugehörigen Textnachricht empfehlenswert, alternativ auch nur schlicht REJECT.
OK - ich kann also eine individuelle Fehlermeldung (Pfui - ich nehm doch keine Mail von mir selber an) generieren *g*
Sicherlich nicht verkehrt ist, wenn du alternativ zu einer ausführlichen Auflistung aller denkbaren falschen Domains mit regulären Ausdrücken arbeitest.
Was meinst du mit denkbar falschen Domains? Mir fallen nur alle Domains für die der Server selber zuständig ist als fehlerhaft ein...
Es ist in jedem Fall sinnvoll, die Wirksamkeit der Filtermaßnahmen durch Statistiken zu kontrollieren. Es gibt "mailgraph" zur grafischen Auswertung (siehe SELFHTML Blog: http://aktuell.de.selfhtml.org/weblog/sober_rollt_an), es gibt auch pflogsumm. Beide Tools (und sicher noch eine ganze Zahl andere) geben dir aus, was in den Logfiles gesammelt drinsteht hinsichtlich Mailereignissen.
Danke - führe ich mir zu Gemüte und werde ich zu installieren versuchen.
Hängt davon ab, was du willst. Wenn du beispielsweise für alle Domains, die du hast, für alle "info@"-Adressen einen scharfen Spamfilter willst, und dafür nur eine einzige Zeile in der Datei, mußt du die Domains ja nicht alle aufzählen.
Das ist für mich weniger interessant, weil die Domains die über den Server laufen (sollen) nicht alle mir sind und die Inhaber der Domains (Verwandte von mir) den Spammschutz für Ihre Domains selber wählen können sollen.
Und wenn alle Mailadressen einer gesamten Domain einen Filter kriegen sollen (oder einen Standardfilter, der bei explizit genannten Mailadressen durch Überschreiben mit einem anderen Wert auch geändert werden kann), dann wird halt nur die Domain als Schlüssel eingetragen, nicht die gesamte Mailadresse. Sozusagen "Wildcards".
Hm, ich überlege grade, dass dies doch auch mit einem entsprechenden SELECT-Command gehen müsste, welcher das Feld anhand des @ aufsplittet... Ich muss das mal ausprobieren...
MfG, Dennis.
Moin!
Als irgendwas ist die Angabe von SMTP-Fehlercode und einer zugehörigen Textnachricht empfehlenswert, alternativ auch nur schlicht REJECT.
OK - ich kann also eine individuelle Fehlermeldung (Pfui - ich nehm doch keine Mail von mir selber an) generieren *g*
Ich würde nur etwas schreiben, was ich auch menschlichen Nutzern zumuten würde, ohne dabei das Gesicht zu verlieren.
Sicherlich nicht verkehrt ist, wenn du alternativ zu einer ausführlichen Auflistung aller denkbaren falschen Domains mit regulären Ausdrücken arbeitest.
Was meinst du mit denkbar falschen Domains? Mir fallen nur alle Domains für die der Server selber zuständig ist als fehlerhaft ein...
Ich schrieb "denkbaren falschen", nicht "denkbar falschen". Wenn du für example.com Mails annimmst - dann auch von jemandem mit "HELO friend.example.com"?
Und wenn alle Mailadressen einer gesamten Domain einen Filter kriegen sollen (oder einen Standardfilter, der bei explizit genannten Mailadressen durch Überschreiben mit einem anderen Wert auch geändert werden kann), dann wird halt nur die Domain als Schlüssel eingetragen, nicht die gesamte Mailadresse. Sozusagen "Wildcards".
Hm, ich überlege grade, dass dies doch auch mit einem entsprechenden SELECT-Command gehen müsste, welcher das Feld anhand des @ aufsplittet... Ich muss das mal ausprobieren...
Postfix schickt von sich aus schon diverse Querys an die Datenbank, da mußt du nichts selbst manipulieren. Lass dir die Querys mal von MySQL ins Log schreiben, dann siehst du, was ich meine.
- Sven Rautenberg