Mit Postfix Disclaimer basteln

Zur Zeit geistern vermehrt Warnungen vor einer Abmahnwelle durch die Presse. Grund ist eine zum 01.01.2007 gültig gewordene Erweiterung des § 125a Abs. 1 Satz 1 des EHUG.

Hier wurde die bei Geschäftsbriefen ohnehin schon bestehende Pflicht zur Angabe der Handelregisterangaben auch auf eMails ausgeweitet.

Da man zwar alle Mitarbeiter auf diesen Umstand hinweisen kann, aber noch lange nicht sicher ist, dass dieser von allen gelesen (geschweige denn auch umgesetzt) wird, haben wir uns daher entschlossen, unserem MTA Postfix diese Aufgabe anzuvertrauen.

Dieser soll nun unter alle ausgehenden eMails des Hauses die gewünschten Angaben druntertackern.

Und da nicht nur wir das Problem haben dürften, hier eine kurze Beschreibung, wie wir das umgesetzt haben:

Grundlage für die Umsetzung war das Tool “alterMIME“, das u.a. ermöglicht, MIME-kodierte Dateien um Disclaimer zu erweiteren.

Wir haben uns im Großen und Ganzen bei der Installation und Konfiguration an die dort verlinkte Anleitung zur Konfiguration von alterMIME unter Postfix gehalten:

Nach dem Herunterladen und Kompilieren von altermime mit:
$ wget http://www.pldaniels.com/altermime/altermime-0.3.7.tar.gz
$ tar xvf altermime-0.3.7.tar.gz
$ cd altermime-0.3.7
$ make

(Und nein: es fehlt beim “tar” kein Parameter “z” ;) – Das Archiv heisst zwar so, ist aber nicht gezippt).

kommt das Programm nach /usr/local/bin und wird dort für jedermann ausführbar:
# cp altermime /usr/local/bin/
# chmod 755 /usr/local/bin/altermime

Wir lassen den Filter als User “postfix” ausführen, unter dem bei uns auch der MTA selbst läuft, halten uns aber in der Anleitung an das o.g. Vorbild und richten dafür einen extra Benutzer “filter” ein:
# useradd -r -c "Postfix Filter" -m -d /var/spool/filter filter

