Abwesenheitsmeldungen mit postfix: Unterschied zwischen den Versionen

Aus
Zeile 73: Zeile 73:


msg=""
msg=""
touch /opt/var/log/autoreply.log
err=''
err=''



Version vom 8. August 2010, 14:39 Uhr

Für dovecot-sieve gibt es mit vacation ein Plugin, welches Abwesenheitsmeldungen erstellt und verschickt. "Leider" ist vacation so geschrieben, dass maximal einmal pro Tag eine Mail pro Sender rausgeht. Will man also z.B. für eine info-Adresse jede Mail mit einer Meldung bestätigen, geht dies mit vacation nicht ohne den Quelltext zu verändern (mehr zu vacation und dovecot-sieve)

Zum Glück gibt es eine sehr einfache Möglichkeit einen autoresponder direkt am Postfix-Server einzurichten. Dazu muss man Anpassungen in zwei Konfigfiles machen und ein Script haben, welches das Beantworten übernimmt

Konfiguration

virtual

In der Datei virtual legt man pro Adresse, die autoresponder haben sollen, einen Eintrag in der folgenden Form an

postmaster@domain.tld user@domain.tld,user@domain.tld@autoreply.domain.tld

Mails für postmaster@domain.tld werden hierbei an den user@domain.tld geschickt. Zusätzlich geht die Mail an die zweite Adresse, welche den autoresponder von postfix verarbeitet.
autoreply.domain.tld darf keinesfalls unter mydestination oder virtual_mailbox_domains in der main.cf aufgeführt sein!

Danach die Datei mittels postmap für postfix lesbar machen

postmap /path/to/virtual

transport

In der Datei transport wird auf Basis der Domain der Empfangsadresse der "Lieferweg" festgelegt. Hier drin legen wir einen Eintrag für die autoreply-Adresse an und weisen diesem einen Postfix-Handler zu (auch diese Datei muss mittels postmap kovertiert werden)

autoreply.domain.tld autoreply:

Wenn also eine Mail an die autoreply-Domain geschickt wird, dann wird der Postfix-Handler autoreply aufgerufen. Diesen müssen wir erst noch defnieren.

master.cf

In master.cf werden die "Dienste" von Postfix definiert und konfiguriert. Hier müssen wir für autoreply einen Handler erstellen. Dieser kann so ausschauen

autoreply	unix	-	n	n	-	-	pipe
 flags= user=nobody argv=/opt/etc/postfix/autoreply ${sender} ${original_recipient}

Wenn also autoreply aufgerufen wird, dann "piped" Postfix die Mail an das angegebene Script. Neben dem Inhalt der Mail via stdin übergibt Postfix 2 Parameter an das Script. Damit das Script weiss von wem die Mail ist und wohin die Meldung geschickt werden soll.

main.cf

Jetzt muss man nur noch in main.cf virtual resp transport aktivieren

transport_maps = hash:/path/to/transport
virtual_alias_maps = hash:/path/to/virtual

Danach ein

postfix stop
postfix start

autoresponder Script

Hier kommt das unter autoreply festgelegt Script. Es handelt sich hierbei um ein einfaches Shellscript, welches den Inhalt der Mail (inkl aller Mailheader) via stdin übergeben bekommt. Zusätzlich erwartet das Script den Sender und den Originalempfänger der E-Mail als Parameter.

Das Script prüft ob die Mail von einer Mailingliste kommt oder sonstige Bedingungen nicht erfüllt. In diesen Fällen wird keine Mail versendet. Bei den Bedingungen habe ich mich an vacation orientiert

  • Auto-Submitted: header exists with any value except "no"
  • Precedence: header exists with value "junk", "bulk" or "list"
  • The envelope sender
    • begins with "MAILER-DAEMON" (case-insensitive)
    • begins with "LISTSERV" (case-insensitive)
    • begins with "majordomo" (case-insensitive)
    • begins with "owner-" (case-sensitive)
    • contains the string "-request" anywhere within it (case-sensitive)
  • The envelope sender and envelope recipient are the same
  • The envelope recipient is not found in the message To:, Cc: or Bcc: fields.

Code

#!/bin/sh

if test "$1" = "-h"; then
 echo "*************************************************************"
 echo "*                                                           *"
 echo "* autoreply script by <tobster@brain-force.ch> Version 0.1b *"
 echo "*                                                           *"
 echo "* Usage:    autoreply sender reciever                       *"
 echo "* sender:   the original sender of the mail                 *"
 echo "* reciever: the original reciever of the mail               *"
 echo "* stdin:    on stdin the content of the mail is expected    *"
 echo "*                                                           *"
 echo "*************************************************************"
 exit
fi

msg=""
err=''

while read x1
do
 msg="$msg\n$x1"
done

sendReply ()
{
 mail=/usr/syno/mailstation/sbin/sendmail
 str="From: $2 <$2>\n"
 str=$str"To: <"$1">\n"
 str=$str"Content-Type: multipart/alternative; boundary=\"grenze\"\n"
 str=$str"Subject: Ihre Anfrage an / Your request to "$2"\n\n"
 str=$str"--grenze\nContent-Type: text/plain\nContent-Transfer-Encoding: 7bit\n\nBesten Dank fuer Ihre Anfrage,\n Ihre Anfrage wird so schnell wie moeglich beantwortet\n\nThanks for your request,\n it will be answered asap\n\nGruss / Regards\n\n$2\n"
 str=$str"--grenze\nContent-Type: text/html\nContent-Transfer-Encoding: 7bit\n\n"
 str=$str"<p>Besten Dank für Ihre Anfrage, <br />  Ihre Anfrage ist angekommen und wird schnellstmöglich beantwortet</p><p>Thanks for your request,<br />  Your request has been received and will be anwered asap</p>\n"
 str=$str"<p>Gruss / Regards<br /><br /><a href=\"mailto:"$2"\">"$2"</a></p>\n"
 str=$str"--grenze--"
 echo -e "$str" | $mail -f "$2" -t "$1"
 #echo -e "$3\n"
 #echo -e "$str"
 exit
}


err=$(echo -e $msg | grep -i ^Auto-Submitted: | grep -iv "no" )
if test $? = 0; then
 echo "Message has Auto-Submitted Headers with a value other than \"no\""
 exit
fi

err=$(echo -e $msg | grep -i ^Precedence: | grep -i "junk")
if test $? = 0; then
 echo "Messages has Precedence \"junk\" header"
 exit
fi

err=$(echo -e $msg | grep -i ^Precedence: | grep -i "bulk")
if test $? = 0; then
 echo "Messages has Precedence header \"bulk\""
 exit
fi

err=$(echo -e $msg | grep -i ^Precedence: | grep -i "list")
if test $? = 0; then
 echo "Message has Precedence header with \"list\""
 exit
fi

err=$(echo $1 | egrep -i mailer-daemon\|listserv\|majordomo\|owner-\|\-request)
if test $? = 0; then
 echo "Message seems to be from a mailing list"
 exit
fi

if test "$1" = "$2" ; then
 echo "Fehler: Sender und Empfaenger sind gleich"
 exit
fi

err=$(echo -e $msg | grep -i ^To: | grep "$2")
if test $? = 0; then
 sendReply $1 $2 "$msg"
fi

err=$(echo -e $msg | grep -i ^Cc: | grep "$2")
if test $? = 0; then
 sendReply $1 $2 "$msg"
fi

err=$(echo -e $msg | grep -i ^Bcc: | grep "$2")
if test $? = 0; then
 sendReply $1 $2 "$msg"
fi

echo -e "The original-recipient could not be found in the headers of the mail"