# Postfix

# alle ausgehenden Mails an einen festgelegten Empfänger umleiten

Vor allem auf Entwicklungsservern macht es oft Sinn, dass alle Mails, die diese Server verschicken sollen, nur an einen vorher festgelegten Empfänger gehen, um z.B. echte Kunden nicht zu belästigen oder ungewollte Bestellungen aufzugeben.

Alle Mail soll an entwicklung@meinedomain.de gehen.

Folgende Files müssen angepasst oder erstellt werden:

```
always_bcc=entwicklung@meinedomain.de
transport_maps = hash:/etc/postfix/transport
```

<div data-lang="code etcpostfixmaincf" id="bkmrk-always_bcc%3Dentwicklu-0"><textarea style="display: none;">always\_bcc=entwicklung@meinedomain.de transport\_maps = hash:/etc/postfix/transport</textarea> <textarea readonly="readonly" spellcheck="false" style="position: absolute; bottom: -1em; padding: 0px; width: 1px; height: 1em; outline: currentcolor none medium;" tabindex="0" wrap="off"></textarea></div>Dies bewirkt, dass alle Mails per BCC an entwicklung@meinedomain.de geschickt werden. Jetzt muss nur noch verhindert werden, dass die echten Mails verschickt werden. Dazu folgendes Transport-File erstellen /etc/postfix/transport

```
entwicklung@meinedomain.de : * discard:silently
```

Die erste Zeile sorgt dafür, dass Mails an entwicklung@meinedomain.de auf normalem Weg zugestellt werden. Zeile 2 wirft alle anderen Mails weg.

Das transport-File muss jetzt nur noch gehasht (postmap /etc/postfix/transport) und der Postfix reloaded werden (/etc/init.d/postfix reload).

Die korrekte Funktionalität kann man natürlich in /var/log/mail.log überwachen.

# Disclaimer an ausgehende Mails ranhängen

Postfix selbst läßt keine Änderung des Bodies durchlaufender Mails zu. Um einen Disclaimer oder sonstigen Text ans Ende jeder Mail zu hängen bedienen wir uns des Tools „altermime“ und konfigurieren im Postfix einen zusätzlichen Content-Filter.

Postfix master.cf, ändern der Zeile smtp (-o content\_filter hinzufügen):

<div id="bkmrk-smtp-inet-n---n-----"><div>```
smtp      inet  n       -       n       -       -       smtpd
  -o content_filter=dfilt:
```

</div></div>Am Ende der Datei folgenden Eintrag hinzufügen:

<div id="bkmrk-dfilt-unix---n-n----"><div>```
dfilt     unix    -       n       n       -       -       pipe
    flags=Rq user=filter argv=/etc/postfix/disclaimer -f ${sender} -- ${recipient}
```

</div></div>Erstellen des disclaimer-Scripts /etc/postfix/disclaimer mit folgendem Inhalt:

<div id="bkmrk-%23%21%2Fbin%2Fsh-%23-localize"><div>```
#!/bin/sh
# Localize these.
INSPECT_DIR=/var/spool/filter
SENDMAIL="/usr/sbin/sendmail -G -i"

# don't alter mails from the addresses in this file
DISCLAIMER_ADDRESSES=/etc/postfix/disclaimer_addresses

# Exit codes from <sysexits.h>
EX_TEMPFAIL=75
EX_UNAVAILABLE=69

# Clean up when done or when aborting.
trap "rm -f in.$$" 0 1 2 3 15

# Start processing.
cd $INSPECT_DIR || { echo $INSPECT_DIR does not exist; exit
$EX_TEMPFAIL; }

cat >in.$$ || { echo Cannot save mail to file; exit $EX_TEMPFAIL; }

# obtain From address
from_address=`grep -m 1 "^From:" in.$$ | cut -d "<" -f 2 | cut -d ">" -f 1  | sed 's/^From: //g' | awk '{print $1}'`

if [ ! `grep -wi ^${from_address}$ ${DISCLAIMER_ADDRESSES}` ]; then
  /usr/bin/altermime --input=in.$$ \
                     --disclaimer=/etc/postfix/disclaimer.txt \
                     --disclaimer-html=/etc/postfix/disclaimer.txt || \
                     { echo Message content rejected; exit $EX_UNAVAILABLE; }
fi

$SENDMAIL "$@" <in.$$

exit $?
```

