Emailserver mit Postfix und Dovecot: Difference between revisions

From Linuxwiki
Jump to navigation Jump to search
 
(63 intermediate revisions by 2 users not shown)
Line 10: Line 10:
* '''Art des Servers: '''Internet Site<br>
* '''Art des Servers: '''Internet Site<br>
* '''Root and postmaster mail recipient:''' ein Postfach eintragen, z.B.postmaster@example.de <br>
* '''Root and postmaster mail recipient:''' ein Postfach eintragen, z.B.postmaster@example.de <br>
* '''Other destinations to accept mail for (blank for none): z.B. mail.example.de, localhost, $mydomain (kann man erstmal die defaults belassen)
* '''Other destinations to accept mail for (blank for none):''' z.B. mail.example.de, localhost, $mydomain (kann man erstmal die defaults belassen)
* '''Force synchronous updates on mail queue:''' no'''
* '''Force synchronous updates on mail queue:''' no'''
* '''Local subnets:''' 127.0.0.1/8, 192.168.63.0/24 (hier das eigene Netz ergänzen)
* '''Local subnets:''' 127.0.0.1/8, 192.168.63.0/24 (hier das eigene Netz ergänzen)
Line 22: Line 22:
ändern.
ändern.


Danach befinden sich alle relevanten Dateien im Verzeichnis ''/etc/postfix''.
Alle relevanten Dateien befinden sich im Verzeichnis ''/etc/postfix''.


== Konfiguration ==
== Konfiguration ==
Line 91: Line 91:
# dehydrated -c
# dehydrated -c


Dies setzt allerdings einen Webserver voraus, der auf Port 80 lauscht. Gibt es diesen nicht, kann mal alternativ letsencrypt via DNS verwenden (https://letsencrypt.org/docs/challenge-types).
Dies setzt allerdings einen [[Webserver_mit_Apache | Webserver]] voraus, der auf Port 80 lauscht. Gibt es diesen nicht, kann mal alternativ letsencrypt via DNS verwenden (https://letsencrypt.org/docs/challenge-types).


=== Alternative eigene CA (nicht empfohlen) ===
=== Alternative eigene CA (nicht empfohlen) ===
Line 167: Line 167:
$ openssl pkcs12 -export -out mx.example.de.pfx -inkey mx.example.de.key -in mx.example.de.crt
$ openssl pkcs12 -export -out mx.example.de.pfx -inkey mx.example.de.key -in mx.example.de.crt
pfx-File und Passwort dem User zukommen lassen.
pfx-File und Passwort dem User zukommen lassen.

'''Spoiler:''' <br>
[[ Emailserver_mit_Postfix_und_Dovecot#Dovecot | Dovecot ]] „vergisst“ manchmal das neue Zertifikat und behält die alte Version, d.h. die meisten Mailclients spoolen dann keine neuen Emails mehr. In diesem Fall den Dovecot Service neu starten.


== SASL ==
== SASL ==
Line 183: Line 186:


Im Mailclient äußert sich das Verhalten so, dass man beim ersten Senden einer Nachricht sein Mailbox-Passwort angeben muss.
Im Mailclient äußert sich das Verhalten so, dass man beim ersten Senden einer Nachricht sein Mailbox-Passwort angeben muss.
Bevor dieses Feature aktiviert wird, muss es einen IMAP-Server geben (s. nächstes Kapitel).
Bevor dieses Feature aktiviert wird, muss es einen IMAP-Server geben (s. [[#Dovecot|nächstes Kapitel]] ).


== Maps ==
== Maps ==
Line 225: Line 228:
=== Virtual Mailbox ===
=== Virtual Mailbox ===
virtual_mailbox_maps = hash:/etc/postfix/virtual
virtual_mailbox_maps = hash:/etc/postfix/virtual
Locations der Mailboxen des imap-Servers (näheres unter #Dovecot)
Locations der Mailboxen des imap-Servers (näheres unter [[ Emailserver_mit_Postfix_und_Dovecot#Dovecot | Dovecot ]])


sunflower@example.de    example.de/sunflower/
sunflower@example.de    example.de/sunflower/
Line 244: Line 247:
administrator root
administrator root
root    sunflower
root    sunflower
fortune:  fortune
lmaa@ihr-koennt-mich-alle.de            fortune
Letzteres ist eine Pipe. Dazu später mehr.
Letzteres ist eine Pipe. Dazu später mehr.


Line 252: Line 255:


=== Einfaches Beispiel: Emails von einer Domain auf eine andere weiterleiten ===
=== Einfaches Beispiel: Emails von einer Domain auf eine andere weiterleiten ===
Nehmen wir an, wir haben einen mailserver1 in der Domain example.com. Dieser soll alle Email die an <userXY>@example.com eintreffen, an <userXY>@example.de weiterleiten. Auch hier ist eine Eintrag in der o.g. ''virtual_maps'' Datei nötig:
Nehmen wir an, wir haben einen Emailserver1 in der Domain example.com. Dieser soll alle Email die an <userXY>@example.com eintreffen, an <userXY>@example.de weiterleiten. Auch hier ist eine Eintrag in der o.g. ''virtual_maps'' Datei nötig:
@example.com @example.de
@example.com @example.de
Nun werden alle example.com-Emails zum zuständigen Emailserver für example.de weitergeleitet. Der user part bleibt unverändert.
Nun werden alle example.com-Emails zum zuständigen Emailserver für example.de weitergeleitet. Der user part bleibt unverändert.

=== Transports ===
Transports sind die Art und Weise, wie eine eingehende Mail behandelt wird, z.B. lokal in eine Datei speichern, an einen imap-Server weiterreichen oder ein Script ausführen.

Hier ein Beispiel: <br>
Wenn auf eine bestimmte Adresse geschickt wird, soll ein Script ausgeführt werden, das dem Absender einen Zufallsspruch zurücksendet '''und''' die Mail gleichzeitig in ein Postfach einliefert.
Schritte:

1. Alias definieren (virtual_maps):

fortune@example.de           fortune

2. Alias auf einen Transport mappen (transports):

fortune@example.de     randomphrase:

3. Transport definieren (master.cf):

<pre>
randomphrase      unix  - n n - - pipe
  flags=h user=vmail:vmail argv=/usr/local/bin/randomphrase.pl ${sender}
</pre>

(Den User vmail muss es natürlich in der passwd geben, z.B. so:
vmail:x:4000:4000::/home/vmail:/user/sbin/nologin
)

4. Script hinterlegen:
/usr/local/bin/randomphrase.pl
für alle ausführbar machen

Mit dem Script [[ randomphrase.pl ]] wird ein Zufallsspruch erzeugt. Dafür muss das Paket ''fortune-mod'' installiert sein.
Zum Weiterschicken der Email wird das Script /usr/local/bin/deliver_mail.sh aufgerufen. ([[File:Deliver_mail.sh]])
<br> Hierfür muss der User vmail in der Datei ''/etc/sudoers.d/vmail'' berechtigt werden:
vmail ALL=(root) NOPASSWD: /usr/local/bin/deliver_mail

Eine Email an die Adresse fortune@example.de erzeugt nun eine Antwort an die Absenderadresse mit einem Zufallsspruch.

== Multidomain ==

Natürlich kann Postfix auch Emails für mehrere Domains annehmen. Dafür gibt es den Parameter „virtual_mailbox_domains“:

virtual_mailbox_domains = example.de example.com ihr-koennt-mich-alle.de
Die Variable $mydomain sollte dann aus mydestination entfernt werden.

== Special DNS Records ==
=== SPF (Sender Policy Framework) ===
Mit einem RR-Type TXT kann man eine Liste von Emailservern definieren, die als Absender die Emaildomain verwenden dürfen. Generiert jemand eine Fakeemail von einem anderen System aus, kann diese abgewiesen werden.

Beispiel für einen DNS TXT Record:
IN TXT  "v=spf1 mx:example.de a:foo.example.de ip4:8.15.47.11/32 ip6:2008:15:5:47::11/48 ip6:2008:15:5:47::12/48 -all"

Howto: <br>
https://dmarcian.com/create-spf-record/ <br>
http://www.open-spf.org/SPF_Record_Syntax/

SPF in Postfix integrieren:

Nun ist die Domain vor Missbrauch vor Fakeeemails geschützt. Jetzt gibt es aber noch die andere Seite zu beachten. Postfix soll ebenfalls die SPF-Records anderer Emaildomains prüfen und die Email ggf ablehnen.
https://makeityourway.de/enabling-spf-sender-policy-framework-checking-on-postfix/

Hier in Kürze zusammengefasst, was es zu beachten gibt:
# apt install postfix-policyd-spf-python
Die Config-Datei ''/etc/postfix-policyd-spf-python/policyd-spf.conf'' liefert bereits brauchbare Defaults, optional kann man noch eine Whitelist ergänzen z.B.

Domain_Whitelist = example.com
In der master.cf ergänzen:
<pre>
policyd-spf  unix  -     n       n       -       -       spawn
  user=policyd-spf argv=/usr/bin/policyd-spf
</pre>

In der main.cf ergänzen:
smtpd_recipient_restrictions =
(...)
check_policy_service unix:private/policyd-spf
(…)
'''Achtung:''' Wenn es schon einen check_policy_service Eintrag gibt, '''keinesfalls''' einen weiteren Eintrag anhängen, sondern eine neue Zeile aufmachen!
policy-spf_time_limit = 3600s

# postfix reload

Ein paar Testemails einkippen und mail.log gucken.

=== DMARC (Domain based Message Authentication, Reporting and Conformance) ===
https://dmarcian.com/dmarc-record/

Beispiel für einen DNS TXT Record:
_dmarc                  IN TXT   "v=DMARC1;p=quarantine;rua=mailto:postmaster@example.de"

In dem Fall werden verdächtige Emails in einen Quarantäne-Ordner verschoben und ein Report an den postmaster versandt.
Für die Integration in Postfix gibt es das Paket opendmarc.
Implementierung von SPF, DKIM und DMARC in Postfix:

https://www.skelleton.net/2015/03/21/how-to-eliminate-spam-and-protect-your-name-with-dmarc/
(untested)

== Nützliche Commands ==
Erzeugen eines database files aus einer Textdatei:
postmap <filename>
Alle Configparameter anzeigen:
postconf
Konfigprüfung:
postfix check
Mailqueue anschauen:
mailq
Alle Messages in der Queue ausliefern:
postqueue -f
Nur eine bestimmte Message ausliefern:
postqueue -i <ID>
Message löschen:
postsuper -d <ID>
Alle Messages löschen (!):
postsuper -d ALL
Inhalt einer Message anschauen:
postcat -vq <ID>

== Logfile ==

Geloggt wird nach ''/var/log/mail.log'' (alles) bzw. Errors nach ''/var/log/mail.err'' und Warnings nach ''/var/log/mail.warn''.
<br>Protipp: Alias anlegen:
maillog='tail -f /var/log/mail.log'

== Greylisting und Antispam ==

Zur Bekämpfung der Spamflut gibt es das praktische Programm '''„Postgrey“'''. Unter Debian kann dieses als Paket installiert werden. Dieses wird in die main.cf im Abschnitt smtpd_recipient_restrictions eingebunden.
smtpd_recipient_restrictions =
 permit_mynetworks
permit_sasl_authenticated
permit_tls_clientcerts
reject_unauth_destination
'''reject_non_fqdn_sender'''
'''reject_non_fqdn_recipient'''
'''reject_rbl_client bl.spamcop.net'''
'''check_policy_service inet:127.0.0.1:10023'''

(Die Blacklist ''dnsbl.sorbs.net'' wurde hier außen vor gelassen, da diese so ziemlich alles blockt, z.B. alle yahoo- oder gmx-Adressen.)
Damit das funktioniert, muss natürlich noch Postgrey selbst an den Start gebracht werden.
Hierfür wird die Datei ''/etc/default/postgrey'' bearbeitet. Hier ein Beispiel:
POSTGREY_OPTS="--inet=10023 --auto-whitelist-clients=8  
POSTGREY_TEXT="Busy. Come back in 5 minutes."

Der Service lauscht also auf Port 10023. Im obigen Beispiel wird ein Absender beim 8. erfolgreichen Zustellversuch automatisch gewhitelistet (optionaler Parameter ''--auto-whitelist-clients'', evtl. Zahl erhöhen oder Parameter ganz weglassen).

Anschließend wechselt man ins Verzeichnis ''/etc/postgrey''. Dort gibt es 2 Whitelistings. Die Absender stehen in '''whitelist_clients'''. Dort stehen bereits IPs und Domains diverser Provider. Man kann dort selbst Einträge hinzufügen (z.B. example.ch).

In der Datei '''whitelist_recipients''' kann man alle Empfänger der eigenen Domain eintragen, die auf jeden Fall immer Emails bekommen sollen. z.B. postmaster@, abuse@.<br>
Nach getaner Anpassung, den postgrey-Service (neu)starten.
# service postgrey restart
Überprüfen, ob der Dienst läuft z.B. mit:
# lsof -i :10023
Anschließend Postfix reloaden
# postfix reload
und die Mailbox(en) beobachten, hinsichtlich Spamaufkommen.

''(Quelle: Artikel „Postzusteller“, Admin-Magazin, Ausgabe 03-2013)''


= Dovecot =
= Dovecot =


Open Source IMAP-Server zum Einliefern der Emails in Postfächer mittels POP3 oder IMAP bzw. IMAPs. Im folgenden wird nur auf IMAPs eingegangen.
= Erweiterungen =

== Postgrey ==
== Installation ==

Es empfiehlt sich, den Dovecot auf demselben System zu installieren wie Postfix. Andere Fälle werden hier nicht berücksichtigt.

Installation des imapd mittels
# apt install dovecot-imapd

Dies reicht für alle Grundfunktionen der Emailauslieferung. Für erweiterte Optionen wie z.B. Filterfunktion können weiter dovecot-Pakete wie '''dovecot-antispam, dovecot-sieve''' installiert werden.

User (i.d.F. ''vmail'') als Owner für die Mailboxen anlegen:

useradd -u 4000 -m -d /home/vmail -s /user/sbin/nologin vmail

== Konfiguration ==

Configdateien in ''/etc/dovecot/conf.d'' anpassen.
Die Datei ''/etc/dovecot/dovecot.conf'' inkludiert per Default alle Dateien unter conf.d/*.conf.

=== Usermanagement ===

Hier ein Beispiel, wo User in einer separaten Datei abgelegt werden.

''10-auth.conf:''
<pre>
disable_plaintext_auth = no
auth_username_format = %n
auth_master_user_separator = *
auth_mechanisms = plain login
!include auth-master.conf.ext
</pre>
Wenn kein auth über pam:
#!include auth-system.conf.ext

Plaintext Auth kann man erlauben, weil die User-Passwörter als gehashter String übertragen werden. Für die Kommunikation zwischen Postfix und Dovecot spielt das ohnehin keine Rolle, da sich beide Dienste auf einem Server befinden. Der Zugriff von einem MUA aus wird über TLS/SSL erfolgen (s.u.).

master user anlegen (optional):
<pre>
doveadm pw -p supergeheim -s SHA512-CRYPT -u administrator@example.de
</pre>
Den Output zusammen mit dem Usernamen in die Datei master-users pasten.
<pre>
cat  ../master-users     
administrator@example.de:{SHA256-CRYPT}$5$9zrt7/e2CDkPmSuA$SNEkm/L4XZcYFAbYkJp5ESl9u35fVBSd4ukO0dm5yp3
</pre>

Sonstige User anlegen:
<pre>
doveadm pw -p strenggeheim -s SHA512-CRYPT -u sunflower@example.de
</pre>
→ /etc/dovecot/users:
<pre>
sunflower:{SHA256-CRYPT}$5$D3PhhtqUhRXT7cmZ$E5244BpvNafb.9FtbhF9AUfbvw8XpnOJhPyM/q/rRN2:::Sun Flo,,,:/var/mail/example.de/sunflower:/bin/false
</pre>
Hier sollten keine Abkürzungen wie ''%d'' oder ''%n'' stehen, weil diese nicht (von sieve, s.u.) bzw. nur teilweise (von dovecot) interpretiert werden.

Damit der Account auch Email bekomemn kann, ergänzt man die virtual table im Postfix directory:
cat sunflower@example.de example.de/spambucket >> /etc/postfix/virtual
Aktivieren mit
postmap virtual
postfix reload

=== Dateirechte ===

Die Files master-users, users sollten nur von dovecot gelesen werden können!
<pre>
# chgrp dovecot /etc/dovecot/*users
# chmod o-r /etc/dovecot/*users
</pre>
Mailbox anlegen und User berechtigen:
<pre>
# maildirmake.dovecot /var/mail/<username>
# chown -R vmail.vmail /var/mail/<username>
</pre>
Achtung, der Parameter %d wird nicht als Domain gelesen, sondern bleibt leer!<br>
=> mail_location = maildir:/var/mail/%d/%n <br>
bedeutet, dass die Emails in /var/mail/<username> liegen. D.h. die Postfächer müssen direkt unter /var/mail angelegt werden.

User im Postfix anlegen, in den virtual maps, s. o.

Kontrolle:
<pre>
# doveadm user <username>
</pre>

=== IMAP konfigurieren ===
Protipp: erstmal conf.d wegsichern:
<pre>
rsync -av /etc/doveconf/conf.d /etc/doveconf/conf.d.orig
</pre>
Folgende Konfigurationsdateien in conf.d entsprechend anpassen:
* '''10-auth.conf'''
<pre>
disable_plaintext_auth = no
auth_username_format = %n
auth_master_user_separator = *
auth_mechanisms = plain login

!include auth-master.conf.ext
!include auth-system.conf.ext
!include auth-passwdfile.conf.ext
</pre>
* '''10-mail.conf'''
<pre>
mail_location = maildir:/var/mail/%d/%n
namespace inbox {
 inbox = yes
}
mail_uid = 4000
mail_gid = 4000
mail_privileged_group = mail
</pre>
* '''10-master.conf'''
<pre>
service imap-login {
  inet_listener imaps {
   port = 993
   ssl = yes
 }
}
service auth {
 unix_listener auth-userdb {
   user = vmail  
   group = vmail
 }
 unix_listener /var/spool/postfix/private/auth {
   mode = 0666
   user = postfix
   group = postfix
 }
}
service stats {
unix_listener stats-reader {
               user = vmail
               group = vmail
               mode = 0660
     }

unix_listener stats-writer {
       user = vmail
       group = vmail
       mode = 0660
    }
}
</pre>
* '''10-ssl.conf'''
<pre>
# (z.B. Postfix certs verwenden)
ssl = yes
ssl_cert = </etc/ssl/certs/mx.example.de.crt
ssl_key = </etc/ssl/private/mx.example.de.key
ssl_client_ca_dir = /etc/ssl/certs
ssl_dh = </usr/share/dovecot/dh.pem
</pre>

Zertifikate generieren: s. https://wiki.nomorebluescreen.de/index.php?title=Webserver_mit_Apache#Alternative_letsencrypt

'''Spoiler:'''<br>
Jedes Mal, wenn das Zertifikat ausgetauscht wird, muss der dovecot-Service neu gestartet werden, damit das neue Zertifikat auch eingelesen wird.

'''Überprüfen, welche Dateien angefasst wurden:'''
<pre>
diff -quw conf.d.orig conf.d
Files conf.d.orig/10-ssl.conf and conf.d/10-ssl.conf differ
Files conf.d.orig/15-lda.conf and conf.d/15-lda.conf differ
Files conf.d.orig/20-imap.conf and conf.d/20-imap.conf differ
Files conf.d.orig/20-managesieve.conf and conf.d/20-managesieve.conf differ
Files conf.d.orig/90-sieve.conf and conf.d/90-sieve.conf differ
Files conf.d.orig/auth-passwdfile.conf.ext and conf.d/auth-passwdfile.conf.ext differ
</pre>

'''Ausgabe der gesamten Config'''

# doveconf -n

==== Sieve ====
Engine zum Filtern von Emails

dovecot-sieve und dovecot-managesieved installieren

'''15-lda.conf:'''
<pre>
lda_mailbox_autocreate = yes
lda_mailbox_autosubscribe = yes
protocol lda {
 mail_plugins = $mail_plugins sieve
}
</pre>

'''20-managesieve.conf:'''
<pre>
protocols = $protocols sieve
</pre>

'''90-sieve.conf:'''
<pre>
plugin {
 sieve = file:~/sieve;active=~/.dovecot.sieve
sieve_default = /var/lib/dovecot/sieve/default.sieve
 sieve_global_dir = /var/lib/dovecot/sieve
}
</pre>
Kontrolle, ob der sieve-Service läuft und auf Port 4190 lauscht.
<pre>
# service dovecot restart
# ss -plnt | grep 4190
</pre>
Da der User i.a. nicht direkt auf dem Emailserver sein /home mit den Sieve-Regeln editieren kann, erfolgt die weitere Konfiguration im Email-Client (s.u.).

Achtung Bug:<br>
Da sieve/dovecot die Variable %n in der users-Datei nicht interpretiert, sollte man diese dort nicht verwenden. Somit kann es passieren, dass von roundcube ein Verzeichnis ''%n'' angelegt wird, in dem sich eine gemeinsame sieve config für '''alle''' User befindet.

=== Transport von Postfix zu Dovecot ===

Dem Postfix muss noch beigebracht werden, dass die Emails zum Dovecot gehen.<br>
'''master.cf''' im Postfix anpassen (die Einträge in den {} gehören so, nicht ersetzen!):
<pre>
dovecot unix - n n - - pipe flags=DRhu user=vmail:vmail
argv=/usr/lib/dovecot/deliver -a ${recipient} -f ${sender} -d $
{user} @${nexthop} -m ${extension}
</pre>
und einen mailbox_command Eintrag in der main.cf vornehmen:
<pre>
mailbox_command = /usr/lib/dovecot/dovecot-lda -f "$SENDER" -a "$RECIPIENT"
</pre>
(https://doc.dovecot.org/configuration_manual/howto/dovecot_lda_postfix/#howto-dovecot-lda-postfix)

Danach noch postfix und dovecot service restarten.

== Logging ==

Logfiles gehen ebenfalls (wie postfix) nach /var/log/mail.log <br>
Nützlicher Alias:
<pre>
maillog='tail -f /var/log/maillog'
</pre>

Debugging einschalten:
mail_debug = yes
in der Datei
''10-logging.conf''.

'''Protipp:'''
Wenn im Log folgender Fehler erscheint:

Mar 27 08:03:56 aphantopus postfix/pipe[2317]: 521066005D: to=<sunflower@example.de>, relay=dovecot, delay=0.3, delays=0.19/0.04/0/0.07, dsn=2.0.0, status=sent (delivered via dovecot service (lda(sunflower@example.de,)Error: net_connect_unix(/var/run/dovecot/stats-writer) failed: Permission denied))

=> In der ''10-master.conf'' '''stats''' für User vmail erlauben (s.o.)

= Roundcube =

Praktisches Webfrontend zum Abholen und Verschicken von Emails

Erst mysql-server installieren, sonst bricht die Installation mit einem Fehler ab
# apt install mariadb-server roundcube
Die dbconfig-common Frage mit „yes“ beantworten, mysql-Passwort setzen.
Config Datei anpassen (''/etc/roundcube/config.inc.php''):
$config['smtp_server'] = 'localhost';
$config['smtp_port'] = 25;

== Plugins ==

Standard-Plugings installieren
# apt install roundcube-plugins

Weitere Plugins installieren:
# apt install roundcube-plugins-extra git curl composer
(composer braucht man für die Installation von Plugins, git, weil die meisten aus github kommen)<br>
Die, die man haben will, in der Datei ''/etc/roundcube/config.inc.php'' enablen

$config['plugins'] = array(
       'compose-addressbook',
'markasjunk2',
       'fail2ban'
);

Übersicht über die offiziellen Plugins:

https://plugins.roundcube.net/

Plugins, die es nicht als Paket gibt:<br>
Schritte:<br>
* README lesen
* Plugin als zip herunterladen, nach ''/usr/share/roundcube/plugins'' entpacken
* (evtl. umbenennen)
* ''/etc/roundcube/config.inc.php'' bearbeiten:
Abschnitt
$config['plugins'] = array(
suchen und fehlendes Plugin ergänzen

== Filter Plugin for Sieve ==

Achtung, nicht das Plugin „filter“ verwenden, sondern '''managesieve''' (ist Bestandteil des roundcube-plugins Paketes)

Eine Anleitung gibt es hier:<br>
https://www.pair.com/support/kb/how-to-add-sieve-filtering-code-in-roundcube/
<br>
https://www.pair.com/support/kb/how-to-add-sieve-filtering-in-roundcube/
</br>

Anmerkung: Den protocols Parameter nicht in der dovecot.conf editieren, sondern in
''20-managesieve.conf'' (s.o.):

protocols = $protocols sieve

Nun kann man über das Webfrontend Sieve-Filterregeln generieren

Achtung Bug:<br>
Sieve legt ein sieve-Verzeichnis unter dem Verzeichnis an, das in mail_location definiert ist. Wenn man die emails der User unter ''/var/mail/<domain>/<username>'' ablegen möchte, wird man folgendes konfigurieren:

mail_location = maildir:/var/mail/%d/%n

Da dovecot aber %d nicht interpretiert (s.o.), liegt das User maildirectory unter /var/mail/<username>. Sieve interpretiert dagegen %n nicht und legt ein Directory /var/mail/<domain>/%n/sieve an, unter der die roundcube.sieve Datei liegt. Somit greifen alle User auf dieselbe Datei zu, was technisch möglich, securitytechnisch aber fatal ist. Leider keine gute Idee zur Abhilfe bekannt.

== Passwort ändern ==
Um den Usern die Möglichkeit zu geben, ihr Passwort selbst zu ändern, wird in der ''config.inc.php'' das Plugin enabled:

<pre>
$config['plugins'] = array(
(...)
'password'
);
</pre>

Weitere Einstellungen, wenn die User in einem Passwortfile gepflegt werden wie im Kapitel '''Dovecot''' beschrieben:<br>
(wir gehen davon aus, dass die Userpasswörter mit sha512 verschlüsselt werden, s.o.)

# https://stackoverflow.com/questions/62655236/how-to-enable-password-plugin-on-roundcube
$config['password_algorithm'] = 'ssha512';
$config['password_algorithm_prefix'] = '{SSHA512}';
$config['password_driver'] = 'dovecot_passwdfile';
$config['password_dovecot_passwdfile_path'] = '/etc/dovecot/users';

Die users Datei vom dovecot muss dann entsprechend für www-data les- und schreibbar sein:
-rw-rw---- 1 dovecot www-data 1240 Dec 2 23:20 /etc/dovecot/users

(Achtung, riskant bei eventueller Kompromittierung des Webservers! Als Alternative überlegen, die dovecot-Passwörter in eine [mysql-]DB auszulagern)

== Identities ändern ==

Normalerweise kann ein User nur mit seiner Absenderadresse senden. Das ist eine sinnvolle Einstellung, aber wer das Feature zu Testzwecken abschalten will, kann folgende Einstellung vornehmen:
$config['identities_level'] = 0;
Nun kann der User über "Einstellungen" weitere Absender hinzufügen (https://www.servercake.blog/multiple-identities-roundcube/)

(Leider bisher keine Möglichkeit gefunden, dies nur auf (einen) bestimmte(n) User einzuschränken)

== Apache Integration ==

Hier eine Beispielkonfiguration für einen Virtual Host, um die Roundcube-Seite unter https://mail.example.de zu erreichen.
Weiteres im Kapitel [[Webserver mit Apache|apache]]
<pre>
<VirtualHost *:443>
ServerName mail.example.de
ServerAdmin postmaster@example.de

SSLEngine on
SSLCertificateFile /var/lib/dehydrated/certs/mail.example.de/fullchain.pem
SSLCertificateKeyFile /var/lib/dehydrated/certs/mail.example.de/privkey.pem

DocumentRoot /usr/share/roundcube

# Includes
Include /etc/apache2/conf-available/ssl-encryption.conf
      
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" vhost_combined
CustomLog /var/log/apache2/mail-ssl.log combined
ErrorLog /var/log/apache2/mail-ssl-error.log
</VirtualHost>
</pre>

Das roundcube-Paket bringt zudem noch eine roundcube.conf mit, die unter /etc/apache2/conf-available/roundcube.conf installiert und aktiviert wird.

=== PHP ===
Damit der Roundcube überhaupt läuft, muss das php Plugin installiert und aktiviert sein. Passiert unter Debian mittels:
# apt install libapache2-mod-php

Etwas performanter ist die Verwendung von '''php-fpm''' (https://www.zend.com/blog/apache-phpfpm-modphp).
# apt install php-fpm

Der default Upload bei PHP sind dürftige 2 MB. Um diesen z.B. auf 50MB raufzudrehen, muss folgende Datei angefasst werden:
<pre>VERSION=$(php -v| head -n 1 | awk '{ print $2 }' | sed -e 's|.[[:digit:]]*$||')</pre>
* modphp:
/etc/php/${VERSION}/apache2/php.ini
upload_max_filesize = 50M
* php-fpm:
/etc/php/${VERSION}/fpm/php.ini
upload_max_filesize = 50M

= Integration in einen MUA =
Wer nicht über den (langsamen) Webmailer gehen will, kann natürlich auch einen MUA seiner Wahl verwenden. Hier ein Beispiel.

== Thunderbird==

Einstellungen für Outgoing Server (SMTP)
<pre>
Servername: FQDN des Email-Servers
Port: 25
Connection Security: STARTTLS
Authentication Method: Normal Password
Username: Name des Mailbox-Users
</pre>

Beim 1. Mal wird man nach seinem Mailbox-Passwort gefragt. Dieses eingeben und speichern.

Server Settings (IMAP)
<pre>
Server Type: IMAP Mail Server
Server Name: FQDN des Email-Servers
Port: 993
Username: Name des Mailbox-Users
Connection Security: SSL/TLS
Authentication Method: Normal Password
(Die restlichen Defaults so belassen oder bei Bedarf anpassen)
</pre>

[[File:Screenshot thunderbird1.png|900px]]
[[File:Screenshot thunderbird2.png|900px]]

Latest revision as of 18:28, 13 April 2025

Postfix

Postfix ist ein MTA (Mail Transfer Agent), der eine gute Alternative zu anderen gängigen MTAs (Sendmail, Exim) darstellt, da seine Konfiguration gut lesbar ist. In unserem Beispiel soll der MTA mit einem IMAPd (Dovecot) verknüpft werden, so dass Benutzer eine Mailbox direkt auf dem System haben. Das Abholen der Mails erfolgt per IMAPs.

Installation

Zunächst muss das Paket „postfix“ installiert werden. Dabei sind noch ein paar Fragen zu beantworten:

  • Art des Servers: Internet Site
  • Root and postmaster mail recipient: ein Postfach eintragen, z.B.postmaster@example.de
  • Other destinations to accept mail for (blank for none): z.B. mail.example.de, localhost, $mydomain (kann man erstmal die defaults belassen)
  • Force synchronous updates on mail queue: no
  • Local subnets: 127.0.0.1/8, 192.168.63.0/24 (hier das eigene Netz ergänzen)
  • Mailbox size limit: 0 (unbegrenzt)
  • Local address extension character: + (i.a. als default ausreichend)
  • Internet protocols to use: all (wenn man nicht explizit ipv4 oder ipv6 sprechen will)

Diese Einstellungen lassen sich jederzeit mit

 # dpkg-reconfigure postfix

ändern.

Alle relevanten Dateien befinden sich im Verzeichnis /etc/postfix.

Konfiguration

Bevor wir zur Postfixconfig kommen, überprüfen wir den Inhalt der Datei /etc/mailname:

 $ cat /etc/mailname

Dort darf nur der Domainname stehen, nicht der Hostname (e.g. example.com). Andernfalls kann das Auswirkungen auf den Emailversand haben, v.a. wenn in der main.cf (s.u.) auf die Datei referenziert wird.

Die wichtigeste Datei zum Anpassen ist zunächst die main.cf. Hier ein Beispiel für den Server „mx“ in der Domain example.de. Folgende Parameter sollten konfiguriert sein (exemplarisch):

 myhostname
 mydomain
 myorigin
 mydestination

Meistens gibt es schon ein paar brauchbare defaults. Der Parameter mynetworks erlaubt es bestimmten Netzen, Emails ohne weitere Einschränkungen einzuliefern.

Beispielconfig:

myhostname = mx01.example.de 
mydomain = example.de 
myorigin = $mydomain 
mydestination = $myhostname, localhost, localhost.$mydomain
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 192.168.99.0/24 [2001:780:11b::/48] 214.94.24.154 [2004:780:8:0:5ff0:c5ff:fe09:98f9]

Vor allem der Parameter mynetworks sollte mit Bedacht gewählt werden, denn dies sind alle Hosts und Netze, von denen jegliche Emails angenommen werden (auch von und nach Fremddomains). Fehlkonfigurationen führen hier schnell zum OpenRelay.

Beachte: ipv6-Adressen müssen in [eckigen Klammern] geschrieben werden, sonst werden keine Emails ausgeliefert! Fehler im Logfile:

postfix/smtpd[21928]: warning: smtpd_client_event_limit_exceptions: 2a01:40f8:c013:5050::0/64: table lookup problem

Nach jeder Änderung ist der Dienst zu reloaden mit dem Befehl

 # postfix reload

Ob der Restart ordentlich funktioniert hat, kann man z.B. anhand des Logs überprüfen:

 # tail /var/log/mail.log

master.cf

Das Kernstück des Postfixdaemons. Hier werden die Transports festgelegt Bedeutung der Spalten:

  • service-Feld: Name des Dienstes (smtp, local, procmail, ...) (str)
  • typ-Feld: Verbindungstyp (inet, fifo, unix) (str)
  • Zugriffsrecht: Zugriff auch für externe Programme (default: y) (bool)
  • unpriv-Feld: Start als unprivilegierter Benutzer (default: y) oder root (n) (bool)
  • chroot: Soll der Dienst in einer chroot-Umgebung gestartet werden (default: y) (bool)
  • wakeup-Feld: Sekunden zwischen 2 Aufrufen (default: 0) (int)
  • Prozessmaximum: Wie viele Prozesse maximal gleichzeitig (default: 50) (int)

Danach erfolgt ein Kommando mit Flags und Parametern (optional).

TLS

Optional kann man mit Zertifikaten verschlüsselte Übertragung von Emails konfigurieren. das funktioniert aber nur dann, wenn der Mailserver der Gegenstelle das Zertifikat auch einbindet. Man kann das Zertifikat auch in einen Mailclient einbinden (s. später). Die Zertifikatserzeugung kann mit mit letsencrypt erfolgen. Clients zur Zertifikatserzeugung sind certbot oder dehydrated.

Zertifikatsgenerierung in Kürze

# echo $HOSTNAME > /etc/dehydrated/domains.txt
# dehydrated –register –accept-terms
# dehydrated -c

Dies setzt allerdings einen Webserver voraus, der auf Port 80 lauscht. Gibt es diesen nicht, kann mal alternativ letsencrypt via DNS verwenden (https://letsencrypt.org/docs/challenge-types).

Alternative eigene CA (nicht empfohlen)

Wer unbedingt eine eigene CA betreiben will, kann das mit folgender Anleitung tun. Achtung: Das Vorgehen sollte nur gewählt werden, wenn ein zwingender Grund dafür besteht. Viele Browser und MUAs haben Probleme damit, erzeugen hässliche Warnings oder lassen die Seite nicht zu.

CA erstellen

Wenn noch kein Zertifikat vorhanden ist, kann man sich selbst eines erstellen oder einen CSR (Certificate Signing Request) erstellen und diesen an eine offizielle CA schicken. Soll ein kommerziell genutzter Mailserver entstehen, ist dies der realistische Weg.

Achtung: Dieser Schritt wird nicht gebraucht, wenn es schon eine CA gibt.

Schritte:
Key erstellen (+Passwort dafür vergeben), Zertifkatsrequest für die CA erstellen, CA erstellen

$ openssl genrsa -out ca.key -des3 4096
 
$ openssl req -new -x509 -days 3650 -key ca.key -out ca.crt
Enter pass phrase for ca.key: 
You are about to be asked to enter information that will be incorporated 
into your certificate request. 
What you are about to enter is what is called a Distinguished Name or a DN. 
There are quite a few fields but you can leave some blank 
For some fields there will be a default value, 
If you enter '.', the field will be left blank. 
----- 
Country Name (2 letter code) [AU]:DE 
State or Province Name (full name) [Some-State]:Bavaria 
Locality Name (eg, city) []:Nuernberg 
Organization Name (eg, company) [Internet Widgits Pty Ltd]:example.de 
Organizational Unit Name (eg, section) []:Hostmaster 
Common Name (e.g. server FQDN or YOUR name) []:*.example.de 
Email Address []:postmaster@example.de

Zertifikat mit der neuen CA erstellen

Schritte:

   • Key erstellen
   • Request erstellen 
   • Zertifikat erstellen und signen
 $ openssl genrsa -out mx.example.de.key 4096

(kein Passwort festlegen)

$ openssl req -new -key mx.example.de.key -out mx.example.de.csr

(wieder das Formular ausfüllen as usual)

$ openssl x509 -req -days 365 -in mx.example.de.csr -CA  ca.crt -CAkey ca.key -set_serial 01 -out mx.example.de.crt

Beim Erneuern des Zertifikats fallen die Schritte „Erstellen der CA“ und Erzeugen des Keys weg. Ferner muss man auch keine Serial mehr angeben. Der Renew-Befehl lautet also folgendermaßen:

$ openssl x509 -req -days 730 -in mx.example.de.csr -CA ca.crt -CAkey ca.key -out mx.example.de.crt

Einbinden in die Config-Datei

Dieser Schritt gilt wieder für alle Zertifikate, egal wie sie erzeugt wurden. Die Pfade müssen natürlich entsprechend angepasst werden,

Zertifikate an die entsprechende Stelle kopieren und in der Konfig einbinden:

smtpd_tls_cert_file=/etc/ssl/certs/mx.example.de.crt 
smtpd_tls_key_file=/etc/ssl/private/mx.example.de.key 
smtpd_tls_CAfile=/etc/postfix/ca.crt 
smtpd_use_tls=yes 
smtpd_tls_session_cache_database = btree: 
  ${data_directory}/smtpd_cache
smtp_tls_session_cache_database = btree:  
  ${data_directory}/smtp_scache

Der Parameter smtpd_tls_Cafile entfällt, wenn eine offizielle CA vorhanden ist (z.B. letsencrypt).
Die Pfade zu den Zertifikaten können abweichen, bei letsencrypt liegen diese z.B. unter /var/lib/dehydrated/certs/. Überprüfung:

$ openssl s_client -connect mx.example.de:25 -starttls smtp

oder https://www.checktls.com/

Ergänzung: Manche MTAs wollen ein Zertifikat in pfx-Form. Dieses kann man aus dem cert file wie folgt erzeugen:

$ openssl pkcs12 -export -out mx.example.de.pfx -inkey mx.example.de.key -in mx.example.de.crt

pfx-File und Passwort dem User zukommen lassen.

Spoiler:
Dovecot „vergisst“ manchmal das neue Zertifikat und behält die alte Version, d.h. die meisten Mailclients spoolen dann keine neuen Emails mehr. In diesem Fall den Dovecot Service neu starten.

SASL

Zur Vermeidung eines Open Relays ist dringend anzuraten, per default nur das Einliefern mit dem Absender @example.de von bestimmten Netzen zu erlauben. Dieses passiert mit dem Parameter mynetworks (s.o.). Nun kann es natürlich passieren, dass Benutzer von einem Mailclient irgendwo im Internet Mails verschicken wollen. Diese wären laut Konfig nicht berechtigt. Da die meisten PCs mit dynamischen Adressen im Internet unterwegs sind, macht es hier auch keinen Sinn, die jeweilige IP-Adresse in der Konfig zu ergänzen.
Das Problem kann umgangen werden, indem Emails versenden dann erlaubt wird, wenn sich der Benutzer einmal erfolgreich am IMAP-Server authentifiziert hat. Hierfür gibt es SASL. Die entsprechenden Eintragungen in der main.cf sind:

smtpd_relay_restrictions = permit_mynetworks  
permit_sasl_authenticated defer_unauth_destination
smtpd_sasl_auth_enable = yes 
smtpd_sasl_type = dovecot 
smtpd_sasl_local_domain = $mydomain 
smtpd_sasl_security_options = noanonymous 
smtpd_sasl_path = private/auth

Im Mailclient äußert sich das Verhalten so, dass man beim ersten Senden einer Nachricht sein Mailbox-Passwort angeben muss. Bevor dieses Feature aktiviert wird, muss es einen IMAP-Server geben (s. nächstes Kapitel ).

Maps

Um besser unterscheiden zu können, was mit welchen Absender-/Zieladressen passiert, wird die Konfiguration in sogenannte „Maps“ aufgeteilt. Diese können als Klartext-File oder als Berkley DB vorliegen. In letzterem Fall müssen diese mit dem Kommando postmap nach jeder Bearbeitung umgewandelt werden.
Ausnahme: Die Datei /etc/aliases.db (nur relevant für lokale Emailauslieferung) wird mit dem Kommando postalias oder newaliases generiert.

alias_maps = hash:/etc/aliases 
alias_database = hash:/etc/aliases 

Hier werden aliase eingerichtet, die auf eine andere Mailbox mappen. Beispiel:

postmaster:    root

Access

smtpd_sender_restrictions = hash:/etc/postfix/access 

Hier können für Aktionen für spezielle Absenderadressen eingerichtet werden. Beispiel:

example.com     DISCARD

Relocated

relocated_maps = hash:/etc/postfix/relocated 

Abweisen der Mail mit einem Hinweis. Beispiel:

testy.test      "Mails bitte statt an diese Adresse an ich@hier.de senden"

Ergebnis:

<testy.test@example.de>: Recipient address rejected: User has 
moved to "Mails bitte statt an diese Adresse an ich@hier.de
senden"

Canonical

Sender

sender_canonical_maps = hash:/etc/postfix/sender_canonical 

Bestimmte Adressen werden auf ein übliches Standardformat umgeschrieben:

sunflower@example.de   petra.sonne@example.de
phun@work.de		   peter.hun@example.de

Recipient

recipient_canonical_maps = hash:/etc/postfix/recipient_canonical 

Arbeitet genauso wie sender_canonical, nur für Empfängeradressen.

Virtual Mailbox

virtual_mailbox_maps = hash:/etc/postfix/virtual

Locations der Mailboxen des imap-Servers (näheres unter Dovecot )

sunflower@example.de   	example.de/sunflower/ 
testy@example.de		example.de/testy 
test@example.de		example.de/test 
lmaa@ihr-koennt-mich-alle.de	ihr-koennt-mich-alle.de/lmaa

Virtual Aliases

virtual_alias_maps = hash:/etc/postfix/virtual_maps

Adressen die auf andere Adressen umgebogen werden (ähnlich wie die aliases), kann auch domainübergreifend passieren. So können mehrere Empfängeradressen in dieselbe Mailbox laufen.

anrufbeantworter@example.de      sunflower@example.de,H.Hirsch@gmx.de,harry1999@yahoo.de
info@example.de        sunflower@example.de
postmaster    root 
webmaster     root 
administrator root
root    sunflower

fortune:  fortune Letzteres ist eine Pipe. Dazu später mehr.

Umwandeln von Text in DB-File und in Postfix einlesen:

postmap <aliases|access|canonical|...>
postfix reload

Einfaches Beispiel: Emails von einer Domain auf eine andere weiterleiten

Nehmen wir an, wir haben einen Emailserver1 in der Domain example.com. Dieser soll alle Email die an <userXY>@example.com eintreffen, an <userXY>@example.de weiterleiten. Auch hier ist eine Eintrag in der o.g. virtual_maps Datei nötig:

@example.com	@example.de

Nun werden alle example.com-Emails zum zuständigen Emailserver für example.de weitergeleitet. Der user part bleibt unverändert.

Transports

Transports sind die Art und Weise, wie eine eingehende Mail behandelt wird, z.B. lokal in eine Datei speichern, an einen imap-Server weiterreichen oder ein Script ausführen.

Hier ein Beispiel:
Wenn auf eine bestimmte Adresse geschickt wird, soll ein Script ausgeführt werden, das dem Absender einen Zufallsspruch zurücksendet und die Mail gleichzeitig in ein Postfach einliefert. Schritte:

1. Alias definieren (virtual_maps):

fortune@example.de           fortune

2. Alias auf einen Transport mappen (transports):

fortune@example.de     randomphrase:

3. Transport definieren (master.cf):

 randomphrase      unix  - n n - - pipe 
  flags=h user=vmail:vmail argv=/usr/local/bin/randomphrase.pl ${sender}

(Den User vmail muss es natürlich in der passwd geben, z.B. so:

vmail:x:4000:4000::/home/vmail:/user/sbin/nologin

)

4. Script hinterlegen:

/usr/local/bin/randomphrase.pl

für alle ausführbar machen

Mit dem Script randomphrase.pl wird ein Zufallsspruch erzeugt. Dafür muss das Paket fortune-mod installiert sein. Zum Weiterschicken der Email wird das Script /usr/local/bin/deliver_mail.sh aufgerufen. (File:Deliver mail.sh)
Hierfür muss der User vmail in der Datei /etc/sudoers.d/vmail berechtigt werden:

vmail ALL=(root) NOPASSWD: /usr/local/bin/deliver_mail

Eine Email an die Adresse fortune@example.de erzeugt nun eine Antwort an die Absenderadresse mit einem Zufallsspruch.

Multidomain

Natürlich kann Postfix auch Emails für mehrere Domains annehmen. Dafür gibt es den Parameter „virtual_mailbox_domains“:

virtual_mailbox_domains = example.de  example.com  ihr-koennt-mich-alle.de

Die Variable $mydomain sollte dann aus mydestination entfernt werden.

Special DNS Records

SPF (Sender Policy Framework)

Mit einem RR-Type TXT kann man eine Liste von Emailservern definieren, die als Absender die Emaildomain verwenden dürfen. Generiert jemand eine Fakeemail von einem anderen System aus, kann diese abgewiesen werden.

Beispiel für einen DNS TXT Record:

IN TXT  "v=spf1 mx:example.de a:foo.example.de ip4:8.15.47.11/32 ip6:2008:15:5:47::11/48 ip6:2008:15:5:47::12/48 -all"

Howto:
https://dmarcian.com/create-spf-record/
http://www.open-spf.org/SPF_Record_Syntax/

SPF in Postfix integrieren:

Nun ist die Domain vor Missbrauch vor Fakeeemails geschützt. Jetzt gibt es aber noch die andere Seite zu beachten. Postfix soll ebenfalls die SPF-Records anderer Emaildomains prüfen und die Email ggf ablehnen. https://makeityourway.de/enabling-spf-sender-policy-framework-checking-on-postfix/

Hier in Kürze zusammengefasst, was es zu beachten gibt:

# apt install postfix-policyd-spf-python

Die Config-Datei /etc/postfix-policyd-spf-python/policyd-spf.conf liefert bereits brauchbare Defaults, optional kann man noch eine Whitelist ergänzen z.B.

Domain_Whitelist = example.com 

In der master.cf ergänzen:

 policyd-spf  unix  -     n       n       -       -       spawn 
  user=policyd-spf argv=/usr/bin/policyd-spf

In der main.cf ergänzen:

smtpd_recipient_restrictions =
(...)
check_policy_service unix:private/policyd-spf
(…)

Achtung: Wenn es schon einen check_policy_service Eintrag gibt, keinesfalls einen weiteren Eintrag anhängen, sondern eine neue Zeile aufmachen!

policy-spf_time_limit = 3600s
# postfix reload

Ein paar Testemails einkippen und mail.log gucken.

DMARC (Domain based Message Authentication, Reporting and Conformance)

https://dmarcian.com/dmarc-record/

Beispiel für einen DNS TXT Record:

_dmarc                  IN TXT      "v=DMARC1;p=quarantine;rua=mailto:postmaster@example.de"

In dem Fall werden verdächtige Emails in einen Quarantäne-Ordner verschoben und ein Report an den postmaster versandt. Für die Integration in Postfix gibt es das Paket opendmarc. Implementierung von SPF, DKIM und DMARC in Postfix:

https://www.skelleton.net/2015/03/21/how-to-eliminate-spam-and-protect-your-name-with-dmarc/ (untested)

Nützliche Commands

Erzeugen eines database files aus einer Textdatei:

postmap <filename>

Alle Configparameter anzeigen:

 postconf

Konfigprüfung:

 postfix check

Mailqueue anschauen:

 mailq

Alle Messages in der Queue ausliefern:

 postqueue -f

Nur eine bestimmte Message ausliefern:

 postqueue -i <ID>

Message löschen:

 postsuper -d <ID>

Alle Messages löschen (!):

 postsuper -d ALL

Inhalt einer Message anschauen:

 postcat -vq <ID>

Logfile

Geloggt wird nach /var/log/mail.log (alles) bzw. Errors nach /var/log/mail.err und Warnings nach /var/log/mail.warn.
Protipp: Alias anlegen:

maillog='tail -f /var/log/mail.log'

Greylisting und Antispam

Zur Bekämpfung der Spamflut gibt es das praktische Programm „Postgrey“. Unter Debian kann dieses als Paket installiert werden. Dieses wird in die main.cf im Abschnitt smtpd_recipient_restrictions eingebunden.

smtpd_recipient_restrictions = 
 permit_mynetworks
 permit_sasl_authenticated
 permit_tls_clientcerts
 reject_unauth_destination
 reject_non_fqdn_sender
 reject_non_fqdn_recipient
 reject_rbl_client bl.spamcop.net
 check_policy_service inet:127.0.0.1:10023

(Die Blacklist dnsbl.sorbs.net wurde hier außen vor gelassen, da diese so ziemlich alles blockt, z.B. alle yahoo- oder gmx-Adressen.) Damit das funktioniert, muss natürlich noch Postgrey selbst an den Start gebracht werden. Hierfür wird die Datei /etc/default/postgrey bearbeitet. Hier ein Beispiel:

POSTGREY_OPTS="--inet=10023 --auto-whitelist-clients=8  
POSTGREY_TEXT="Busy. Come back in 5 minutes."

Der Service lauscht also auf Port 10023. Im obigen Beispiel wird ein Absender beim 8. erfolgreichen Zustellversuch automatisch gewhitelistet (optionaler Parameter --auto-whitelist-clients, evtl. Zahl erhöhen oder Parameter ganz weglassen).

Anschließend wechselt man ins Verzeichnis /etc/postgrey. Dort gibt es 2 Whitelistings. Die Absender stehen in whitelist_clients. Dort stehen bereits IPs und Domains diverser Provider. Man kann dort selbst Einträge hinzufügen (z.B. example.ch).

In der Datei whitelist_recipients kann man alle Empfänger der eigenen Domain eintragen, die auf jeden Fall immer Emails bekommen sollen. z.B. postmaster@, abuse@.
Nach getaner Anpassung, den postgrey-Service (neu)starten.

 # service postgrey restart

Überprüfen, ob der Dienst läuft z.B. mit:

# lsof -i :10023

Anschließend Postfix reloaden

# postfix reload

und die Mailbox(en) beobachten, hinsichtlich Spamaufkommen.

(Quelle: Artikel „Postzusteller“, Admin-Magazin, Ausgabe 03-2013)

Dovecot

Open Source IMAP-Server zum Einliefern der Emails in Postfächer mittels POP3 oder IMAP bzw. IMAPs. Im folgenden wird nur auf IMAPs eingegangen.

Installation

Es empfiehlt sich, den Dovecot auf demselben System zu installieren wie Postfix. Andere Fälle werden hier nicht berücksichtigt.

Installation des imapd mittels

# apt install dovecot-imapd

Dies reicht für alle Grundfunktionen der Emailauslieferung. Für erweiterte Optionen wie z.B. Filterfunktion können weiter dovecot-Pakete wie dovecot-antispam, dovecot-sieve installiert werden.

User (i.d.F. vmail) als Owner für die Mailboxen anlegen:

useradd -u 4000 -m -d /home/vmail -s /user/sbin/nologin vmail

Konfiguration

Configdateien in /etc/dovecot/conf.d anpassen. Die Datei /etc/dovecot/dovecot.conf inkludiert per Default alle Dateien unter conf.d/*.conf.

Usermanagement

Hier ein Beispiel, wo User in einer separaten Datei abgelegt werden.

10-auth.conf:

disable_plaintext_auth = no
auth_username_format = %n
auth_master_user_separator = *
auth_mechanisms = plain login 
!include auth-master.conf.ext

Wenn kein auth über pam:

#!include auth-system.conf.ext

Plaintext Auth kann man erlauben, weil die User-Passwörter als gehashter String übertragen werden. Für die Kommunikation zwischen Postfix und Dovecot spielt das ohnehin keine Rolle, da sich beide Dienste auf einem Server befinden. Der Zugriff von einem MUA aus wird über TLS/SSL erfolgen (s.u.).

master user anlegen (optional):

doveadm pw -p supergeheim -s SHA512-CRYPT -u administrator@example.de 

Den Output zusammen mit dem Usernamen in die Datei master-users pasten.

cat  ../master-users     
administrator@example.de:{SHA256-CRYPT}$5$9zrt7/e2CDkPmSuA$SNEkm/L4XZcYFAbYkJp5ESl9u35fVBSd4ukO0dm5yp3

Sonstige User anlegen:

doveadm pw -p strenggeheim -s SHA512-CRYPT -u sunflower@example.de

→ /etc/dovecot/users:

sunflower:{SHA256-CRYPT}$5$D3PhhtqUhRXT7cmZ$E5244BpvNafb.9FtbhF9AUfbvw8XpnOJhPyM/q/rRN2:::Sun Flo,,,:/var/mail/example.de/sunflower:/bin/false

Hier sollten keine Abkürzungen wie %d oder %n stehen, weil diese nicht (von sieve, s.u.) bzw. nur teilweise (von dovecot) interpretiert werden.

Damit der Account auch Email bekomemn kann, ergänzt man die virtual table im Postfix directory:

 cat sunflower@example.de  example.de/spambucket >> /etc/postfix/virtual

Aktivieren mit

postmap virtual
postfix reload

Dateirechte

Die Files master-users, users sollten nur von dovecot gelesen werden können!

# chgrp dovecot /etc/dovecot/*users
# chmod o-r /etc/dovecot/*users

Mailbox anlegen und User berechtigen:

# maildirmake.dovecot /var/mail/<username>
# chown -R vmail.vmail /var/mail/<username>

Achtung, der Parameter %d wird nicht als Domain gelesen, sondern bleibt leer!
=> mail_location = maildir:/var/mail/%d/%n
bedeutet, dass die Emails in /var/mail/<username> liegen. D.h. die Postfächer müssen direkt unter /var/mail angelegt werden.

User im Postfix anlegen, in den virtual maps, s. o.

Kontrolle:

# doveadm user <username>

IMAP konfigurieren

Protipp: erstmal conf.d wegsichern:

rsync -av /etc/doveconf/conf.d /etc/doveconf/conf.d.orig

Folgende Konfigurationsdateien in conf.d entsprechend anpassen:

  • 10-auth.conf
disable_plaintext_auth = no
auth_username_format = %n
auth_master_user_separator = *
auth_mechanisms = plain login

!include auth-master.conf.ext
!include auth-system.conf.ext
!include auth-passwdfile.conf.ext
  • 10-mail.conf
mail_location = maildir:/var/mail/%d/%n 
namespace inbox { 
 inbox = yes 
} 
mail_uid = 4000 
mail_gid = 4000
mail_privileged_group = mail
  • 10-master.conf
service imap-login { 
  inet_listener imaps { 
   port = 993 
   ssl = yes 
 } 
}
service auth { 
 unix_listener auth-userdb { 
   user = vmail  
   group = vmail 
 } 
 unix_listener /var/spool/postfix/private/auth { 
   mode = 0666 
   user = postfix 
   group = postfix 
 } 
}
service stats { 
	unix_listener stats-reader { 
               user = vmail 
               group = vmail 
               mode = 0660 
     } 

	unix_listener stats-writer { 
       user = vmail 
       group = vmail 
       mode = 0660 
   	} 
}
  • 10-ssl.conf
# (z.B. Postfix certs verwenden)
ssl = yes 
ssl_cert = </etc/ssl/certs/mx.example.de.crt 
ssl_key = </etc/ssl/private/mx.example.de.key 
ssl_client_ca_dir = /etc/ssl/certs 
ssl_dh = </usr/share/dovecot/dh.pem

Zertifikate generieren: s. https://wiki.nomorebluescreen.de/index.php?title=Webserver_mit_Apache#Alternative_letsencrypt

Spoiler:
Jedes Mal, wenn das Zertifikat ausgetauscht wird, muss der dovecot-Service neu gestartet werden, damit das neue Zertifikat auch eingelesen wird.

Überprüfen, welche Dateien angefasst wurden:

diff -quw conf.d.orig conf.d
Files conf.d.orig/10-ssl.conf and conf.d/10-ssl.conf differ
Files conf.d.orig/15-lda.conf and conf.d/15-lda.conf differ
Files conf.d.orig/20-imap.conf and conf.d/20-imap.conf differ
Files conf.d.orig/20-managesieve.conf and conf.d/20-managesieve.conf differ
Files conf.d.orig/90-sieve.conf and conf.d/90-sieve.conf differ
Files conf.d.orig/auth-passwdfile.conf.ext and conf.d/auth-passwdfile.conf.ext differ

Ausgabe der gesamten Config

# doveconf -n

Sieve

Engine zum Filtern von Emails

dovecot-sieve und dovecot-managesieved installieren

15-lda.conf:

lda_mailbox_autocreate = yes
lda_mailbox_autosubscribe = yes
protocol lda { 
 mail_plugins = $mail_plugins sieve 
}

20-managesieve.conf:

protocols = $protocols sieve

90-sieve.conf:

plugin { 
 sieve = file:~/sieve;active=~/.dovecot.sieve 
 sieve_default = /var/lib/dovecot/sieve/default.sieve 
 sieve_global_dir = /var/lib/dovecot/sieve 
}

Kontrolle, ob der sieve-Service läuft und auf Port 4190 lauscht.

# service dovecot restart
# ss -plnt | grep 4190

Da der User i.a. nicht direkt auf dem Emailserver sein /home mit den Sieve-Regeln editieren kann, erfolgt die weitere Konfiguration im Email-Client (s.u.).

Achtung Bug:
Da sieve/dovecot die Variable %n in der users-Datei nicht interpretiert, sollte man diese dort nicht verwenden. Somit kann es passieren, dass von roundcube ein Verzeichnis %n angelegt wird, in dem sich eine gemeinsame sieve config für alle User befindet.

Transport von Postfix zu Dovecot

Dem Postfix muss noch beigebracht werden, dass die Emails zum Dovecot gehen.
master.cf im Postfix anpassen (die Einträge in den {} gehören so, nicht ersetzen!):

dovecot unix - n n - - pipe flags=DRhu user=vmail:vmail    
 argv=/usr/lib/dovecot/deliver -a ${recipient} -f ${sender} -d $ 
 {user} @${nexthop} -m ${extension}

und einen mailbox_command Eintrag in der main.cf vornehmen:

mailbox_command = /usr/lib/dovecot/dovecot-lda -f "$SENDER" -a "$RECIPIENT"

(https://doc.dovecot.org/configuration_manual/howto/dovecot_lda_postfix/#howto-dovecot-lda-postfix)

Danach noch postfix und dovecot service restarten.

Logging

Logfiles gehen ebenfalls (wie postfix) nach /var/log/mail.log
Nützlicher Alias:

maillog='tail -f /var/log/maillog'

Debugging einschalten:

mail_debug = yes

in der Datei 10-logging.conf.

Protipp: Wenn im Log folgender Fehler erscheint:

Mar 27 08:03:56 aphantopus postfix/pipe[2317]: 521066005D: to=<sunflower@example.de>, relay=dovecot, delay=0.3, delays=0.19/0.04/0/0.07, dsn=2.0.0, status=sent (delivered via dovecot service (lda(sunflower@example.de,)Error: net_connect_unix(/var/run/dovecot/stats-writer) failed: Permission denied))

=> In der 10-master.conf stats für User vmail erlauben (s.o.)

Roundcube

Praktisches Webfrontend zum Abholen und Verschicken von Emails

Erst mysql-server installieren, sonst bricht die Installation mit einem Fehler ab

# apt install mariadb-server roundcube

Die dbconfig-common Frage mit „yes“ beantworten, mysql-Passwort setzen. Config Datei anpassen (/etc/roundcube/config.inc.php):

$config['smtp_server'] = 'localhost';
$config['smtp_port'] = 25;

Plugins

Standard-Plugings installieren

# apt install roundcube-plugins

Weitere Plugins installieren:

# apt install roundcube-plugins-extra git curl composer

(composer braucht man für die Installation von Plugins, git, weil die meisten aus github kommen)
Die, die man haben will, in der Datei /etc/roundcube/config.inc.php enablen

$config['plugins'] = array( 
       'compose-addressbook', 
       'markasjunk2', 
       'fail2ban' 
);

Übersicht über die offiziellen Plugins:

https://plugins.roundcube.net/

Plugins, die es nicht als Paket gibt:
Schritte:

  • README lesen
  • Plugin als zip herunterladen, nach /usr/share/roundcube/plugins entpacken
  • (evtl. umbenennen)
  • /etc/roundcube/config.inc.php bearbeiten:

Abschnitt

$config['plugins'] = array( 

suchen und fehlendes Plugin ergänzen

Filter Plugin for Sieve

Achtung, nicht das Plugin „filter“ verwenden, sondern managesieve (ist Bestandteil des roundcube-plugins Paketes)

Eine Anleitung gibt es hier:
https://www.pair.com/support/kb/how-to-add-sieve-filtering-code-in-roundcube/
https://www.pair.com/support/kb/how-to-add-sieve-filtering-in-roundcube/

Anmerkung: Den protocols Parameter nicht in der dovecot.conf editieren, sondern in 20-managesieve.conf (s.o.):

protocols = $protocols sieve

Nun kann man über das Webfrontend Sieve-Filterregeln generieren

Achtung Bug:
Sieve legt ein sieve-Verzeichnis unter dem Verzeichnis an, das in mail_location definiert ist. Wenn man die emails der User unter /var/mail/<domain>/<username> ablegen möchte, wird man folgendes konfigurieren:

mail_location = maildir:/var/mail/%d/%n

Da dovecot aber %d nicht interpretiert (s.o.), liegt das User maildirectory unter /var/mail/<username>. Sieve interpretiert dagegen %n nicht und legt ein Directory /var/mail/<domain>/%n/sieve an, unter der die roundcube.sieve Datei liegt. Somit greifen alle User auf dieselbe Datei zu, was technisch möglich, securitytechnisch aber fatal ist. Leider keine gute Idee zur Abhilfe bekannt.

Passwort ändern

Um den Usern die Möglichkeit zu geben, ihr Passwort selbst zu ändern, wird in der config.inc.php das Plugin enabled:

$config['plugins'] = array(
 (...)
 'password'
);

Weitere Einstellungen, wenn die User in einem Passwortfile gepflegt werden wie im Kapitel Dovecot beschrieben:
(wir gehen davon aus, dass die Userpasswörter mit sha512 verschlüsselt werden, s.o.)

# https://stackoverflow.com/questions/62655236/how-to-enable-password-plugin-on-roundcube
$config['password_algorithm'] = 'ssha512';
$config['password_algorithm_prefix'] = '{SSHA512}';
$config['password_driver'] = 'dovecot_passwdfile';
$config['password_dovecot_passwdfile_path'] = '/etc/dovecot/users';

Die users Datei vom dovecot muss dann entsprechend für www-data les- und schreibbar sein:

-rw-rw---- 1 dovecot www-data 1240 Dec  2 23:20 /etc/dovecot/users

(Achtung, riskant bei eventueller Kompromittierung des Webservers! Als Alternative überlegen, die dovecot-Passwörter in eine [mysql-]DB auszulagern)

Identities ändern

Normalerweise kann ein User nur mit seiner Absenderadresse senden. Das ist eine sinnvolle Einstellung, aber wer das Feature zu Testzwecken abschalten will, kann folgende Einstellung vornehmen:

$config['identities_level'] = 0;

Nun kann der User über "Einstellungen" weitere Absender hinzufügen (https://www.servercake.blog/multiple-identities-roundcube/)

(Leider bisher keine Möglichkeit gefunden, dies nur auf (einen) bestimmte(n) User einzuschränken)

Apache Integration

Hier eine Beispielkonfiguration für einen Virtual Host, um die Roundcube-Seite unter https://mail.example.de zu erreichen. Weiteres im Kapitel apache

<VirtualHost *:443> 
    ServerName mail.example.de 
    ServerAdmin postmaster@example.de 

    SSLEngine on 
    SSLCertificateFile         /var/lib/dehydrated/certs/mail.example.de/fullchain.pem 
    SSLCertificateKeyFile /var/lib/dehydrated/certs/mail.example.de/privkey.pem 

    DocumentRoot /usr/share/roundcube 

    # Includes 
    Include /etc/apache2/conf-available/ssl-encryption.conf 
      
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" vhost_combined 
    CustomLog /var/log/apache2/mail-ssl.log combined 
    ErrorLog /var/log/apache2/mail-ssl-error.log 
</VirtualHost>

Das roundcube-Paket bringt zudem noch eine roundcube.conf mit, die unter /etc/apache2/conf-available/roundcube.conf installiert und aktiviert wird.

PHP

Damit der Roundcube überhaupt läuft, muss das php Plugin installiert und aktiviert sein. Passiert unter Debian mittels:

# apt install libapache2-mod-php

Etwas performanter ist die Verwendung von php-fpm (https://www.zend.com/blog/apache-phpfpm-modphp).

# apt install php-fpm

Der default Upload bei PHP sind dürftige 2 MB. Um diesen z.B. auf 50MB raufzudrehen, muss folgende Datei angefasst werden:

VERSION=$(php -v| head -n 1 | awk '{ print $2 }' | sed -e 's|.[[:digit:]]*$||')
  • modphp:
/etc/php/${VERSION}/apache2/php.ini
 upload_max_filesize = 50M
  • php-fpm:
/etc/php/${VERSION}/fpm/php.ini
 upload_max_filesize = 50M

Integration in einen MUA

Wer nicht über den (langsamen) Webmailer gehen will, kann natürlich auch einen MUA seiner Wahl verwenden. Hier ein Beispiel.

Thunderbird

Einstellungen für Outgoing Server (SMTP)

Servername: FQDN des Email-Servers
Port: 25
Connection Security: STARTTLS
Authentication Method: Normal Password
Username: Name des Mailbox-Users

Beim 1. Mal wird man nach seinem Mailbox-Passwort gefragt. Dieses eingeben und speichern.

Server Settings (IMAP)

Server Type: IMAP Mail Server
Server Name: FQDN des Email-Servers
Port: 993
Username: Name des Mailbox-Users
Connection Security: SSL/TLS
Authentication Method: Normal Password
(Die restlichen Defaults so belassen oder bei Bedarf anpassen)

Screenshot thunderbird1.png Screenshot thunderbird2.png