Postfix und Domain Aliase

Eben wurde ich auf eine Situation aufmerksam gemacht, die mir nicht bewußt war (oder ist es vielleicht schon nicht mehr aktuell?!):

Postfix kann keine unbekannten Benutzer in Domains, die ein alias für andere Domains sind, zurückweisen. Das ist schlecht, weil damit alle Mails, für beliebige Empfänger also, angenommen werden – und dafür dann ein bounce generiert werden muss.

Als Lösung gibt es, beim Einsatz von Mysql, eine recht komplizierte SQL Abfrage. Die möchte ich hier nennen und sie auch gleich erklären:

/etc/postfix/main.cf:
virtual_alias_maps =
proxy:mysql:/etc/postfix/mysql_virtual_gate.cf,

/etc/postfix/mysql_virtual_gate.cf:

query =select destination from forwardings where source = ‚%s‘
and left(destination,1) <> ‚@‘
union
select concat(left(‚%s‘,locate(‚@‘,’%s‘)-1), destination) as rewritten from forwardings
where source = ‚@%d‘ and left(destination,1) = ‚@‘
limit 1

Die Mysql-Tabelle „forwardings“ sieht dabei z.B. so aus:

source destination
postmaster@bla.zz postmaster@blubb.zz
staff@blubb.zz info@yet-another-dom.zz
@bla.zz @blubb.zz

So, jetzt die Funktionsweise: Ziel ist es ja, unbekannte Empfänger abzuweisen. Dazu gehe ich jetzt die SQL Zeilen durch.

select destination from forwardings where source = ‚%s‘

Wenn bei Source die einkommende Email Adresse steht, war es das schon: das Ziel – „destination“ – wird als erstes ausgegeben. Kommt also eine Email an postmaster@bla.zz, kommt als Resultat postmaster@blubb.zz raus.

and left(destination,1) <> ‚@‘

Dies blockiert Ausgaben, wo bei „destination“ nur „@domain“ steht (Übersetzt heisst das Statement: wo das linke eine (1) Zeichen nicht „@“ ist).

union

Verbindet die gerade erfolgte Auswahl mit dem, was jetzt kommt. Ich überspringe jetzt die folgende „select“ Zeile, die hängt von der „from“ Zeile danach ab.

where source = ‚@%d‘ and left(destination,1) = ‚@‘

Hier wird der generelle Domain-Alias ausgewählt, also die Zeile „@bla.zz“ „@blubb.zz“. Bei der Quell-Email muss der Domain-Teil (%d) auf die Angabe bei „source“ passen – und bei „destination“ „@irgendwas, also eine gesamte Domain, stehen. Diese „destination“ Angabe, im Beispiel „@blubb.zz“, wird jetzt bei der Select-Anweisung in der Zeile davor benutzt:

select concat(left(‚%s‘,locate(‚@‘,’%s‘)-1), destination) as rewritten from forwardings

Rewritten deutet es schon an, hier wird was umgeschrieben. Wir müssen in der innersten Klammer beginnen und uns nach aussen arbeiten:

  • locate(‚@‘,’%s‘) sucht in der einkommenden Email-Adresse das „@“, also dessen Postition.
  • „-1“ – wird von der Positionszahl abgezogen.
  • „left(‚%s‘, <Positionszahl>)“ – hier wird der linke Teil der einkommenden Email-Adresse genommen, und zwar <Positionszahl> Buchstaben. Dieses sehr verklausulierte entspricht dem Benutzernamen in der Email-Adresse! Beispiel: es kommt „staff@bla.zz“ rein, dann bleibt „staff“ übrig.
  • „concat(<Benutzername>, destination)“ – concatenate heisst auf englisch zusammenfügen. Hier werden einfach die beiden Teile aneinandergehängt – man erhält also „staff“ + „@blubb.zz“ -> „staff@blubb.zz“
  • „select „staff@blubb.zz“ from forwardings“ – Auf diese gerade zusammengefügte alias Email-Adresse wird jetzt der „select“ angewandt: oben auf das Beispiel angewandt folgt daraus „info@yet-another-dom.zz“, ist also auch valide.

Diese beiden Teile, die direkte Auswahl wenn die Eingabe bei „source“ steht und die umgebaute Version, werden mit der „union“ verbunden und mit einem „limit 1“ auf eine Ausgabezeile beschränkt. Kommt eine Email raus, ist die ankommende Emailadresse ok, ist die Ausgabe leer, wird die Email abgelehnt.

 

Quelle: http://billboebel.typepad.com/blog/2005/11/postfix_and_dom.html