</div></div>Das Script jetzt nocht ausführbar machen („chmod og+x /etc/postfix/disclaimer; chgrp filter /etc/postfix/disclaimer“).

Anlegen einer Datei mit dem Disclaimertext /etc/postfix/disclaimer.txt:

<div id="bkmrk-testfirma-blastra%C3%9Fe-"><div>```
Testfirma
Blastraße 1
12345 Blastadt

Alle Rechte vorbehalten!
```

</div></div>Anlegen einer Datei /etc/postfix/disclaimer\_addresses mit Mailadressen, die NICHT mit einem Disclaimer versehen werden sollen:

<div id="bkmrk-noreply%40testfirma.de"><div>```
noreply@testfirma.de
```

</div></div>Jetzt noch den Postfix reloaden (service postfix reload). Nun werden alle Mails, deren Absender nicht mit einer Adresse aus disclaimer\_addresses übereinstimmt, mit dem konfigurierten Disclaimer versehen.

Wenn die Funktion von „disclaimer\_addresses“ umgedreht werden soll, sprich nur Mails von Absendern, die in der Datei enthalten sind, werden mit einem Disclaimer versehen, dann muss nur das „!“ in Zeile 34 entfernt werden.

<p class="callout warning">Da altermime den Body der Mail verändert könnnen PGP-verschlüsselte Mails hinterher nicht mehr entschlüsselt werden!</p>

# header-Checks

Ein Beispiel für die Datei /etc/postfix/header\_checks

<div id="bkmrk-if-%2F%5Esubject%3A%2F-%2F%5Esub"><div>```
IF /^Subject:/

/^Subject: Belebt Geist und Korper/                           REJECT  Message content rejected; No spam please! (H1)
/^Subject: Bitte tiefer eindringen und abladen/               REJECT  Message content rejected; No spam please! (H2)
/^Subject: Nie mehr zu fruh kommen/                           REJECT  Message content rejected; No spam please! (H3)
/^Subject: Privatkredite/                                     REJECT  Message content rejected; No spam please! (H4)
/^Subject: schoolgirls/                                       REJECT  Message content rejected; No spam please! (H5)
/^Subject: Russian/                                           REJECT  Message content rejected; No spam please! (H6)
/^Subject: Potenzprobleme/                                    REJECT  Message content rejected; No spam please! (H7)
/^Subject: Probieren Sie es/                                  REJECT  Message content rejected; No spam please! (H8)
/^Subject: Teenage/                                           REJECT  Message content rejected; No spam please! (H9)
/^Subject: Spitzenduell/                                      REJECT  Message content rejected; No spam please! (H10)
/^Subject: Energy/                                            REJECT  Message content rejected; No spam please! (H11)
/^Subject: sparen/                                            REJECT  Message content rejected; No spam please! (H12)
/^Subject: Banish/                                            REJECT  Message content rejected; No spam please! (H13)
/^Subject: rufen/                                             REJECT  Message content rejected; No spam please! (H14)
/^Subject: Rabatte/                                           REJECT  Message content rejected; No spam please! (H15)
/^Subject: safe/                                              REJECT  Message content rejected; No spam please! (H16)
/^Subject: Ficken/                                            REJECT  Message content rejected; No spam please! (H17)
/^Subject: Financial/                                         REJECT  Message content rejected; No spam please! (H18)
/^Subject: girl/                                              REJECT  Message content rejected; No spam please! (H19)
/^Subject: Happy/                                             REJECT  Message content rejected; No spam please! (H20)
/^Subject: Newsletter/                                        REJECT  Message content rejected; No spam please! (H21)
/^Subject: lebt/                                              REJECT  Message content rejected; No spam please! (H22)
/^Subject: Man/                                               REJECT  Message content rejected; No spam please! (H23)
/^Subject: PAYMENT/                                           REJECT  Message content rejected; No spam please! (H24)
/^Subject: Pedolover/                                         REJECT  Message content rejected; No spam please! (H25)
/^Subject: Pedo/                                              REJECT  Message content rejected; No spam please! (H26)
/^Subject: Medically/                                         REJECT  Message content rejected; No spam please! (H27)
/^Subject: Pics/                                              REJECT  Message content rejected; No spam please! (H28)
/^Subject: %/                                                 REJECT  Message content rejected; No spam please! (H29)
ENDIF
```

