Abwesenheitsmeldungen mit postfix: Unterschied zwischen den Versionen
imported>Jahlives |
imported>Jahlives |
||
Zeile 56: | Zeile 56: | ||
* The envelope recipient is not found in the message To:, Cc: or Bcc: fields. | * The envelope recipient is not found in the message To:, Cc: or Bcc: fields. | ||
=== Code === | === Code === | ||
== autoreply == | |||
<pre> | <pre> | ||
#!/bin/sh | #!/bin/sh | ||
Zeile 206: | Zeile 207: | ||
fi | fi | ||
echo -e $(date +"%b %_d %T")"\trcpt not found in headers (To, Cc or Bcc)\n$1\t$2" >> $log | echo -e $(date +"%b %_d %T")"\trcpt not found in headers (To, Cc or Bcc)\n$1\t$2" >> $log | ||
</pre> | |||
== split.php == | |||
<pre> | |||
#!/usr/bin/php | |||
<?php | |||
$fp=fopen('php://stdin','r'); | |||
$str = array(); | |||
while($line=fgets($fp,4096)){ | |||
$t = trim($line); | |||
if(!empty($t)) { | |||
$bool = true; | |||
} | |||
if($bool === true){ | |||
$str[] = trim($line); | |||
} | |||
} | |||
echo $str[array_search('',$str)+1]; | |||
?> | |||
== trim.php == | |||
<pre> | |||
#!/usr/bin/php | |||
<?php | |||
$fp=fopen('php://stdin','r'); | |||
$str = ''; | |||
while($line=fgets($fp,4096)){ | |||
$str .= $line; | |||
} | |||
echo trim($str); | |||
?> | |||
</pre> | |||
</pre> | </pre> |
Version vom 16. August 2010, 19:51 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} ${mailbox}
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
autoreply
#!/bin/sh ###################################################################### # # # autoreply script for integration into postfix server process # # # # Author: tobi <tobster@brain-force.ch> # # Version: 0.2 # # Date: 11/08/10 # # License: GPL Version 3 # # Free for personal use # # Contact the author for commercial usage # # # # History: * 04/08/10 initial version 0.1 as beta # # * 06/08/10 minor bug fixes # # * 10/08/10 support for template files added # # * 11/08/10 using orginial content and subject # # * 11/08/10 version 0.2 as stable # # * 12/08/10 rfc822 type attachment of original msg # # # # ToDo: * support for txt and html templates (added in 0.2) # # * use original message and subject (added in 0.2) # # * support for attachments in autoreply mail # # * original msg as rfc822 attachment (added in 0.2) # # # # Summary: A small autoreply script that sends messages on every # # mail received ex if you use a info address and want to # # confirm every message that is sent there. # # Some tests are performed before sending the mail: # # # # * is the mail coming from a mailing list? # # * are there typical headers for bulk messages? # # * can the rcpt address been found in msg headers? # # # # Usage: echo msg | autreply sender reciever # # * sender: sender of the original msg. The one who will receive # # the autoreply # # * receiver: the receiver of the original msg. Will be used as # # sender of the autoreply message # # * stdin: on stdin the content of the original msg is expected # # # ###################################################################### if test "$1" = "-h"; then echo "*************************************************************" 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="" log=/opt/var/log/autoreply.log err='' touch $log while read x1 do msg="$msg\n$x1" done sendReply () { mail=/usr/syno/mailstation/sbin/sendmail #text=$(echo -e "$msg" | /opt/etc/postfix/split.php) #subject=$(echo -e "$msg" | grep ^Subject: | cut -c9-) str="From: $2 <$2>\n" str=$str"To: <"$1">\n" str=$str"Content-Type: multipart/mixed; boundary=\"grenze\"\n" str=$str"Subject: Ihre Anfrage an / Your request to "$2"\n\n" str=$str"--grenze\n" str=$str"Content-Type: multipart/alternative; boundary=\"alternative\"\n" eval "t=\"$(cat /opt/etc/postfix/autoreply.txt)\"" str=$str"\n--alternative\n" str=$str$t str=$str"\n\n--alternative\n" eval "t=\"$(cat /opt/etc/postfix/autoreply.html)\"" str=$str$t"\n\n--alternative--\n\n--grenze\n" rfc=$(echo -e "$msg" | /opt/etc/postfix/trim.php) str=$str"Content-Type: message/rfc822\nContent-Disposition: attachment;filename=message.eml;\nContent-Transfer-Encoding: 7bit\n\n$rfc\n\n--grenze--" echo -e "$str" | $mail -f "$2" -t "$1" #echo -e $(date +"%b %_d %T")"\tMessage sent: $1\t$2" >> /opt/var/log/autoreply.log #echo -e "$str" exit } err=$(echo -e $msg | grep -i ^Auto-Submitted: | grep -iv "no" ) t=$? if test $t -eq 0 ; then echo -e $(date +"%b %_d %T")"\tMessage has Auto-Submitted Headers with a value other than \"no\"\n$1\t$2" >> $log exit fi err=$(echo -e $msg | grep -i ^Precedence: | grep -i "junk") t=$? if test $t -eq 0 ; then echo -e $(date +"%b %_d %T")"\tMessages has Precedence \"junk\" header\n$1\t$2" >> $log exit fi err=$(echo -e $msg | grep -i ^Precedence: | grep -i "bulk") t=$? if test $t -eq 0 ; then echo -e $(date +"%b %_d %T")"\tMessages has Precedence header \"bulk\"\n$1\t$2" >> $log exit fi err=$(echo -e $msg | grep -i ^Precedence: | grep -i "list") t=$? if test $t -eq 0 ; then echo -e $(date +"%b %_d %T")"\tMessage has Precedence header with \"list\"\n$1\t$2" >> $log exit fi err=$(echo $1 | egrep -i mailer-daemon\|listserv\|majordomo\|owner-\|\-request) t=$? if test $t -eq 0 ; then echo -e $(date +"%b %_d %T")"\tMessage seems to be from a mailing list\n$1\t$2" >> $log #echo "$msg\n$1\n$2" > /opt/var/log/autoreply.log exit fi if test "$1" = "$2" ; then echo -e $(date +"%b %_d %T")"\tFehler: Sender und Empfaenger sind gleich\n$1\t$2" >> $log exit fi err=$(echo -e $msg | grep -i ^To: | grep "$2") t=$? if test $t -eq 0; then sendReply $1 $2 "$msg" fi err=$(echo -e $msg | grep -i ^Cc: | grep "$2") t=$? if test $t -eq 0; then sendReply $1 $2 "$msg" fi err=$(echo -e $msg | grep -i ^Bcc: | grep "$2") t=$? if test $t -eq 0; then sendReply $1 $2 "$msg" fi echo -e $(date +"%b %_d %T")"\trcpt not found in headers (To, Cc or Bcc)\n$1\t$2" >> $log
split.php
#!/usr/bin/php <?php $fp=fopen('php://stdin','r'); $str = array(); while($line=fgets($fp,4096)){ $t = trim($line); if(!empty($t)) { $bool = true; } if($bool === true){ $str[] = trim($line); } } echo $str[array_search('',$str)+1]; ?> == trim.php == <pre> #!/usr/bin/php <?php $fp=fopen('php://stdin','r'); $str = ''; while($line=fgets($fp,4096)){ $str .= $line; } echo trim($str); ?>