Und jetzt zum eigentlichen Script “/etc/postfix/disclaimer/filter”, das bei uns dafür sorgt, dass nur ausgehende Nachrichten mit dem Disclaimer versehen werden. Wir filtern das über die Absender-eMail-Adresse, die als erster Parameter an das Filter-Script übergeben wird:
#!/bin/bash
#
# Wo sind meine Sachen?
INSPECT_DIR=/var/spool/filter
SENDMAIL=/usr/sbin/sendmail
ALTERMIME=/usr/local/bin/altermime
#
SENDER_DOMAIN=meine-domain.de
COPYRIGHT_HEADER="Wichtiger Text"
#
# Fehlercodes:
EX_TEMPFAIL=75
EX_UNAVAILABLE=69
#
# Aufraeumen nicht vergessen:
trap "rm -f in.$$" 0 1 2 3 15
#
# und los geht es
cd $INSPECT_DIR || { echo $INSPECT_DIR existiert nicht; exit $EX_TEMPFAIL; }
cat >in.$$ || { echo Kann eMail nicht speichern; exit $EX_TEMPFAIL; }
#
# Domain aus uebergebener Absenderadresse filtern:
DOMAIN=${2##*@}
#
if [ "$DOMAIN" == "$SENDER_DOMAIN" ]; then
$ALTERMIME --input=in.$$ \
--disclaimer=/etc/postfix/disclaimer/disclaimer.txt \
--disclaimer-html=/etc/postfix/disclaimer/disclaimer.txt \
--xheader="X-Copyrighted-Material: $COPYRIGHT_HEADER" || \
{ echo Message content rejected; exit $EX_UNAVAILABLE; }
else
$ALTERMIME --input=in.$$ \
--xheader="X-Copyrighted-Material: $COPYRIGHT_HEADER" || \
{ echo Message content rejected; exit $EX_UNAVAILABLE; }
fi
#
$SENDMAIL "$@" <in.$$
exit $?

Das Ganze muss jetzt noch für den Filter-User ausführbar gemacht werden:
# chgrp filter /etc/postfix/disclaimer/filter
# chmod 750 /etc/postfix/disclaimer/filter

Der Text, der in die eMail eingefügt werden soll, muss jetzt als /etc/postfix/disclaimer/disclamaimer.txt angelegt werden.

Jetzt fehlt noch das Wichtigste: die Einbindung von alterMIME in die Postfix-Umgebung. Dies geschieht über die Erweiterung der /etc/postfix/master.cf.

Da bei uns der Mailserver nur eine IP-Adresse hat, und zusätzlich zum alterMIME auch noch Amavis mit der Mailfilterung beschäftigt ist (es wollen ja auch noch Spams und Viren bekämpft werden), sieht unsere master.cf in den angepassten Teilen jetzt so aus (hier unsere komplette master.cf.zip):


# ==========================================================================
# service type private unpriv chroot wakeup maxproc command + args
# (yes) (yes) (yes) (never) (100)
# ==========================================================================
smtp inet n - n - - smtpd
-o content_filter=smtp-amavis:[127.0.0.1]:10024
#
# [...hier noch das Standardzeug ...]
#
smtp-amavis unix - - n - 2 smtp
-o smtp_data_done_timeout=1200
-o disable_dns_lookups=yes
127.0.0.1:10025 inet n - n - - smtpd
-o content_filter=dfilt:
-o local_recipient_maps=
-o relay_recipient_maps=
-o smtpd_restriction_classes=
-o smtpd_client_restrictions=
-o smtpd_helo_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o mynetworks=127.0.0.0/8
-o strict_rfc821_envelopes=yes
-o smtpd_error_sleep_time=0
-o smtpd_soft_error_limit=1001
-o smtpd_hard_error_limit=1000
dfilt unix - n n - - pipe
flags=Rq user=filter argv=/etc/postfix/disclaimer/filter -f ${sender} -- ${recipient}

Nach einem
# postfix reload

sollten die Hinweise nun in keinen ausgehenden elektronischen Nachrichten mehr fehlen, überprüfbar ist das im Mail.log über einen grep auf “dfilt”.

Über Stefan

Meine Leidenschaft, sowohl im beruflichen als auch im privaten Bereich, gilt seit mittlerweile über 15 Jahren Linux-Systemen. Einen speziellen Schwerpunkt in diesem Bereich habe ich nicht - nur Debian-basiert sollte es sein.
Dieser Artikel wurde in Aus dem Alltag, Linux, Postfix, Cyrus und Co. veröffentlicht.Permalink als Favorit speichern.

69 Antworten zu Mit Postfix Disclaimer basteln

  1. Seb schreibt:

    Ich habe jetzt bemerkt dass das script gar nicht aufgerufen wird. Also muss es an der master.cf liegen, was ist falsch?
    http://seb-com.de/master.cf

  2. Stefan schreibt:

    Du hast in Deiner master.cf amavis nicht aufgerufen (wie bei uns mit: content_filter=smtp-amavis:[127.0.0.1]:10024 beim SMTP-Service) , wartest aber dann auf Port 10025 auf die von dort zurückgegebenen, gefilterten Mails. Erst dann rufst Du als Content-Filter “dfilt” auf.

    Wenn Du amavis nicht einsetzt, erweitere die Zeile für SMTP um den Content-Filter dfilt:

    smtp      inet  n       -       n       -       -       smtpd
       -o content_filter=dfilt:
  3. Seb schreibt:

    Mh, ok das leuchtet mir jetzt ein. Vielen Dank!
    Und funktionieren tut es jetzt auch noch, oh man ist das schön :D

  4. Seb schreibt:

    Eine Frage noch, wie kann ich den Text nur für eine bestimmte Mail-Adresse zuschneiden?

  5. Stefan schreibt:

    Du kannst einfach das Filter-Script entsprechend anpassen, etwa in der Art:

    # Domain aus uebergebener Absenderadresse filtern:
    ABSENDER=$2
    #
    case "$ABSENDER" in
       foo@bar.de)
          FILEDISCLAIMER=disclaimer_foo
          ;;
       foobar@foobar.de)
          FILEDISCLAIMER=disclaimer_foobar
          ;;
       *)
          FILEDISCLAIMER=disclaimer
          ;;
    esac
    #
    # und (fast) weiter wie bisher
    #
    if [ "$DOMAIN" == "$SENDER_DOMAIN" ]; then
       $ALTERMIME --input=in.$$ \
          --disclaimer=/etc/postfix/disclaimer/$(FILEDISCLAIMER).txt \
          --disclaimer-html=/etc/postfix/disclaimer/$(FILEDISCLAIMER).txt \
          --xheader="X-Copyrighted-Material: $COPYRIGHT_HEADER" || \
          { echo Message content rejected; exit $EX_UNAVAILABLE; }
    
    [...]
    

    Jetzt musst Du nur noch fuer die einzelnen Absender entsprechende Dateien unter /etc/postfix/disclaimer anlegen.

    Gruß
    Stefan

  6. sabi stephan schreibt:

    wg Leerzeichen / Zeilenumbrüche in Signatur (bei html-Format) Mal im source der versandten Mail gekuckt: nach x Zeichen (ich glaub 72) kommt zwangsweise ein Umbruch, egal ob vorher ein linebreak war. Der Umbruch wird im Source sichtbar: da steht dann ein Leerzeichen gefolgt von einem =. Das = wird nicht ausgegeben, aber das Leerzeichen schon. Das macht natürlich im HTML ein Leerzeichen, wo garkeins hingehört, z.B. mitten im Wort. Wie gesagt: ich hab mir den Quelltext der empfangenen html-Mails mal angesehen und bin zu folgender Lösung gekommen:
    Diese zwei Zeilen werden wie 1 Zeile gelesen: (sozusgen kein html-break drin, und zeilenumbruch wird dann ignoriert)
    blablabla blablabla
    2. zeile blablabla irgendein text

    Also habe ich einfach die Zeilen mit Leerzeichen aufgefüllt (bissl experimentiert, ob 72 Zeichen pro Zeile oder 76 oder was auch immer):
    blablabla 1. zeile……………
    2.zeile………………………………………………………..
    usw……………………………………………….

    Dann sieht alles sauber aus beim Empfänger.

    hth

  7. falcon5 schreibt:

    Vielen Dank für den Howto.
    Ich möchte mal wissen ob es auch möglich ist um ein Disclaimer im MySQL zu setzen.

  8. Stefan schreibt:

    Da Altermime als Parameter nur den Pfad auf eine Datei, die den Disclaimer-Text enthält entgegennimmt, nicht aber den Text selbst, hast Du leider keine einfache Möglichkeit, die gewünschten Daten über eine Datenbankabfrage zu ermitteln.

    Die einzige Möglichkeit, z.B. je nach Absendeadresse unterschiedliche Fußtexte an die ausgehenen eMails zu hängen ist, für jeden Disclaimer eine eigene Datei anzulegen, und diese im Shellscript je nach Absender ($2) über ein if-Konstrukt zuzuweisen (siehe meinen Kommentar vom 2.8.2007).

  9. maddin schreibt:

    Hi Leute!

    Ich hab ein Problem und zwar kommen die E-Mails nicht an, laut log werden sie einwandfrei gefiltert, aber sie werden nach dem filtern anscheinend nicht mehr weitergeleteitet oder gesendet, hier der log-Eintrag:

    Jan 5 19:02:57 debian-test2 postfix/pipe[11117]: 64799C7BC9: to=, relay=dfilt, delay=0.13, delays=0.07/0.02/0/0.04, dsn=2.0.0, status=send (delivered via dfilt service)

    Kann sich das jemand erklären?

    Viele Grüße,
    Martin

  10. Stefan schreibt:

    Hi Martin,

    zwei Dinge sind komisch an Deinem Log-Eintrag:
    - Hinter “to=” sollte die Empfänger-Mail-Adresse folgen
    - statt “send” sollte “sent” in der Zeile stehen

    Ich vermute einen Fehler in der master.cf oder falsche Zugriffsrechte auf Dein Filter-Script.

    Wobei mir Zweiteres weniger wahrscheinlich erscheint, da in diesem Fall zumindest die eMail-Adresse nach dem “to=” auftauchen sollte.

  11. Stefan R schreibt:

    Hey,

    habe das Howto durchgearbeitet und auch die Komentare beachtet, aber bei mir will es nicht laufen,

    ich bekomme keine fehlermeldungen in der log, die email kommt beim empfänger an aber ohne disclaimer

  12. Stefan schreibt:

    @Stefan R

    Hast Du die master.cf überprüft (siehe ein paar Kommentare weiter oben)? Außerdem musst Du sicherstellen, dass altermime ausführbar ist und auch auf den Disclaimer-Text zugreifen kann.

  13. Stefan R schreibt:

    @Stefan

    danke für die Antwort.

    die master.cf hab ich geprüft

    inhalt:

    #
    # DO NOT SHARE THE POSTFIX QUEUE BETWEEN MULTIPLE POSTFIX INSTANCES.
    #
    # ==========================================================================
    # service type private unpriv chroot wakeup maxproc command + args
    # (yes) (yes) (yes) (never) (100)
    # ==========================================================================
    smtp inet n – n – – smtpd
    -o content_filter=dfilt:
    #628 inet n – n – – qmqpd
    pickup fifo n – n 60 1 pickup
    cleanup unix n – n – 0 cleanup
    qmgr fifo n – n 300 1 qmgr
    #qmgr fifo n – n 300 1 nqmgr
    rewrite unix – – n – – trivial-rewrite
    bounce unix – – n – 0 bounce
    defer unix – – n – 0 bounce
    flush unix n – n 1000? 0 flush
    proxymap unix – – n – – proxymap
    smtp unix – – n – – smtp
    relay unix – – n – – smtp
    -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
    showq unix n – n – – showq
    error unix – – n – – error
    local unix – n n – – local
    virtual unix – n n – – virtual
    lmtp unix – – n – – lmtp
    #
    # Interfaces to non-Postfix software. Be sure to examine the manual
    # pages of the non-Postfix software to find out what options it wants.
    #
    # maildrop. See the Postfix MAILDROP_README file for details.
    #
    maildrop unix – n n – – pipe
    flags=DRhu user=vmail argv=/usr/local/bin/maildrop -d ${recipient}
    #
    # The Cyrus deliver program has changed incompatibly, multiple times.
    #
    # old-cyrus unix – n n – – pipe
    flags=R user=cyrus argv=/cyrus/bin/deliver -e -m ${extension} ${user}

    procmail unix – n n – – pipe
    flags=R user=nobody argv=/usr/bin/procmail -t -m /etc/procmailrc $(sender) $(recipient)

    dfilt unix – n n – – pipe
    flags=Rq user=filter argv=/etc/postfix/disclaimer/filter -f ${sender} — ${recipient}

    altermime kann ich ausführen und bekomm die befehlsliste.

  14. Stefan R schreibt:

    ok mittlerweile geht nen teil.
    nun bekomm ich den fehler, wenn ich ne mail verschicke:

    (expanded from ): bad address syntax

    also ich bekomm dann vom postfix ne email zurück


    If you do so, please include this problem report. You can delete your own text from the attached returned message.

    The mail system

    (expanded from ): bad address syntax

  15. Stefan R schreibt:

    ich hab mein Problem gefunden!

    Amavis gibt die email an Altermime, altermime wieder zu amavis!
    danach bekomm ich

    to many hops …

    ich verzweifle noch.

    sorry für die vielen komentare ;/ aber google ist nicht sehr hilfreich gerade

  16. Stefan schreibt:

    Wie rufst Du denn amavis auf? In der von Dir geposteten master.cf steht nichts davon.

  17. Joerg Peter schreibt:

    Hallo,
    ich habe jetzt auf Version 3.10 upgedatet, weil ich ein Problem hatte und dachte ich könnte es mit dem Update lösen. Okay, ging nicht. Und zwar werden manche eMail Anlagen einfach gelöscht. Und zwar wird der Filter auch aufgerufen bei Mails die ich empfange. Und bei denen wird dann kein Disclaimer angehängt, aber die Anlagen werden nicht “durchgereicht”. Außerdem habe ich dann versucht das >>/tmp/altermime.log zu füllen, was aber immer leer ist. Daher ist meine Fehlersuche nur sehr eingeschränkt möglich. Hier mein Codesnip

    if [ $DOMAIN == $SENDER_DOMAIN1 -o $DOMAIN == $SENDER_DOMAIN2 -o $DOMAIN == $SENDER_DOMAIN3 ]; then
    echo $ALTERMIME –input=in.$$ \
    –debug –verbose \
    –xheader=”X-Copyrighted-Material: $COPYRIGHT_HEADER” || \
    { echo Message content rejected; exit $EX_UNAVAILABLE; }
    else

    Wie bzw. wo muß ich dieses >> /tmp/altermime.log eintragen damit alles reingeschrieben wird *grübel*. Gibt es eine Möglichkeit zu sagen “so wie sie ist weiterleiten”?

    Cu
    Jörg Peter

  18. Stefan schreibt:

    Hallo Jörg Peter,

    klar, das Script wird für alle Mails aufgerufen, deswegen ja auch die Abfrage der $DOMAIN in dem Script selbst, um altermime nur für ausgehende Nachrichten aufzurufen.

    Das “>> /tmp/altermime.log” gehört an das Ende der Zeile “$ALTERMIME –input …”, wobei in Deinem Post noch ein Fehler im Script ist.

    Das “echo” vor “$ALTERMIME” muss weg.

    Das Problem, dass Anlagen von Mails unterschlagen werden, habe ich nicht. Was ich mir vorstellen kann, ist dass im E-Mail-Text in einer Zeile nur ein Punkt steht, was normalerweise das Ende der Mail anzeigt.

    Im Kommentar von Marc vom 5.April 2007 gibt’s eine Lösung hierzu.

    Gruß
    Stefan

  19. Markus schreibt:

    Toller Beitrag! Ich würde gerne eine Textdatei mit Domains oder Emails anlegen die keinen Disclaimer bekommen sollen. Ich würde mich sehr über Hilfe freuen.

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

*

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>