</div></div>Einzelne Regeln lassen sich auch folgendermaßen testen:

<div id="bkmrk-echo-%27subject%3A-beleb">```
echo 'Subject: Belebt Geist und Korper' | postmap -fq - pcre:/etc/postfix/header_checks
```

</div>

# Mail aus Mailqueue löschen

Als Admin kennt man das. Mal ein durchdrehendes Script, mal ein Spamopfer… Gelegentlich ist es nötig Mails schnell aus der Postfix-Queue zu löschen.

#### Alle Mails aus der Queue löschen

Das könnte wichtig werden, wenn die Queue eigentlich nur mit double-bounces verstopft ist. Achtung, dieses Kommando räumt die Queue richtig auf.

```
postsuper -d ALL
```

<div id="bkmrk-"></div>#### Alle Mails mit bestimmten Inhalt löschen

Wenn z.B. ein Kontaktformular eines Forum missbraucht wurde und in allen (ungewünschten) Mails der gleiche Text vorkommt.

```
grep -rl "Ein netter Gruss von" * | cut -d"/" -f2 | postsuper -d -
```

<div id="bkmrk--1"></div>#### Mail mit bestimmten Sender oder Empfänger löschen

Dies löscht Mails mit einem bestimmten Sender oder Empfänger:

```
postqueue -p | tail -n +2 | awk 'BEGIN { RS = "" } /@yahoo\.it$/ { print $1 }' | tr -d '*!' | postsuper -d -
```

<div id="bkmrk-mailq-%7C-tail--n-%2B2-%7C"></div>#### Mail an bestimmten Empfänger löschen

Als Einzeiler:

```
postqueue -p | grep -v '^ *(' | awk 'BEGIN { RS = "" } { if ($8 == "benutzer@deinserver.de")print $1 }' | tr -d '*!' | postsuper -d -
```

Oder über ein Perl-Script mit einem regulären Ausdruck:

```
#!/usr/bin/perl
 
$REGEXP = <a href="http://perldoc.perl.org/functions/shift.html" rel="noopener" target="_blank">shift</a> || <a href="http://perldoc.perl.org/functions/die.html" rel="noopener" target="_blank">die</a> "no email-adress given (regexp-style, e.g. bl.*\@yahoo.com)!";
 
@data = qx</usr/sbin/postqueue -p>;
for (@data) {
  if (/^(\w+)(\*|\!)?\s/) {
     $queue_id = $1;
  }
  if($queue_id) {
    if (/$REGEXP/i) {
      $Q{$queue_id} = 1;
      $queue_id = "";
    }
  }
}
 
#open(POSTSUPER,"|cat") || die "couldn't open postsuper" ;
<a href="http://perldoc.perl.org/functions/open.html" rel="noopener" target="_blank">open</a>(POSTSUPER,"|postsuper -d -") || <a href="http://perldoc.perl.org/functions/die.html" rel="noopener" target="_blank">die</a> "couldn't open postsuper" ;
 
foreach (<a href="http://perldoc.perl.org/functions/keys.html" rel="noopener" target="_blank">keys</a> %Q) {
  <a href="http://perldoc.perl.org/functions/print.html" rel="noopener" target="_blank">print</a> POSTSUPER "$_\n";
};
<a href="http://perldoc.perl.org/functions/close.html" rel="noopener" target="_blank">close</a>(POSTSUPER);
```

<div id="bkmrk--2"></div>

# Mails werden manchmal doppelt zugestellt

Manchmal werden Mails doppelt zugestellt, dies wird durch die doppelte Auswertung der virtual\_alias\_maps in Postfix, einmal vor dem content\_filter, und dann nach dem content\_filter, wenn Amavisd-new die Mail wieder an Postfix zurückgibt, hervorgerufen.

Um dies abzustellen muss in der /etc/postfix/master.cf folgendes konfiguriert werden:

