Dennis: Postfix mit MySQL-Support unter Debian

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.

--
Mein SelfCode: ie:{ fl:( br:> va:) ls:[ fo:) rl:( n4:# ss:) de:] js:| ch:{ sh:| mo:} zu:|
Das ist eine Ehrlichkeit, die an Blödheit grenzt. (Thomas Gottschalk)
  1. 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";

    1. 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.

      --
      Mein SelfCode: ie:{ fl:( br:> va:) ls:[ fo:) rl:( n4:# ss:) de:] js:| ch:{ sh:| mo:} zu:|
      Patch zur Verwendung von PATHINFO in JLog
      Wer kämpft, kann verlieren. Wer nicht kämpft, hat schon verloren. (Bertholt Brecht)
      1. 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.

  2. 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.

    --
    Mein SelfCode: ie:{ fl:( br:> va:) ls:[ fo:) rl:( n4:# ss:) de:] js:| ch:{ sh:| mo:} zu:|
    Patch zur Verwendung von PATHINFO in JLog
    Lache nie über die Dummheit der anderen. Sie ist deine Chance. (Winston Churchill)
    1. 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

      --
      "Love your nation - respect the others."
      1. 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.

        --
        Mein SelfCode: ie:{ fl:( br:> va:) ls:[ fo:) rl:( n4:# ss:) de:] js:| ch:{ sh:| mo:} zu:|
        Patch zur Verwendung von PATHINFO in JLog
        Lesen Sie schnell, denn nichts ist beständiger als der Wandel im Internet! (Anita Berres)
        1. 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"):

          Restriction Classes Definitions

          smtpd_restriction_classes = sammeladdr, userlevel3, userlevel2, userlevel1

          Filterregeln fuer Sammeladdressen: Extrem streng, filtern auch

          Kollateralschaeden wie Bounces (FROM: <>) heraus.

          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

          --
          "Love your nation - respect the others."
          1. 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

            --
            "Love your nation - respect the others."
            1. 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.

              --
              Mein SelfCode: ie:{ fl:( br:> va:) ls:[ fo:) rl:( n4:# ss:) de:] js:| ch:{ sh:| mo:} zu:|
              Das ist eine Ehrlichkeit, die an Blödheit grenzt. (Thomas Gottschalk)
          2. 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.

            1. 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

              --
              "Love your nation - respect the others."
              1. 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.

                --
                Mein SelfCode: ie:{ fl:( br:> va:) ls:[ fo:) rl:( n4:# ss:) de:] js:| ch:{ sh:| mo:} zu:|
                Patch zur Verwendung von PATHINFO in JLog
                Berater sind Leute die dir deine Uhr wegnehmen, damit sie dir anschließend sagen können wie spät das es ist! (Aus einem Kabarett)
                1. 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

                  --
                  "Love your nation - respect the others."
                  1. 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.

                    --
                    Mein SelfCode: ie:{ fl:( br:> va:) ls:[ fo:) rl:( n4:# ss:) de:] js:| ch:{ sh:| mo:} zu:|
                    Patch zur Verwendung von PATHINFO in JLog
                    Viele Menschen sind gut erzogen, um nicht mit vollem Mund zu sprechen, aber sie haben keine Bedenken, es mit leerem Kopf zu tun. (Orson Welles)
                    1. 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

                      --
                      "Love your nation - respect the others."