<div id="bkmrk-%5B...%5D-127.0.0.1%3A1002"><div>```
[...]
127.0.0.1:10025 inet n  -       n     -       -  smtpd
     -o content_filter=
     -o local_recipient_maps=
     -o relay_recipient_maps=
     -o smtpd_restriction_classes=
     -o smtpd_delay_reject=no
     -o smtpd_client_restrictions=permit_mynetworks,reject
     -o smtpd_helo_restrictions=
     -o smtpd_sender_restrictions=
     -o smtpd_recipient_restrictions=permit_mynetworks,reject
     -o smtpd_data_restrictions=reject_unauth_pipelining
     -o smtpd_end_of_data_restrictions=
     -o mynetworks=127.0.0.0/8
     -o smtpd_error_sleep_time=0
     -o smtpd_soft_error_limit=1001
     -o smtpd_hard_error_limit=1000
     -o smtpd_client_connection_count_limit=0
     -o smtpd_client_connection_rate_limit=0

Hinzufügen:
     -o receive_override_options=no_address_mappings
```

</div></div>falls es die Zeile „-o receive\_override\_options=“ bereits gibt, muss „no\_address\_mappings“ einfach durch Komma getrennt hinten angehängt werden.

# Mails über ein Relay verschicken, außer bestimmte Empfänger

Alle ausgehenden Mails sollten über ein Relay verschickt werden. Nur Mails an bestimmte Empfänger sollen direkt zugestellt werden.

In der Postfix-Standardkonfiguration werden noch folgende Anpassungen gemacht:

an /etc/postfix/main.cf wird folgende Zeile angehängt. Die Variable relay\_host wird nicht konfiguriert

<div id="bkmrk-transport_maps-%3D-has"><div>```
transport_maps = hash:/etc/postfix/transport
```

</div></div>Empfänger, an die direkt zugestellt werden soll, werden in der Datei /etc/postfix/transport eingetragen. Das Standard-Relay wird die letzte Zeile in der Datei

<div id="bkmrk-testuser%40domain1.de-"><div>```
testuser@domain1.de :
direkt@domain2.de :
* smtp:mein.relay.de
```

</div></div>Nun muss noch das File-Hash erzeugt werden:

<div id="bkmrk-postmap-%2Fetc%2Fpostfix"><div>```
postmap /etc/postfix/transport
```

</div></div>und die Postfix Konfiguration neu geladen werden:

<div id="bkmrk-%2Fetc%2Finit.d%2Fpostfix-"><div>```
/etc/init.d/postfix reload
```

</div></div>jetzt einige Testmails verschicken und den Weg in /var/log/mail.log überprüfen:

<div id="bkmrk-direkt%3A-echo-%22testma">```
direkt:
echo "Testmail direkt" | mail -s Test1 direkt@domain2.de

über das Relay:
echo "Testmail relay" | mail -s Test2 nichtdirekt@domain2.de
```

</div>

# Postfix catch-all Mailaccount

Dies beschreibt die Einrichtung eines catch-all Mailaccounts im Postfix-MTA

<div id="bkmrk-als-root-die-datei-%2F">- <div>Als root die Datei /etc/postfix/main.cf bearbeiten und folgenden Eintrag vornehmen/aktivieren:</div>

```
virtual_alias_maps = hash:/etc/postfix/virtual
```

- <div>in der Datei /etc/postfix/virtual werden nun die die virtuellen Accounts definiert:</div>

```
# lokale user
heinz@server.de     heinz
bert@server.de      bert 
schwuffi@server.de  schwuffi

# catch-all 
@server.de          mailsammler
```

- <div>um daraus das DB-File für Postfix zu erzeugen:</div>

```
postmap /etc/postfix/virtual
```

- <div>jetzt noch den Postfix reloaden mit:</div>

```
postfix reload
```

</div>

# Flush mailqueues - Auslieferung erzwingen

ganz einfach über folgenden Befehl:

<div id="bkmrk-postqueue--f"><div>```
postqueue -f
```

</div></div>Um die Queue betrachten und z.B. nur einzelne Mails zu flushen oder auf HOLD zu setzen, bietet sich das Tool „pfqueue“ an, dass bei allen gängigen Distris in den Repos enthalten sein sollte.