Mailserver mit Dovecot, Postfix, MySQL und Spamassassin unter Ubuntu 16.04 LTS


Im Fr├╝hjahr 2014 habe ich meine erste ausf├╝hrliche Anleitung zur Einrichtung eines einfachen Mailservers mit Postfix und Dovecot auf diesem Blog ver├Âffentlicht. Viele Leser sind so erfolgreich zu ihrem privaten oder gesch├Ąftlichen Mailserver gekommen. Nachdem nun zwei Jahre vergangen sind und sich mittlerweile auch mein eigenes Setup ge├Ąndert hat, will ich euch mit diesem Beitrag eine neue, aktualisierte Anleitung f├╝r einen Mailserver mit erweiterten Funktionen vorstellen.

Beachtet auch meine meine neue Mailserver-Anleitung vom August 2017: Diese wurde an einigen Stellen optimiert und setzt auf Rspamd statt Amavis/Spamassassin/Opendkim. Die neue Anleitung ist zwar auf Debian 9 “Stretch” ausgelegt, sollte gr├Â├čtenteils aber auch mit Ubuntu Server kompatibel sein.

Diese Anleitung wurde mehrmals im Ganzen auf einem neu installierten Ubuntu Server getestet und f├╝r funktionierend befunden. Solltest du dennoch einen Fehler finden oder einen Verbesserungsvorschlag haben, schreibÔÇś mir an: mailserver [ett] thomas-leister.de

Am Ende dieser Anleitung werdet ihr einen robusten Mailserver mit Spam-Abwehrmechanismen und weiteren Extras vor euch haben, den ihr so direkt verwenden und auf das Internet loslassen k├Ânnt. Au├čerdem liegt mir etwas daran, die grundlegende Funktionsweise des Mailsystems zu erkl├Ąren, sodass ihr versteht, was Schritt f├╝r Schritt eingestellt wird. Ich betreibe selbst erst seit wenigen Jahren einen eigenen Mailserver und h├Ątte mir zu Anfangszeiten gew├╝nscht, zu verstehen, was ich da eigentlich konfiguriere. Wer einfach nur schnell zu einem Ergebnis kommen will, kann die Erkl├Ąrungen nat├╝rlich ├╝berspringen und einfach nur Schritt f├╝r Schritt die Anweisungen befolgen. Ich rate aber trotzdem, sich mit dem Thema zumindest grundlegend auseinanderzusetzen: Wenn ein gewisses Verst├Ąndnis vorhanden ist, k├Ânnen k├╝nftige Erweiterungen und ├änderungen an der Software einfacher durchgef├╝hrt werden.

Wer lieber auf eine fertige L├Âsung setzt und sich die Handarbeit sparen will, sollte sich einmal Mailcow ansehen.
Manuel M├╝ller hat einen Docker-Container f├╝r das hier vorgestellte Setup erstellt: https://muellermh.wordpress.com/2016/04/22/locker-mit-docker-heute-der-mailserver/
Die Firma ROCK5 GmbH hat ein Ansible-Playbook f├╝r dieses Setup ver├Âffentlicht: https://github.com/ROCK5GmbH/ansible-mailserver

Der eigene Mailserver ÔÇô Das ideale Wochenend-Projekt

Wenn ihr diese Anleitung an einem Samstag lest, habt ihr ja schon alles richtig gemacht ;-) ÔÇŽ was ich damit sagen will, ist: Nehmt euch genug Zeit. Ein Mailserver ist f├╝r Unge├╝bte nicht “mal eben aufgesetzt” und funktioniert in manchen F├Ąllen nicht sofort. Ich gebe mir bei meinen Ausf├╝hrungen zwar viel M├╝he, trotzdem k├Ânnen sich (Tipp-/)Fehler einschleichen, wenn ihr die Konfigurationen anpasst. Dann funktioniert euer m├Âglicherweise Mailsystem nicht oder nur teilweise. Die Fehlersuche kann unter Umst├Ąnden viel Zeit kosten, sodass ihr euch nicht vornehmen solltet, in einer Stunde schon perfekt mit dem neuen Server kommunizieren zu k├Ânnen. ├änderungen im DNS ben├Âtigen u.U ohnehin ein paar Stunden, bis sie weltweit aktiv sind.

├ťbrigens: Ge├╝bte Leser k├Ânnen diese Anleitung in etwa 45 Minuten durcharbeiten (inkl. Erkl├Ąrungen).

Funktionen

  • Senden und Empfangen von E-Mails f├╝r beliebige Domains
  • Nutzerverwaltung via MySQL-Backend
  • Festlegen einer maximalen Mailbox-Gr├Â├če (“Quota”)
  • Einrichtung von Mail-Weiterleitungen / Aliasen
  • Einrichtung allgemeiner und Nutzer-spezifischer Filter- und Sortierregeln mit Sieve (+ Zugriff ├╝ber kompatible Mailclients -> Managesieve)
  • Empf├Ąngerdomain-spezifische TLS-Einstellungen (z.B. nur verschl├╝sselt und DANE-verifiziert schicken an mailserver.tld)
  • Spamerkennung mit Spamassassin (+ MySQL) und Filterregeln von Heinlein Support
  • Spamserver-Fr├╝herkennung mit Postscreen
  • Einrichtung von “Send only”-Usern, die senden, aber nicht empfangen k├Ânnen (z.B. f├╝r Forensoftware, Soziale Netzwerke, OwnCloud, ÔÇŽ)
  • DKIM-Signierung von ausgehenden E-Mails
  • Spamassassin-Training mit Dovecot-Antispam

Verwendete Software

Diese Anleitung basiert auf Software der folgenden Versionen (Versionierung nach Ubuntu Server Paketquellen):

Mit etwas ├Ąlteren oder neueren Softwareversionen oder anderen Linux-Distributionen sollte diese Anleitung in den Grundz├╝gen ├Ąhnlich nachvollziehbar sein. Probiert es einfach aus :-)

Annahmen

In dieser Anleitung kommen folgende Domains vor:

  • mysystems.tld: ├ťbergeordnete Domain
  • mail.mysystems.tld: Subdomain, unter der der Mailserver verf├╝gbar sein soll (FQDN des Mailsystems)
  • imap.mysystems.tld: Alias auf mail.mysystems.tld, wird von vielen Mailclient automatisch gesucht und gefunden
  • smtp.mysystems.tld: Dasselbe f├╝r den SMTP-Dienst
  • domain2.tld: Eine zweite Domain neben mysystems.tld, f├╝r die E-Mails gesendet und empfangen werden sollen
  • domain3.tld: Eine dritte Domain, f├╝r die E-Mails verarbeitet werden sollen

Diese Domains m├╝ssen in der Anleitung selbstverst├Ąndlich durch eigene ersetzt werden. Auf domain2.tld und domain3.tld kann verzichtet werden, wenn der Mailserver nur f├╝r eine Domain genutzt werden soll.

Grundvoraussetzungen f├╝r einen eigenen Mailserver

  • Rootserver mit installiertem Ubuntu Server 16.04 LTS und statischer IP-Adresse (DSL-Adressbereiche werden von fremden Servern oftmals blockiert, daher empfehle ich, einen kleinen, g├╝nstigen, virtuellen Server in einem Rechenzentrum anzumieten.) Ein Singlecore-Server mit 1 GB RAM ist f├╝r private Zwecke v├Âllig ausreichend und bezahlbar ÔÇô zum Beispiel bei servercow.de (~5 ÔéČ / Monat) oder active-servers.com
  • Mindestens eine eigene Domain, die mit dem Mailserver benutzt wird + Kontrolle ├╝ber die DNS-Zone

Aufbau des Mailservers

Damit ihr einen ├ťberblick habt, wie die einzelnen Komponenten des Mailsystems zusammen geh├Âren, habe ich auch eine ├ťbersichtsskizze erstellt:

Mailserver Schema

Genutzte Software

Welche Softwareversionen verwendet werden, wisst ihr bereits. Doch welche Software ├╝bernimmt welche Aufgaben?

Dovecot

Dovecot ist ein weit verbreiteter MDA (Mail Delivery Agent) und IMAP-Server. Er sortiert ankommende E-Mails in die Postf├Ącher des jeweiligen Empf├Ąngers ein und stellt eine Schnittstelle zum Abrufen der Mailbox bereit (IMAP). Au├čerdem wird Dovecot in diesem Setup von Postfix als sog. SASL-Authentifizierungsserver genutzt: Postfix fragt Dovecot, ob ein bestimmter Benutzer berechtigt ist, sich am System anzumelden.

Aufgaben: Verwaltung der Mailbox, Bereitstellung einer Schnittstelle zum Abrufen erhaltener E-Mails, SASL-Authentifizierungsserver (├╝berpr├╝ft Benutzeranmeldung)

Postfix

Postfix wird oft zusammen mit Dovecot eingesetzt. Der popul├Ąre MTA (Mail Transfer Agent) k├╝mmert sich um alles, was mit dem Transport der E-Mail zu tun hat: Vom E-Mail Client zum eigenen Mailserver, und von dort aus zum jeweiligen Zielserver. Au├čerdem nimmt Postfix E-Mails von fremden Servern an und leitet sie an den MDA Dovecot weiter. Antispam-Software wird i.d.R. direkt in Postfix integriert, um eintreffende Spammails erst gar nicht in die Mailbox des Nutzers gelangen zu lassen.

Aufgaben: E-Mail-Transport und -Filterung

Anmerkung: Postfix ist “der eigentliche Mailserver”. E-Mails k├Ânnen ohne weiteres einzig und allein mit Postfix gesendet und empfangen werden. Alle weiteren Komponenten wie Dovecot, Amavis und Spamassassin machen uns das Leben allerdings einfacher ;-)

MySQL-Datenbank

Dovecot und Postfix werden so konfiguriert, dass sie eine MySQL-Datenbank als Backend (Datenbasis) nutzen. In der Datenbank werden zu nutzende Domains, Benutzer, Aliase und weitere Daten gespeichert. Durch einfaches Hinzuf├╝gen oder Entfernen von Datens├Ątzen in oder aus Datenbanktabellen k├Ânnen neue Benutzer oder Aliase angelegt oder gel├Âscht werden. Der Vorteil eines Datenbank-Backends ist, dass sich der Mailserver damit sehr einfach verwalten l├Ąsst: So lie├če sich zur Benutzerverwaltung beispielsweise eine Weboberfl├Ąche in PHP entwickeln, die die MySQL-Datenbank ver├Ąndert. Die Serverkonfiguration muss dann nicht manuell ge├Ąndert werden.

Aufgaben: Bereitstellung Betriebsdaten f├╝r Postfix und Dovecot

Amavis

Amavis ist ein E-Mail-Filter-Framework, welches zwischen einen MTA wie Postfix und die sog. Content-Filter (die Filterprogramme an sich) geschaltet wird. Postfix schleift alle E-Mails zun├Ąchst durch Amavis, wo sie dann nochmals durch die einzelnen Filter (z.B. Spamassassin) geschleust werden. Am Ende des Filterprozesses werden die Mails wieder an Postfix zur├╝ckzugeben. Neben der Aktivierung der Content-Filter hat Amavis auch die Aufgabe, eingehende E-Mails auf evtl. vorhandene DKIM-Signaturen zu pr├╝fen und diese zu verifizieren. Bei erfolgreicher Verifizierung sinkt die Wahrscheinlichkeit, dass eine E-Mail als Spam erkannt wird.

Aufgaben: Vermittlung zwischen Postfix und Content-Filter, DKIM-Verifizierung

Amavisd-Milter

Amavis kann leider nicht direkt als Milter in Postfix eingebunden werden. Abhilfe schafft amavisd-milter: Es bildet eine Schnittstelle zwischen Postfix und Amavis und ├╝bersetzt das Milter-Protokoll in das Amavis-eigene AMP.PDP-Protokoll.

Aufgaben: Vermittlung zwischen Postfix und Amavis

Spamassassin

Spamassassin ist ein Content-Filter, der zusammen mit Amavis genutzt werden kann. Er erkennt und markiert Spam-Emails anhand von Filterregeln und wird durch das Razor-netzwerk unterst├╝tzt.

Aufgaben: Erkennung und Markierung von Spammails

Razor / Pyzor

Pyzor ist die Python-Implementierung eines Razor-Clients. Mit Razor kann die Erkennungsrate von Spamassassin verbessert werden.

Aufgaben: Verbesserung der Spamassassin-Erkennungrate

OpenDKIM

Zur DKIM-Signierung der ausgehenden E-Mails wird OpenDKIM verwendet. Warum ich bei der DKIM-Signierung nicht auf Amavis setze, erkl├Ąre ich unten im Beitrag unter “Fragen und Antworten”.

Aufgaben: DKIM-Signierung

Vorbereitungen

Tipp: Reinen Tisch machen

Wenn ihr den Server vorher schon f├╝r etwas anderes (oder sogar ein anderes Mail-Setup) verwendet habt, stellt sicher, dass Reste aus alten Installationen das neue Setup nicht behindern. Speziell vorherige Mailserver-Versuche sollten r├╝ckstandslos entfernt werden (inkl. der zugeh├Ârigen Konfigurationsdateien). Am besten ist nat├╝rlich ÔÇô falls m├Âglich ÔÇô eine komplette Neuinstallation des Servers.

Login als Root

Bei der Installation von Ubuntu Server wird ein normaler Benutzeraccount, z.B. “thomas” eingerichtet, zu dem ihr euch via Passwort verbinden k├Ânnt. Der Root-Account ist standardm├Ą├čig nicht direkt zug├Ąnglich, sondern nur ├╝ber den Umweg via “sudo”. F├╝r diese Anleitung werden permanent Root-Rechte ben├Âtigt. ├ľffnet also am besten eine Root-Kommandozeile via

sudo -s

System aktualisieren

Bevor ihr neue Software-Pakete installiert, solltet ihr mittels

apt update && apt upgrade

sicherstellen, dass euer System aktuell ist. Bei der Gelegenheit bietet sich auch gleich ein Reboot an, um einen m├Âglicherweise aktualisierten Linux-Kernel zu laden.

Hostname und Server-FQDN setzen

Euer Server bekommt zwei Namen, ├╝ber die er identifiziert werden kann:

  • Lokalen Hostnamen: F├╝r die Identifizierung des Servers innerhalb der eigenen Infrastruktur, z.B. “mail”
  • FQDN (Fully Qualified Domain Name): F├╝r die weltweite Identifizierung im Internet, z.B. “mail.mysystems.tld”

Der FQDN muss nicht zwingend etwas mit den Domains zu tun haben, f├╝r die sp├Ąter E-Mails gesendet und empfangen werden sollen. Wichtig ist nur, dass euer k├╝nftiger Mailserver einen solchen Namen hat, der auch ├╝ber das DNS zur Server-IP-Adresse aufgel├Âst werden kann (dazu gleich mehr im Abschnitt “Einrichtung des DNS”). Den lokalen Hostnamen setzt ihr wie folgt:

echo "mail" > /etc/hostname

In der Datei /etc/hosts sollten FQDN und lokaler Hostname hinterlegt sein, z.B.:

127.0.0.1 mail.mysystems.tld mail localhost.localdomain localhost  
::1       mail.mysystems.tld mail localhost.localdomain ip6-localhost

Die Ausgaben der Kommandos “hostname” und “hostname -f” sollten nach den ├änderungen wie folgt aussehen:

root@mail:~# hostname
mail
root@mail:~# hostname -f
mail.mysystems.tld

Der FQDN (in diesem Beispiel “mail.mysystems.tld”) wird au├čerdem nach /etc/mailname geschrieben:

echo $(hostname -f) > /etc/mailname

Tipp: Unbound DNS Resolver installieren

Ein eigener, kleiner DNS-Resolver bringt durch lokales Caching nicht nur Performancevorteile mit sich, sondern auch Sicherheitsvorteile: Statt sich auf die Antworten fremder Resolver verlassen zu m├╝ssen, kann der lokale Resolver befragt werden. Der Server bietet DNSSEC-Funktionalit├Ąt und sehr schnell eingerichtet:

Beitrag: Unbound installieren

F├╝r den Zugriff auf Spamhaus-Blocklists (wie sie sp├Ąter in der Konfiguration verwendet werden) kann es sogar notwendig sein, seinen eigenen DNS-Resolver zu nutzen, weil z.B. Zugriffe ├╝ber das Google DNS blockiert werden.

Diffie-Hellman-Parameter t├Ąglich neu generieren

F├╝r maximal sichere TLS-Verbindungen mit Diffie-Hellman-Schl├╝sselaustausch wird empfohlen, die DH-Parameter t├Ąglich via Cronjob zu erneuern (Siehe auch Beitrag von mailbox.org). Dazu wird das Verzeichnis /etc/myssl erstellt ÔÇŽ

mkdir /etc/myssl

ÔÇŽ die Cronjob-├ťbersicht von root ge├Âffnet ÔÇŽ

crontab -e

und dieser Cronjob eingef├╝gt:

# DH parameter re-generation
@daily FILE=`mktemp` ; openssl dhparam -out $FILE 2048 > /dev/null 2>&1 && mv -f $FILE /etc/myssl/dh2048.pem

Das Kommando zur Generierung der DH-Parameter wird dann einmalig von Hand ausgef├╝hrt, um die dh2048.pem-Datei ein erstes Mal zu generieren:

FILE=`mktemp` ; openssl dhparam -out $FILE 2048 > /dev/null 2>&1 && mv -f $FILE /etc/myssl/dh2048.pem

Einrichtung des DNS

Zu Beginn dieser Anleitung wurde f├╝r den Mailserver der FQDN “mail.mysystems.tld” festgelegt. F├╝r diesen Domain-Namen werden nun A-Records im DNS-Zonefile der Domain “mysystems.tld” erstellt. Loggt euch bei eurem Domain-Provider ein und legt die folgenden Eintr├Ąge an ÔÇô der erste f├╝r die IPv4-IP-Adresse des Mailservers, die zweite f├╝r die IPv6-Adresse. (Beispiel!): Achtet im Folgenden vor allem auf den abschlie├čenden Punkt in den Domainnamen!

mail.mysystems.tld. 86400 IN A    5.1.76.155
mail.mysystems.tld. 86400 IN AAAA 2a00:f820:417::be19:7b23

“mail.mysystems.tld” ist damit im DNS bekannt. Wenn keine IPv6-Adresse genutzt wird, kann der zweite Record entfallen. Bleiben noch “imap.mysystems.tld” und “smtp.mysystems.tld”, die als Alias-Domains f├╝r “mail.mysystems.tld” angelegt werden. Sie sind nicht unbedingt notwendig, werden von vielen Mailclient aber gesucht und sind so ├╝blich:

imap.mysystems.tld. 86400 IN CNAME mail.mysystems.tld.
smtp.mysystems.tld. 86400 IN CNAME mail.mysystems.tld.

Mailclients k├Ânnen sich damit schon ├╝ber imap.mysystems.tld und smtp.mysystems.tld zum Mailserver verbinden. Andere Mailserver suchen bei der E-Mail-├ťbermittlung allerdings nicht nach A- oder CNAME-Records, sondern nach MX-Records. Ein MX-Record zeigt, welcher Mailserver f├╝r die E-Mails zu einer Domain zust├Ąndig ist. In meinem Beispiel soll sich unser Mailserver neben den E-Mails f├╝r mysystems.tld auch um die Mails f├╝r domain2.tld und domain3.tld k├╝mmern.

Im Zonefile der Domain “mysystems.tld” wird dazu dieser Record angelegt:

mysystems.tld. 86400 IN MX 0 mail.mysystems.tld.

In die Zonefiles der anderen Domains werden entsprechend die Records

domain2.tld. 86400 IN MX 0 mail.mysystems.tld.

und

domain3.tld. 86400 IN MX 0 mail.mysystems.tld.

angelegt.

Reverse DNS

Des weiteren muss ein sog. Reverse-DNS-Record / PTR f├╝r den FQDN des Mailservers angelegt werden. Dieser entspricht der Umkehrung eines normalen DNS-Records und ordnet einer IP-Adresse einen Hostnamen zu. Diesen Record kann nur der Inhaber des Netzes anlegen, aus dem eure IP-Adresse stammt. M├Âglicherweise k├Ânnt ihr so einen Reverse-DNS-Record in der Verwaltungsoberfl├Ąche eures Serveranbieters setzen, oder ihr bittet den Support, das zu tun. Der Domain-Name, der mit der IP-Adresse verkn├╝pft werden muss, ist der FQDN eures Mailservers. In meinem Beispiel mail.mysystems.tld. Denkt daran, f├╝r alle vom Mailserver genutzten, ├Âffentlichen IP-Adressen einen solchen Record zu erstellen. In dieser Anleitung wird eine IPv4- und eine IPv6-Adresse verwendet.

SPF-Records

Im Kampf gegen Spam und Phishing wurde das sog. Sender Policy Framework entwickelt (Siehe auch Beitrag: “Voraussetzungen f├╝r den Versand zu gro├čen E-Mail Providern”). Obwohl es sich nur als eingeschr├Ąnkt brauchbar erwiesen hat, erwarten die meisten Mailprovider g├╝ltige SPF-Records f├╝r andere Mailserver und pr├╝fen diese. SPF-Eintr├Ąge werden im Zonefile aller Domains erstellt, f├╝r die ein Mailserver E-Mails verschickt, und geben an, welche Server f├╝r eine Domain sendeberechtigt sind. F├╝r unsere Domain mysystems.tld wird der folgende Record im Zonefile von mysystems.tld angelegt:

mysystems.tld. 3600 IN TXT v=spf1 a:mail.mysystems.tld ?all

Hiermit erh├Ąlt nur der im A-Record “mail.msystems.tld” genannte Server f├╝r mysystems.tld eine Sendeberechtigung. Die Neutral-Einstellung “?all” sorgt daf├╝r, dass E-Mails von anderen Servern trotzdem angenommen werden sollen. Damit gehen wir Problemen beim Mail-Forwarding aus dem Weg. Wir erstellen den SPF-Record also eigentlich nur, damit andere Mailserver unseren Server wegen des existierenden Records positiv bewerten ÔÇô nicht, weil er seinen Nutzen entfalten soll.

In den Zonefiles der beiden Domains “domain2.tld” und “domain3.tld” wird (angepasst auf die Domain) jeweils dieser Record angelegt:

domain2.tld. 3600 IN TXT v=spf1 include:mysystems.tld ?all

├ťber das “include” wird der erste Record der Domain mysystems.tld eingebunden.

TLS-Zertifikate erstellen

Wer seinen eigenen Mailserver vern├╝nftig einsetzen will, kommt um die TLS-Verschl├╝sselung nicht herum. Immer mehr Server lassen keine unverschl├╝sselten Verbindungen mehr zu. Doch sp├Ątestens seit dem Start von LetÔÇÖs Encrypt gibt es auch keinen Grund mehr, kein TLS f├╝r Web- und Mailserver einzusetzen. Wie ihr euch ein TLS-Zertifikat von der kostenlosen Initiative “LetÔÇÖs Encrypt” ausstellen lassen k├Ânnt, habe ich bereits in diesem Beitrag erkl├Ąrt: Kostenlose TLS-Zertifikate f├╝r alle.

Der einfachste (und schnellste!) Weg zu g├╝ltigen Zertifikaten f├╝r die drei Beispiel-Domains “mail.mysystems.tld”, “imap.mysystems.tld” und “smtp.mysystems.tld” f├╝hrt ├╝ber die folgenden drei Kommandozeilen-Befehle:

apt install git
git clone https://github.com/certbot/certbot
cd certbot
./certbot-auto certonly --standalone --rsa-key-size 4096 -d mail.mysystems.tld -d imap.mysystems.tld -d smtp.mysystems.tld

Ein m├Âglicherweise laufender Webserver muss f├╝r den Zertifikatsdownload abgeschaltet sein, damit Certbot Port 80 nutzen kann!

Zertifikat und privater Schl├╝ssel werden unter /etc/letsencrypt/live/mail.mysystems.tld/ abgelegt. In eurem individuellen Fall unterscheidet sich der Pfad selbstverst├Ąndlich. Die Zertifikate sind ├╝brigens f├╝r Web- und Mailserver gleicherma├čen g├╝ltig: Technisch gibt es keinen Unterschied. Achtet auch auf die Erneuerung der Zertifikate! LE-Zertifikate sind nur 90 Tage lang g├╝ltig und m├╝ssen regelm├Ą├čig erneuert werden, z.B. via Cronjob. Anleitungen dazu gibt es zu gen├╝ge ;-)

In dieser Anleitung beziehe ich mich auf LetÔÇÖs Encrypt-Zertifikate, deshalb entspricht privkey.pem dem privaten Schl├╝ssel und fullchain.pem dem Zertifikat + Intermediate-Zertifikat. Selbstverst├Ąndlich funktionieren auch Zertifikate anderer Zertifikatsaussteller. Wichtig ist nur, dass das Zertifikat die drei Domains “mail.mysystems.tld”, “imap.mysystems.tld” und “smtp.mysystems.tld” beinhaltet.

MySQL Datenbank einrichten

Informationen ├╝ber zu verwaltende Domains, Benutzer, Weiterleitungen und sonstige Einstellungen soll der Mailserver aus einer MySQL-Datenbank ziehen. Das hat den Vorteil, dass der Server im laufenden Betrieb flexibel angepasst werden kann, ohne die Konfigurationsdateien ├Ąndern zu m├╝ssen. Die Datenbank erm├Âglicht uns au├čerdem ein virtualisiertes Mailserver-Setup: Die Benutzer auf den Mailservern m├╝ssen nicht mehr als reale Linux-Benutzer im System registriert sein, sondern nur noch in der Datenbank eingetragen werden.

Als DBMS wird Oracles MySQL-Datenbank genutzt. Wer will, kann stattdessen nat├╝rlich auch jeden anderen MySQL-kompatiblen Datenbankserver nutzen, z.B. MariaDB. Weil sich Oracles MySQl-Datenbankserver aber im “main” Repository von Ubuntu Server 16.04 befindet und deshalb im Gegensatz zu MariaDB garantierten Langzeitsupport erh├Ąlt, habe ich mich f├╝r das Original entschieden

apt install mysql-server

W├Ąhrend der Installation werdet ihr nach einem Passwort f├╝r den MySQL-user “root” (nicht den gleichnamigen Systembenutzer!) gefragt. Gebt ein m├Âglichst sicheres Passwort an. Mit dem Benutzernamen “root” und diesem Passwort werdet ihr euch nachher an der MySQL-Konsole anmelden.

Nach der Installation sollte der MySQL-Server bereits gestartet worden sein. Ein “systemctl status mysql” gibt einige Informationen zum Serverbetrieb aus. Wenn MySQL nicht l├Ąuft, k├Ânnt ihr es via “systemctl start mysql” starten.

Als n├Ąchstes wird eine neue Datenbank “vmail” mit einigen Tabellen angelegt, welche alle Informationen f├╝r unser Mailsystem beinhalten sollen. Meldet euch als DB-User “root” und dem zugeh├Ârigen Passwort an der MySQL-Kommandozeile an:

mysql -u root -p

Ein SQL-Kommando endet immer mit einem Semikolon ÔÇÜ ; ÔÇÜ. Mehrzeilige Befehle k├Ânnt ihr ohne weiteres einfach mit ENTER umbrechen, so wie sie im Folgenden dargestellt werden. Achtet auf die Unterscheidung zwischen “Tick” und “Backtick” ÔÇô der Backtick wird mit Shift + 2x Accent-Taste erzeugt. Kopiert die SQL-Statements am besten direkt in eure Zwischenanlage, statt sie m├╝hsam abzutippen.

Im ersten Schritt muss die neue vmail-Datenbank erzeugt werden:

create database vmail;

Ein neuer DB-User “vmail” mit dem Passwort “vmaildbpass” bekommt vollen Zugriff auf diese neue Datenbank:

grant all on vmail.* to 'vmail'@'localhost' identified by 'vmaildbpass';

Alle weiteren Kommandos zu Erstellung der Datenbank-Tabellen sollen sich auf die eben erzeugte Datenbank beziehen:

use vmail

Das Mail-Setup soll 4 verschiedene Tabellen nutzen. Kopiert die SQL-Statements einzeln und nacheinander in die MySQL-Kommandozeile und best├Ątigt jedes mal mit [Enter].

Domain-Tabelle

Die Domain-Tabelle enth├Ąlt alle Domains, die mit dem Mailserver genutzt werden sollen.

CREATE TABLE `domains` (
    `id` int unsigned NOT NULL AUTO_INCREMENT,
    `domain` varchar(255) NOT NULL,
    PRIMARY KEY (`id`),
    UNIQUE KEY (`domain`)
) CHARSET=latin1;

Account-Tabelle

CREATE TABLE `accounts` (
    `id` int unsigned NOT NULL AUTO_INCREMENT,
    `username` varchar(64) NOT NULL,
    `domain` varchar(255) NOT NULL,
    `password` varchar(255) NOT NULL,
    `quota` int unsigned DEFAULT '0',
    `enabled` boolean DEFAULT '0',
    `sendonly` boolean DEFAULT '0',
    PRIMARY KEY (id),
    UNIQUE KEY (`username`, `domain`),
    FOREIGN KEY (`domain`) REFERENCES `domains` (`domain`)
) CHARSET=latin1;

Die Account-Tabelle enth├Ąlt alle Mailserver-Accounts. Das Feld “quota” enth├Ąlt die Volumenbegrenzung f├╝r die Mailbox in MB (Megabyte). Im Feld “enabled” wird ├╝ber einen boolÔÇÖschen Wert festgelegt, ob ein Account aktiv ist, oder nicht. So k├Ânnen einzelne User tempor├Ąr deaktiviert werden, ohne gel├Âscht werden zu m├╝ssen. “sendonly” wird auf “true” gesetzt, wenn der Account nur zum Senden von E-Mails genutzt werden soll ÔÇô nicht aber zum Empfang. Das kann beispielsweise f├╝r Foren- oder Blogsoftware sinnvoll sein, die mit ihrem Account nur E-Mails verschicken soll.

Alias-Tabelle

CREATE TABLE `aliases` (
    `id` int unsigned NOT NULL AUTO_INCREMENT,
    `source_username` varchar(64) NOT NULL,
    `source_domain` varchar(255) NOT NULL,
    `destination_username` varchar(64) NOT NULL,
    `destination_domain` varchar(255) NOT NULL,
    `enabled` boolean DEFAULT '0',
    PRIMARY KEY (`id`),
    UNIQUE KEY (`source_username`, `source_domain`, `destination_username`, `destination_domain`),
    FOREIGN KEY (`source_domain`) REFERENCES `domains` (`domain`)
) CHARSET=latin1;

Die Alias-Tabelle enth├Ąlt alle Weiterleitungen / Aliase und ist eigentlich selbsterkl├Ąrend. Zur tempor├Ąren Deaktivierung von Weiterleitungsadressen gibt es wieder ein “enabled”-Feld.

TLS Policy-Tabelle

CREATE TABLE `tlspolicies` (
    `id` int unsigned NOT NULL AUTO_INCREMENT,
    `domain` varchar(255) NOT NULL,
    `policy` enum('none', 'may', 'encrypt', 'dane', 'dane-only', 'fingerprint', 'verify', 'secure') NOT NULL,
    `params` varchar(255),
    PRIMARY KEY (`id`),
    UNIQUE KEY (`domain`)
) CHARSET=latin1;

Mithilfe der TLS Policy Tabelle kann festgelegt werden, f├╝r welche Empf├Ąngerdomains bestimmte Sicherheitsbeschr├Ąnkungen beim Mailtransport gelten sollen. F├╝r einzelne Domains, z.B. “gmx.de” kann beispielsweise angegeben werden, dass diese E-Mails nur noch verschl├╝sselt ├╝bertragen werden d├╝rfen. Mehr dazu sp├Ąter.

Die Datenbank wird mit Datens├Ątzen bef├╝llt, sobald die Server fertig konfiguriert sind. Bis dahin k├Ânnt ihr die MySQL-Kommandozeile mit “quit” verlassen.

vmail-Benutzer und -Verzeichnis einrichten

Alle Mailboxen werden direkt im Dateisystem des Ubuntu Servers abgelegt. F├╝r die Zugriffe auf die Mailbox-Verzeichnisse wird ein eigener Benutzer “vmail” (“Virtual Mail”) erstellt, unter dem die Zugriffe von Dovecot und anderen Komponenten des Mailservers geschehen sollen. Einerseits wird so verhindert, dass Mailserver-Komponenten auf sensible Systemverzeichnisse Zugriff bekommen, andererseits k├Ânnen wir so die Mailboxen vor dem Zugriff von au├čen sch├╝tzen. Nur vmail (und root) d├╝rfen auf die Mailboxen zugreifen.

Das Verzeichnis /var/vmail/ soll alle Mailserver-relevanten Dateien (also Mailboxen und Filterscripts) enthalten und wird f├╝r den vmail-User als Home Directory festgelegt.

vmail-Verzeichnis erstellen:

mkdir /var/vmail

vmail-Systembenutzer erstellen:

adduser --disabled-login --disabled-password --home /var/vmail vmail

vmail Unterverzeichnisse erstellen:

mkdir /var/vmail/mailboxes
mkdir -p /var/vmail/sieve/global

/var/vmail an vmail-User ├╝bereignen und Verzeichnisrechte passend setzen:

chown -R vmail /var/vmail
chgrp -R vmail /var/vmail
chmod -R 770 /var/vmail

Dovecot installieren und konfigurieren

Nachdem die Datenbank und der vmail-User angelegt wurden, widmen wir uns nun dem Dovecot-Server. Wie bereits erw├Ąhnt, verwaltet dieser Server die Mailboxen und bekommt daher (in der Gestalt des vmail-Users) exklusiv Zugriff auf /var/vmail/. Zuerst m├╝ssen jedoch alle Serverkomponenten installiert werden:

apt install dovecot-core dovecot-imapd dovecot-lmtpd dovecot-mysql dovecot-sieve dovecot-managesieved dovecot-antispam
  • dovecot-core: Dovecot-Kern
  • dovecot-imapd: F├╝gt IMAP-Funktionalit├Ąt hinzu
  • dovecot-lmtp: F├╝gt LMTP (Local Mail Transfer Protocol)-Funktionalit├Ąt hinzu; LMTP wird als MTP-Protokoll zwischen Postfix und Dovecot genutzt
  • dovecot-mysql: L├Ąsst Dovecot mit der MySQL-Datenbank zusammenarbeiten
  • dovecot-sieve: F├╝gt Filterfunktionalit├Ąt hinzu
  • dovecot-managesieved: Stellt eine Schnittstelle zur Einrichtung der Filter via Mailclient bereit
  • dovecot-antispam: Trainiert Spamassassin ├╝ber das Verschieben von E-Mails in oder aus dem Spamordner

Nach der Installation wird Dovecot automatisch gestartet. Beendet Dovecot, solange wir keine fertige Konfiguration haben:

systemctl stop dovecot

Nun geht es an die Konfiguration. Die Dovecot-Konfigurationsdateien liegen im Verzeichnis /etc/dovecot/. Dort k├Ânnt ihr schon einige Konfigurationen sehen, die bei der Installation angelegt wurden. Mit meiner letzten Mailserver-Anleitung habe ich die Erfahrung gemacht, dass es besser ist, eine eigene Konfiguration von Grund auf anzulegen, statt die ├änderungen an bestehenden Dateien zu beschreiben. Deshalb wird zuerst einmal die gesamte Dovecot-Konfiguration eingestampft:

rm -r /etc/dovecot/*
cd /etc/dovecot

F├╝r Dovecot reichen die folgenden zwei Konfigurationsdateien aus. Den Inhalt k├Ânnt ihr einfach kopieren. Stellen, die angepasst werden m├╝ssen, habe ich blau markiert.

Datei dovecot.conf

###
### Aktivierte Protokolle
#############################

protocols = imap lmtp sieve



###
### TLS Config
#######################

ssl = required
ssl_cert = </etc/letsencrypt/live/mail.mysystems.tld/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.mysystems.tld/privkey.pem
ssl_dh_parameters_length = 2048
ssl_protocols = !SSLv2 !SSLv3
ssl_cipher_list = EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA256:EECDH:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!IDEA:!ECDSA:kEDH:CAMELLIA128-SHA:AES128-SHA
ssl_prefer_server_ciphers = yes



###
### Dovecot services
################################

service imap-login {
    inet_listener imap {
        port = 143
    }
}


service managesieve-login {
    inet_listener sieve {
        port = 4190
    }
}


service lmtp {
    unix_listener /var/spool/postfix/private/dovecot-lmtp {
        mode = 0660
        group = postfix
        user = postfix
    }

    user = vmail
}


service auth {
    ### Auth socket f├╝r Postfix
    unix_listener /var/spool/postfix/private/auth {
        mode = 0660
        user = postfix
        group = postfix
    }

    ### Auth socket f├╝r LMTP-Dienst
    unix_listener auth-userdb {
        mode = 0660
        user = vmail
        group = vmail
    }
}


###
###  Protocol settings
#############################

protocol imap {
    mail_plugins = $mail_plugins quota imap_quota antispam
    mail_max_userip_connections = 20
    imap_idle_notify_interval = 29 mins
}

protocol lmtp {
    postmaster_address = postmaster@mysystems.tld
    mail_plugins = $mail_plugins sieve
}



###
### Client authentication
#############################

disable_plaintext_auth = yes
auth_mechanisms = plain login


passdb {
    driver = sql
    args = /etc/dovecot/dovecot-sql.conf
}

userdb {
    driver = sql
    args = /etc/dovecot/dovecot-sql.conf
}


###
### Mail location
#######################

mail_uid = vmail
mail_gid = vmail
mail_privileged_group = vmail


mail_home = /var/vmail/mailboxes/%d/%n
mail_location = maildir:~/mail:LAYOUT=fs



###
### Mailbox configuration
########################################

namespace inbox {
    inbox = yes

    mailbox Spam {
        auto = subscribe
        special_use = \Junk
    }

    mailbox Trash {
        auto = subscribe
        special_use = \Trash
    }

    mailbox Drafts {
        auto = subscribe
        special_use = \Drafts
    }

    mailbox Sent {
        auto = subscribe
        special_use = \Sent
    }
}



###
### Mail plugins
############################


plugin {
    sieve_before = /var/vmail/sieve/global/spam-global.sieve   
    sieve = /var/vmail/sieve/%d/%n/active-script.sieve
    sieve_dir = /var/vmail/sieve/%d/%n/scripts

    quota = maildir:User quota
    quota_exceeded_message = Benutzer %u hat das Speichervolumen ├╝berschritten. / User %u has exhausted allowed storage space.

    antispam_backend = pipe
    antispam_spam = Spam
    antispam_trash = Trash
    antispam_pipe_program = /var/vmail/spampipe.sh
    antispam_pipe_program_spam_arg = --spam
    antispam_pipe_program_notspam_arg = --ham
}

“dovecot.conf” ist die Hauptkonfigurationsdatei des Dovecot-Servers:

SSL-Konfiguration: Dovecot generiert seine eigenen Diffie-Hellman-Parameter. Mit ssl_dh_parameters_length wird die gew├╝nschte L├Ąnge in Bits angegeben. 2048 Bit reichen aus. SSL Version 2 und 3 sind veraltet und sollen nicht mehr eingesetzt werden, deshalb werden sie abgeschaltet. Es folgt eine sog. “Cipherlist”, die die gew├╝nschten Verschl├╝sselungsmodalit├Ąten in absteigender Priorit├Ąt vorgibt. Client und Server einigen sich basierend auf dieser Priorisierung auf einen gemeinsam genutzten Cipher, und nutzen die st├Ąrkste Verschl├╝sselung, mit der beide Seiten arbeiten k├Ânnen. Die Cipherlist stammt von bettercrypto.org

Dovecot Services: Im darauf folgenden Abschnitt werden die Dovecot Services konfiguriert. Dazu geh├Ârt z.B. der Dienst “imap-login”, der auf eingehende Verbindungen von E-Mail Clients auf Port 143 horcht. Auch “managesieve-login” kommuniziert mit dem Mailclient, wenn dieser eine Funktion zur Bearbeitung Server-seitiger Filterscripte mitbringt. Die anderen Dienste werden intern genutzt: Der lmtp-Dienst stellt eine Schnittstelle bereit, ├╝ber die Postfix empfangene Mails an die Mailbox ├╝bergeben kann. Der “auth” Dienst wird vom LMTP-Dienst genutzt, um die Existenz von Benutzern zu ├╝berpr├╝fen, aber auch von Postfix, um den Login am Postfix-Server zu ├╝berpr├╝fen. Mit “mode”, “user” und “group” wird bestimmt, welcher Systemuser Zugriff auf den Dienst haben soll (Analog zu den Dateirechten ÔÇô der Socket f├╝r den Dienst ist nichts anderes als eine Datei).

Protocol settings: F├╝r die verwendeten Protokolle k├Ânnen zus├Ątzliche Einstellungen gesetzt werden ÔÇô u.A. auch, welche Erweiterungen im Zusammenhang mit dem Protokoll genutzt werden sollen. “quota” und “imap_quota” sind notwendig, um das maximale Volumen einer Mailbox festsetzen zu k├Ânnen. Beim lmtp-Protokoll kann auf diese Erweiterungen verzichtet werden: Hier wird nur die Sieve-Erweiterung zum Filtern von E-Mails ben├Âtigt.

Client Authentication: Die Zeilen

disable_plaintext_auth = yes
auth_mechanisms = plain login

scheinen sich zu widersprechen, schlie├člich wird die Klartext-Authentifizierung abgeschaltet. Doch tats├Ąchlich wird sie das nur f├╝r unverschl├╝sselte Verbindungen. TLS-Verschl├╝sselte Verbindungen bleiben davon unber├╝hrt, sodass in der n├Ąchsten Zeile die “plain” Authentifizierung mit Klartext-Passw├Ârtern wieder angeboten werden kann. Das wird aus zwei Gr├╝nden getan:

  • “Klartext” tut uns hier nicht weh ÔÇô schlie├člich ist die Verbindung sowieso (zwingend) verschl├╝sselt.
  • Alle Mailclients unterst├╝tzen die Klartextauthentifizierung. Andere Loginmechanismen werden weniger gut unterst├╝tzt und sind aufwendiger.

Wir konzentrieren uns deshalb auf die klassische Klartextauthentifizierung. Wie bereits erw├Ąhnt: Da unsere Verbindung ohnehin verschl├╝sselt ist, ist das in diesem Fall nicht sicherheitsrelevant.

F├╝r “passdb” und “userdb” wird jeweils der Pfad zur SQL-Datei eingestellt. Dort befindt sich jeweils eine passende SQL-Query. Die “passdb” wird befragt, wenn es um die Authentifizierung von Usern geht, die “userdb”, wenn die Existenz eines bestimmten E-Mail Kontos ├╝berpr├╝ft werden soll, oder benutzerdefinierte Einstellungen geladen werden m├╝ssen, wie z.B. das Mailbox-Kontingent (“Quota”).

Maillocation: In diesem Abschnitt wird definiert, unter welchem Systemuser Dovecot auf Dateisystem-Ebene mit E-Mails hantieren soll. Au├čerdem wird ein Pfad-Schema festgelegt, das bestimmt, nach welcher Struktur die Mailbox-Verzeichnisse angelegt werden sollen. %d steht f├╝r die Domain des Accounts und %u f├╝r den Benutzernamen vor dem @. Der Pfad zu einer Benutzermailbox lautet z.B.: /var/vmail/mailboxes/mysystems.tld/admin/mail/

Mailbox Configuration: In der Mailbox eines jeden Users soll sich standardm├Ą├čig ein “Spam”-Ordner befinden, in die ein passendes Sieve-Filterskript verd├Ąchtige E-Mails verschieben soll.

Mail Plugins: Hier werden die Details zu den Erweiterungen “sieve”, “quota” und “antispam” definiert. Das Script unter “sieve_before” wird f├╝r alle User (unabh├Ąngig von den eigenen Einstellungen) immer ausgef├╝hrt. Es hat die Aufgabe, von Spamassassin markierte Mails in den Spam-Ordner zu verschieben. “sieve_dir” definiert das Schema f├╝r den Ort, an dem benutzerdefinierte Scripts abgelegt werden. Das aktive Skript eines Nutzers soll jeweils ├╝ber den symbolischen Link “active-script.sieve” zug├Ąnglich sein.

Im Antispam-Teil wird konfiguriert, wie welches Skript aufgerufen werden soll, wenn eine E-Mail manuell in den Spam-Ordner verschoben oder wieder herausgenommen wird. Bei jedem Verschiebevorgang wird das Script mit den passenden Parametern “ÔÇôspam” oder “ÔÇôham” getriggert (mehr dazu gleich).

Datei dovecot-sql.conf

driver=mysql
connect = "host=127.0.0.1 dbname=vmail user=vmail password=vmaildbpass"
default_pass_scheme = SHA512-CRYPT

password_query = SELECT username AS user, domain, password FROM accounts WHERE username = '%n' AND domain = '%d' and enabled = true;

user_query = SELECT concat('*:storage=', quota, 'M') AS quota_rule FROM accounts WHERE username = '%n' AND domain = '%d' AND sendonly = false;

iterate_query = SELECT username, domain FROM accounts where sendonly = false;

Die Konfigurationsdatei “dovecot-sql.conf” enth├Ąlt alle SQL-relevanten Einstellungen:

  • driver: Welcher Datenbank-Treiber soll genutzt werden?
  • connect: Informationen zur Datenbankverbindung
  • default_pass_scheme: Standardm├Ą├čig angenommenes Hash-Schema, wenn es in der Datenbank nicht explizit angegeben ist, z.B. mit vorangestelltem {SHA512-CRYPT}.
  • password_query: SQL Query f├╝r die ├ťberpr├╝fung des User-Logins. Stimmen Benutzername und Passwort ├╝berein? Existiert der Benutzer und ist er aktiviert?
  • user_query: SQL-Query zum Abholen aller Benutzer-spezifischen Einstellungen. In diesem Fall: Maximales Mailbox-Volumen (“Quota”).
  • iterate_query: SQL-Query zur Abfrage aller verf├╝gbarer Benutzer. Benutzer, die keine Mails empfangen k├Ânnen (sendonly=true) sind f├╝r Dovecot nicht interessant und werden nicht mit ausgegeben.

dovecot-sql.conf enth├Ąlt sensible Datenbank-Zugangsdaten und wird deshalb besonders gesch├╝tzt:

chmod 770 dovecot-sql.conf

Antispam-Script f├╝r Spamassassin

Das vorher beschriebene Antispam-Script wird unter “/var/vmail/spampipe.sh” angelegt und hat folgenden, kurzen Inhalt:

#!/bin/bash
cat | sa-learn "$@" &
exit 0

Im Fall eines Verschiebevorgangs wird das Script mit der Option ÔÇôham oder ÔÇôspam ausgef├╝hrt und der E-Mail der verschobenen Mail zus├Ątzlich via Pipe ├╝bergeben. Das Spampipe.sh Skript nimmt die gepipe-te E-Mail via “cat” entgegen, ├╝bernimmt auch den jeweiligen Aufrufparameter und ├╝bergibt beides an das “sa-learn”-Tool, welches mit Spamassassin mitgeliefert wird. Das “&“-Zeichen am Ende des Kommandos sorgt daf├╝r, dass das Training in einen Hintergrundprozess ausgelagert wird. So wird sichergestellt, dass der Verschiebevorgang im Mailclient schnell bleibt.

Nun wird das Script an den User “vmail” ├╝bereignet (Unter diesem User f├╝hrt Dovecot das Script aus) und f├╝r diesen ausf├╝hrbar gemacht:

chown vmail:vmail /var/vmail/spampipe.sh
chmod u+x /var/vmail/spampipe.sh

Globales Filterscript f├╝r Spam

Unter /var/vmail/sieve/global/ wird das Sieve-Filterscript spam-global.sieve erstellt, das erkannte Spammails in den Unterordner “Spam” jeder Mailbox einsortiert. Spamassassin markiert erkannte E-Mails mit einem speziellen Spam-Header, den das Script erkennt. Inhalt von spam-global.sieve:

require "fileinto";
if header :contains "X-Spam-Flag" "YES" {
  fileinto "Spam";
}

Postfix installieren und konfigurieren

F├╝r unseren Postfix-Server ben├Âtigen wir nur zwei Pakete: Das Kernpaket “postfix” und die Komponente “postfix-mysql”, die Postfix mit der MySQL-Datenbank kommunizieren l├Ąsst.

apt install postfix postfix-mysql

W├Ąhrend der Installation werdet ihr nach der “Allgemeinen Art der Konfiguration” gefragt. W├Ąhlt an dieser Stelle “Keine Konfiguration” und beendet den Postfix-Server wieder:

systemctl stop postfix

Im Postfix-Konfigurationsverzeichnis /etc/postfix befinden sich trotz unserer Wahl “Keine Konfiguration” Konfigurationsdateien, die zun├Ąchst entfernt werden:

cd /etc/postfix
rm -r sasl
rm master.cf

Legt dann folgende Dateien im Verzeichnis /etc/postfix an: main.cf

##
## Netzwerkeinstellungen
##

mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
inet_interfaces = 127.0.0.1, ::1, 5.1.76.152, 2a00:f820:417::7647:b2c2
myhostname = mail.mysystems.tld


##
## Mail-Queue Einstellungen
##

maximal_queue_lifetime = 1h
bounce_queue_lifetime = 1h
maximal_backoff_time = 15m
minimal_backoff_time = 5m
queue_run_delay = 5m


##
## TLS Einstellungen
###

tls_ssl_options = NO_COMPRESSION
tls_high_cipherlist = EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA256:EECDH:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!IDEA:!ECDSA:kEDH:CAMELLIA128-SHA:AES128-SHA

### Ausgehende SMTP-Verbindungen (Postfix als Sender)

smtp_tls_security_level = dane
smtp_dns_support_level = dnssec
smtp_tls_policy_maps = mysql:/etc/postfix/sql/tls-policy.cf
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtp_tls_protocols = !SSLv2, !SSLv3
smtp_tls_ciphers = high
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt


### Eingehende SMTP-Verbindungen

smtpd_tls_security_level = may
smtpd_tls_protocols = !SSLv2, !SSLv3
smtpd_tls_ciphers = high
smtpd_tls_dh1024_param_file = /etc/myssl/dh2048.pem
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache

smtpd_tls_cert_file=/etc/letsencrypt/live/mail.mysystems.tld/fullchain.pem
smtpd_tls_key_file=/etc/letsencrypt/live/mail.mysystems.tld/privkey.pem


##
## Lokale Mailzustellung an Dovecot
##

virtual_transport = lmtp:unix:private/dovecot-lmtp


##
## Milter: DKIM-Signaturen durch OpenDKIM-Milter
## und Mail-Filter mit Amavis (via amavisd-milter)
##

milter_default_action = accept
milter_protocol = 2
smtpd_milters = unix:/var/run/amavis/amavisd-milter.sock,
                unix:/var/run/opendkim/opendkim.sock
non_smtpd_milters = unix:/var/run/opendkim/opendkim.sock

##
## Server Restrictions f├╝r Clients, Empf├Ąnger und Relaying
## (im Bezug auf S2S-Verbindungen. Mailclient-Verbindungen werden in master.cf im Submission-Bereich konfiguriert)
##

### Bedingungen, damit Postfix als Relay arbeitet (f├╝r Clients)
smtpd_relay_restrictions =      reject_non_fqdn_recipient
                                reject_unknown_recipient_domain
                                permit_mynetworks
                                reject_unauth_destination


### Bedingungen, damit Postfix ankommende E-Mails als Empf├Ąngerserver entgegennimmt (zus├Ątzlich zu relay-Bedingungen)
### check_recipient_access pr├╝ft, ob ein account sendonly ist
smtpd_recipient_restrictions = check_recipient_access mysql:/etc/postfix/sql/recipient-access.cf


### Bedingungen, die SMTP-Clients erf├╝llen m├╝ssen (sendende Server)
smtpd_client_restrictions =     permit_mynetworks
                                check_client_access hash:/etc/postfix/without_ptr
                                reject_unknown_client_hostname


### Wenn fremde Server eine Verbindung herstellen, m├╝ssen sie einen g├╝ltigen Hostnamen im HELO haben.
smtpd_helo_required = yes
smtpd_helo_restrictions =   permit_mynetworks
                            reject_invalid_helo_hostname
                            reject_non_fqdn_helo_hostname
                            reject_unknown_helo_hostname

# Clients blockieren, wenn sie versuchen zu fr├╝h zu senden
smtpd_data_restrictions = reject_unauth_pipelining



##
## Postscreen Filter
##

### Postscreen Whitelist / Blocklist
postscreen_access_list =        permit_mynetworks
                                cidr:/etc/postfix/postscreen_access
postscreen_blacklist_action = drop


# Verbindungen beenden, wenn der fremde Server es zu eilig hat
postscreen_greet_action = drop


### DNS blocklists
postscreen_dnsbl_threshold = 2
postscreen_dnsbl_sites = dnsbl.sorbs.net*1, bl.spamcop.net*1, ix.dnsbl.manitu.net*2, zen.spamhaus.org*2
postscreen_dnsbl_action = drop


##
## MySQL Abfragen
##

virtual_alias_maps = mysql:/etc/postfix/sql/aliases.cf
virtual_mailbox_maps = mysql:/etc/postfix/sql/accounts.cf
virtual_mailbox_domains = mysql:/etc/postfix/sql/domains.cf
local_recipient_maps = $virtual_mailbox_maps


##
## Sonstiges
##

### Maximale Gr├Â├če der gesamten Mailbox (soll von Dovecot festgelegt werden, 0 = unbegrenzt)
mailbox_size_limit = 0

### Maximale Gr├Â├če eingehender E-Mails in Bytes (50 MB)
message_size_limit = 52428800

### Keine System-Benachrichtigung f├╝r Benutzer bei neuer E-Mail
biff = no

### Nutzer m├╝ssen immer volle E-Mail Adresse angeben - nicht nur Hostname
append_dot_mydomain = no

### Trenn-Zeichen f├╝r "Address Tagging"
recipient_delimiter = +

Wichtiger Hinweis f├╝r Hetzner CX- vServer Kunden:

Die CX-vServer-Modelle von Hetzner haben ihre ├Âffentliche IP-Adresse nicht direkt an der Netzwerkschnittstelle anliegen. Wenn ihr ein “ip addr” ausf├╝hrt, seht ihr statt der ├Âffentlichen IP-Adresse eine private Adresse. Das liegt daran, dass Hetzner die ├Âffentliche Adresse auf die private Adresse “NATet”. (Mehr dazu unter “Warum hat meine VM die IP 172.31.1.100?” ÔÇô https://wiki.hetzner.de/index.php/VServer#Warum_hat_meine_VM_die_IP_172.31.1.100.3F). Verwendet in der Postfix-Konfiguration und allen ├╝brigen Konfigurationen also nicht die ├Âffentliche Adresse, sondern die private!

Erkl├Ąrung der Konfiguration in main.cf

Netzwerkeinstellungen:

  • mynetworks: Anfragen von diesen IP-Adressen / aus diesen IP-Adressbereichen werden von Postfix gesondert behandelt (Verwendung f├╝r “mynetworks” in den Restrictions). ├ťblicherweise werden hier die *lokalen Adressbereiche und IP-Adressen aus dem eigenen Netz eingetragen.
  • inet_interfaces: Auf diesen IP-Adressen soll Postfix seine Ports ├Âffnen. Die IP-Adressen m├╝ssen an den eigenen Server angepasst werden.
  • myhostname: Der Hostname des Mailservers, wie er bei der Mailverarbeitung genutzt werden soll.

Mail-Queue Einstellungen:

E-Mails in Postfix werden “gequeued”, d.h. in eine Warteschlange eingetragen, die regelm├Ą├čig abgearbeitet wird. Wenn Mails nicht zustellbar sind, verbleiben sie eine gewisse Zeit in der Queue, bis ihre Lebenszeit abgelaufen ist, und sie aus der Queue entfernt werden. Der Absender der E-Mail bekommt dann eine entsprechende Nachricht, in der er ├╝ber die Unzustellbarkeit informiert wird.

  • maximal_queue_lifetime: Lebensdauer einer normalen Nachricht in der Queue. Wenn eine E-Mail innerhalb einer Stunde nicht zugestellt werden konnte, wird sie aus der Queue entfernt und der Absender benachrichtigt.
  • bounce_queue_lifetime: Lebensdauer einer Unzustellbarkeits-Benachrichtigung in der Queue.
  • maximal_backoff_time: Maximale Zeit, die verstreichen darf, bis f├╝r eine E-Mail ein neuer Zustellversuch gestartet wird.
  • minimal_backoff_time: Zeit, die mindestens verstrichen sein muss, bis ein neuer Zustellversuch gestartet wird.
  • queue_run_delay: Intervall, in dem die Queue nach nicht zustellbaren E-Mails durchsucht wird.

TLS-Einstellungen:

Kompression wird abgeschaltet und (wie bei Dovecot) eine Cipherlist vorgegeben, sodass die bestm├Âgliche Verschl├╝sselung zwischen Client und Server genutzt wird. Im ersten Teilabschnitt werden die “smtp”-spezifischen TLS-Einstellungen festgelegt ÔÇô d.h. die Einstellungen, die Postfix als sendenden Kommunikationspartner (Mail-Client) betreffen.

  • smtp_tls_security_level: Standard-TLS-Policy, wenn sie in der Datenbank f├╝r die Empf├Ąngerdomain nicht anders spezifiziert wurde: “dane” kontrolliert zun├Ąchst, ob f├╝r den Empf├Ąngerserver ein TLSA-Eintrag (DANE) im DNS vorliegt. Wenn das der Fall ist, wird eine verschl├╝sselte Verbindung erzwungen und das vorgezeigte Serverzertifikat mittels TLSA-Eintrag verifiziert. Sollte kein TLSA-Eintrag verf├╝gbar sein, f├Ąllt Postfix in die Plicy “may” zur├╝ck und verschl├╝sselt nur, wenn der andere Server das unterst├╝tzt. Zertifikate werden dabei nicht validiert. Sollten vorhandene TLSA-Eintr├Ąge ung├╝ltig sein, wird stattdessen die “encrypt” Policy genutzt, welche zwar zwingend Verschl├╝sselt, aber Zertifikate ebenfalls nicht validiert. Mehr zu den TLS-Policies folgt sp├Ąter.
  • smtp_dns_support_level: DNSSEC-gesicherte DNS-Lookups aktiveren und nutzen, falls m├Âglich
  • smtpd_tls_policy_maps: Verweist auf die SQL-Queries, mit denen Empf├Ąngerdomain-spezifische TLS-Einstellungen geladen werden
  • smtp_tls_protocols: SSL v2 und v3 werden deaktiviert.

Nun zum zweiten TLS-Block: Dieser gilt f├╝r eingehende Verbindungen. Sowohl f├╝r andere Server, als auch Mailclients. Wieder werden SSL v2 und 3 deaktiviert und eine starke Cipherlist ausgew├Ąhlt. Eingehende Verbindungen k├Ânnen verschl├╝sselt sein, m├╝ssen aber nicht. Zus├Ątzlich wird die DH-Parameter-Datei geladen, f├╝r deren Generierung zuvor bereits ein Cronjob eingerichtet wurde.

“virtual_transport” ├╝bermittelt verarbeitete, eingehende E-Mails an den LMTP-Service von Dovecot, der sich dann um die Einordnung der Mail in die passende Mailbox k├╝mmert.

Server Restrictions:

Die Bl├Âcke unter “Server restrictions” sind besonders wichtig f├╝r die Sicherheit des Mailservers. Falsch eingestellt erlauben sie den unberechtigten Versand von E-Mails (Stichwort “Open Relay”). Der Mailserver wird dann als Spam-Schleuder missbraucht und landet sehr schnell auf einer Blacklist. Damit das nicht passiert, sollten die Restrictions (Beschr├Ąnkungen) sorgf├Ąltig eingestellt und mit einem passenden Open Relay Detektor ├╝berpr├╝ft sein.

Die Restrictions werden in Leserichtung nacheinander abgearbeitet. Am Ende jeder Verarbeitung steht immer ein “permit” oder “reject”. F├╝r das bessere Verst├Ąndnis ein Beispiel:

smtpd_relay_restrictions =      reject_non_fqdn_recipient
                                reject_unknown_recipient_domain
                                permit_mynetworks
                                reject_unauth_destination

“smtpd_relay_restrictions” bestimmt die Bedingungen, unter der Postfix als Mail-Relay (“Vermittlungsstelle”) arbeitet. Unser Postfix soll nur in drei F├Ąllen auf eingehende E-Mails reagieren:

  • Wenn ein Mailclient eine E-Mail via Postfix ins Internet schicken will
  • Wenn ein fremder Mailserver eine E-Mail an unseren Postfix schickt
  • Wenn vom Mailserver selbst aus eine Mail verschickt werden soll

Um den ersten Fall wird sich in der master.cf Datei gek├╝mmert. Dort wird werden die Relay Restrictions im Submission-Bereich so ├╝berschrieben, dass Mailclients nicht am freien Versenden gehindert werden. Aktuell interessieren daher nur die letzten beiden Anfrage-Typen. Die erste Zeile der Restriction lautet “reject_non_fqdn_recipient”. Sollte die Empf├Ąngeradresse keine vollwertige E-Mail Adresse sein, wird die Anfrage an Postfix direkt mit einem “reject” abgewiesen. Alle anderen Checks finden dann nicht mehr statt. Das f├╝hrt dazu, dass Postfix eine Weiterverarbeitung nur akzeptiert, wenn die zu verarbeitende E-Mail einen g├╝ltigen Empf├Ąnger hat. ├ähnliches gilt f├╝r “reject_unknown_recipient_domain”: Wenn die Empf├Ąngerdomain keinen g├╝ltigen MX- oder A-Eintrag im DNS hat (und der Zielserver damit nicht feststeht), wird die E-Mail abgelehnt.

Die darauf folgende Zeile enth├Ąlt die “Restriction” “permit_mynetworks”. Wenn der Anfragesteller lokal ist (bzw. seine IP in “mynetworks” vermerkt ist), wird er mit einem “permit” durchgewunken und die E-Mail wird weiter verarbeitet. Weitere Checks finden dann nicht statt. Sollte er nicht in mynetworks vermerkt sein, wird der letzte Check durchgef├╝hrt: “reject_unauth_destination” kann nur bestanden werden, wenn die zu verarbeitende E-Mail an eine Empf├Ąngeradresse dieses Mailsystems geht. Sollte bis zum Ende der restriction-Definition noch kein “permit” oder “reject” ausgel├Âst worden sein, wird automatisch ein “permit” ausgel├Âst und die jeweilige Aktion erlaubt.

Alle anderen Restriction-Definitionen funktionieren ├Ąhnlich: Die Kriterien werden nacheinander ├╝berpr├╝ft. Beginnt ein Kriterium mit einem “reject_“, wird bei Zutreffen ein “reject” ausgel├Âst, beginnt es mit einem “permit”, wird ein “permit” ausgel├Âst. In beiden F├Ąllen werden die nachfolgenden Kriterien nicht mehr ├╝berpr├╝ft.

smtpd_relay_restrictions: Kriterien, die ├╝berpr├╝ft werden, wenn Anfragen am Postfix-Server eintreffen (Von fremden Mailservern oder vom eigenen Server aus, z.B. via sendmail)
smtpd_recipient_restrictions: Kriterien, die zus├Ątzlich zu den relay_restrictions gepr├╝ft werden. Nur bei bestehen der Checks wird eine E-Mail auf dem lokalen System angenommen und an die Empf├Ąnger-Mailbox geschickt. An dieser Stelle wird ├╝ber eine SQL-Abfrage nachgefragt, ob ein bestimmter Empf├Ąnger E-Mails empfangen k├Ânnen soll (=> Siehe Option in der Datenbank, Accounts nur zum Versenden freizuschalten).
smtpd_client-restrictions: Kriterien, auf die hin andere Server ├╝berpr├╝ft werden, wenn Kontakt zum Postfix-Server hergestellt wird. (M├╝ssen g├╝ltigen Hostnamen und Reverse-DNS-Eintrag haben)
smtpd_helo_restrictions: Fremde Server m├╝ssen zu Beginn ihren g├╝ltigen Hostnamen nennen.
smtpd_data_restrictions: Ungeduldige Server sind oft Spammer.

Postscreen Filter:

Der Postscreen-Filter ist ein m├Ąchstiges Werkzeug, um Spammer-Server zu blockieren. Bevor ein fremder Server ├╝berhaupt eine E-Mail zustellen kann, ├╝berpr├╝ft Postscreen einige Merkmale des sendenden Servers und kann in den meisten F├Ąllen zuverl├Ąssig zwischen gutem und b├Âsen Server unterscheiden.

postscreen_access_list: In der Datei "/etc/postfix/postscreen_access k├Ânnen Ausnahmen f├╝r den Postscreen-Filter definiert werden.
DNS Blocklist: Postscreen kann anhand von Blacklists / Blocklists entscheiden, ob von einer bestimmten IP-Adresse h├Ąufig Spam ausgeht. Dazu werden die bekannten Blocklists unter "dnsbl_sites" befragt. Die zahl hinter dem Stern * ist dabei eine Gewichtung. Besonders zuverl├Ąssig arbeitende Blacklists bekommen eine h├Âhere Gewichtung, damit der Schwellwert "dnsbl_threshold" schneller erreicht ist. Sobald der Schwellwert bei einem Server ├╝berschritten wird, wird die Verbindung abgebrochen.

Vorsicht mit der zen.spamhaus.org-Blocklist! Spamhaus l├Ąsst Anfragen aus dem Google DNS nicht zu. Installiert am besten einen eigenen DNS-Resolver, um dem Problem aus dem Weg zu gehen.

MySQL-Abfragen:

Hier sind die Pfade zu den ├╝brigen SQL-Dateien angegeben, die Postfix ben├Âtigt, um Daten aus der Datenbank abfragen zu k├Ânnen.

master.cf

# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (no)    (never) (100)
# ==========================================================================

###
### Postscreen-Service: Pr├╝ft eingehende SMTP-Verbindungen auf Spam-Server
###
smtp      inet  n       -       n       -       1       postscreen
    -o smtpd_sasl_auth_enable=no
###
### SMTP-Daemon hinter Postscreen: Schleift E-Mails zur Filterung durch Amavis
###
smtpd     pass  -       -       n       -       -       smtpd
    -o smtpd_sasl_auth_enable=no
###
### dnsblog f├╝hrt DNS-Abfragen f├╝r Blocklists durch
###
dnsblog   unix  -       -       n       -       0       dnsblog
###
### tlsproxy gibt Postscreen TLS support
###
tlsproxy  unix  -       -       n       -       0       tlsproxy
###
### Submission-Zugang f├╝r Clients: F├╝r Mailclients gelten andere Regeln, als f├╝r andere Mailserver (siehe smtpd_ in main.cf)
###
submission inet n       -       n       -       -       smtpd
    -o syslog_name=postfix/submission
    -o smtpd_tls_security_level=encrypt
    -o smtpd_sasl_auth_enable=yes
    -o smtpd_sasl_type=dovecot
    -o smtpd_sasl_path=private/auth
    -o smtpd_sasl_security_options=noanonymous
    -o smtpd_relay_restrictions=reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_mynetworks,permit_sasl_authenticated,reject
    -o smtpd_sender_login_maps=mysql:/etc/postfix/sql/sender-login-maps.cf
    -o smtpd_sender_restrictions=permit_mynetworks,reject_non_fqdn_sender,reject_sender_login_mismatch,permit_sasl_authenticated,reject
    -o smtpd_client_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
    -o smtpd_helo_required=no
    -o smtpd_helo_restrictions=
    -o milter_macro_daemon_name=ORIGINATING
    -o cleanup_service_name=submission-header-cleanup
###
### Weitere wichtige Dienste f├╝r den Serverbetrieb
###
pickup    unix  n       -       n       60      1       pickup
cleanup   unix  n       -       n       -       0       cleanup
qmgr      unix  n       -       n       300     1       qmgr
tlsmgr    unix  -       -       n       1000?   1       tlsmgr
rewrite   unix  -       -       n       -       -       trivial-rewrite
bounce    unix  -       -       n       -       0       bounce
defer     unix  -       -       n       -       0       bounce
trace     unix  -       -       n       -       0       bounce
verify    unix  -       -       n       -       1       verify
flush     unix  n       -       n       1000?   0       flush
proxymap  unix  -       -       n       -       -       proxymap
proxywrite unix -       -       n       -       1       proxymap
smtp      unix  -       -       n       -       -       smtp
relay     unix  -       -       n       -       -       smtp
showq     unix  n       -       n       -       -       showq
error     unix  -       -       n       -       -       error
retry     unix  -       -       n       -       -       error
discard   unix  -       -       n       -       -       discard
local     unix  -       n       n       -       -       local
virtual   unix  -       n       n       -       -       virtual
lmtp      unix  -       -       n       -       -       lmtp
anvil     unix  -       -       n       -       1       anvil
scache    unix  -       -       n       -       1       scache
submission-header-cleanup unix n - n    -       0       cleanup
    -o header_checks=regexp:/etc/postfix/submission_header_cleanup

Die “master.cf” Datei will ich euch nur im Groben erkl├Ąren. Wichtig zu wissen ist, dass hier die Definition und Konfiguration der verschiedenen Postfix-Dienste wie z.B. postscreen, smtpd und smtp passiert. Gut zu erkennen ist, dass ├╝ber ein “ -o” weitere Parameter an einen Dienst ├╝bergeben werden. So beispielsweise beim Submission-Dienst, der auf Port 587 f├╝r die SMTP-Kommunikation mit den Mailclients bereitsteht: Die hier angegebenen Einstellungen z.B. zu “smtpd_relay_restrictions” ├╝berschreiben die Einstellungen in der main.cf ÔÇô allerdings nur f├╝r diesen einen spezifischen Dienst! Ein gutes Beispiel ist die Einstellung “smtpd_tls_security_level=encrypt”, die im Submission-Block steht. In der Main.cf hatten wir hier “may” definiert, um keine Server auszuschlie├čen, die TLS nicht beherrschen. Da smtpd-Einstellungen aber sowohl f├╝r andere Server als auch f├╝r Mailclient gelten, w├Ąre damit auch zu den Mailclients gesagt: “Ihr k├Ânnt verschl├╝sselte Verbindungen herstellen ÔÇô m├╝sst aber nicht”. Das wollen wir selbstverst├Ąndlich nicht! Mailclients sollen eine verschl├╝sselte Verbindung herstellen m├╝ssen! Deshalb wird die smtpd-Einstellung speziell f├╝r den Submission-Dienst mithilfe der “ -o” Option ├╝berschrieben und auf “encrypt” gesetzt.

F├╝r besseren Datenschutz wird der “Received”-Header (+ weitere Datenschutz-relevante Header) bei eingehenden E-Mails entfernt, wenn sie ├╝ber den Submission-Port eintreffen. Die meisten E-Mail-Clients senden ihren Namen und die Version mit. Zus├Ątzlich vermerkt Postfix bei eingehenden E-Mails, von welcher IP-Adresse die E-Mail stammt. Auf diese Informationen k├Ânnen wir verzichten, deshalb werden sie mithilfe eines kleinen zus├Ątzlichen Dienstes “submission-header-cleanup” (am Ende der Konfiguration) aus der E-Mail gel├Âscht. Im Submission-Bereich wird via “cleanup_service_name” festgelegt, dass bei eingehenden Mails auf dem Submission-Port (wird nur von Mailclients benutz) der Filter anzuwenden ist. Die Filterregeln befinden sich in der Datei /etc/postfix/submission_header_cleanup

Header Cleanup Regeln

Unter /etc/postfix/submission_header_cleanup wird eine Datei mit folgendem Inhalt angelegt:

### Entfernt Datenschutz-relevante Header aus E-Mails von MTUAs

/^Received:/            IGNORE
/^X-Originating-IP:/    IGNORE
/^X-Mailer:/            IGNORE
/^User-Agent:/          IGNORE

SQL-Konfiguration

Neben der Haupt-Konfiguration main.cf und der Service-Konfiguration master.cf werden noch ein paar Konfigurationsdateien innerhalb des Unterverzeichnisses sql/ angelegt, die die SQL-Queries f├╝r die Datenabfragen an die Datenbank enthalten:

mkdir /etc/postfix/sql && cd /etc/postfix/sql/

Erstellt dann die folgenden Konfigurationsdateien mit dem zugeh├Ârigen Inhalt:

accounts.cf

user = vmail
password = vmaildbpass
hosts = 127.0.0.1
dbname = vmail
query = select 1 as found from accounts where username = '%u' and domain = '%d' and enabled = true LIMIT 1;

aliases.cf

user = vmail
password = vmaildbpass
hosts = 127.0.0.1
dbname = vmail
query = select concat(destination_username, '@', destination_domain) as destinations from aliases where source_username = '%u' and source_domain = '%d' and enabled = true;

domains.cf

user = vmail
password = vmaildbpass
hosts = 127.0.0.1
dbname = vmail
query = SELECT domain FROM domains WHERE domain='%s'

recipient-access.cf

user = vmail
password = vmaildbpass
hosts = 127.0.0.1
dbname = vmail
query = select if(sendonly = true, 'REJECT', 'OK') AS access from accounts where username = '%u' and domain = '%d' and enabled = true LIMIT 1;

sender-login-maps.cf

user = vmail
password = vmaildbpass
hosts = 127.0.0.1
dbname = vmail
query = select concat(username, '@', domain) as 'owns' from accounts where username = '%u' AND domain = '%d' and enabled = true union select concat(destination_username, '@', destination_domain) AS 'owns' from aliases where source_username = '%u' and source_domain = '%d' and enabled = true;

tls-policy.cf

user = vmail
password = vmaildbpass
hosts = 127.0.0.1
dbname = vmail
query = SELECT policy, params FROM tlspolicies WHERE domain = '%s'

Alle SQL-Konfgurationsdateien in /etc/postfix/sql werden vor dem Zugriff durch unberechtigte User gesch├╝tzt:

chmod -R 660 /etc/postfix/sql

Weitere Postfix-Konfigurationsdateien

Au├čerdem gibt es noch zwei weitere Dateien in /etc/postfix, die zun├Ąchst leer bleiben k├Ânnen:

touch /etc/postfix/without_ptr
touch /etc/postfix/postscreen_access

Die Datei “without_ptr” kann Eintr├Ąge wie den folgenden beinhalten:

1.2.3.3 OK

Der Server mit dem IP 1.2.3.3 muss dann keinen gültigen PTR-Record mehr besitzen und wird trotzdem akzeptiert. Die without_ptr-Datei muss nach jeder Änderung in einer DB konvertiert und Postfix neu geladen werden:

postmap /etc/postfix/without_ptr
systemctl reload postfix

Im Moment reicht es aus, einfach nur eine leere DB zu generieren:

postmap /etc/postfix/without_ptr

Die Datei “postscreen_access” kann Ausnahme-IP-Adressen enthalten, die nicht von Postscreen ├╝berpr├╝ft werden sollen. Der Inhalt k├Ânnte beispielsweise so aussehen:

1.2.3.3 permit

Ein Server mit der IP-Adresse “1.2.3.3” wird dann nicht mehr von Postscreen kontrolliert. H├Ąngt man statt des “permit” ein “reject” an, wird der Server mit der jeweiligen IP-Adresse auf jeden Fall von Postscreen blockiert.

Zum Schluss wird einmal

newaliases

ausgef├╝hrt, um die Alias-Datei “/etc/aliases.db” zu generieren, die Postfix standardm├Ą├čig erwartet.

DKIM-Signierung mit OpenDKIM einrichten

DKIM ist ein Signaturverfahren, das dabei hilft, den Absender einer E-Mail sicher zu authentifizieren. Dabei werden ausgehende E-Mails automatisch mit einer kryptographischen Signatur versehen, die es dem Empf├Ąnger erm├Âglicht, zu ├╝berpr├╝fen, ob eine E-Mail tats├Ąchlich von dem Absender stammt, der angegeben ist. Zum Signieren wird OpenDKIM verwendet, das zun├Ąchst installiert werden muss:

apt install opendkim opendkim-tools

OpenDKIM wird gestoppt, bis die Konfiguration abgeschlossen ist:

systemctl stop opendkim

Die Konfiguration in /etc/opendkim.conf wird gel├Âscht ÔÇŽ

> /etc/opendkim.conf

ÔÇŽ und eine eigene Konfiguration in die Datei geschrieben:

/etc/opendkim.conf

Syslog              yes
LogResults          yes
LogWhy              yes
SyslogSuccess       yes
UMask               002
Canonicalization    relaxed/relaxed

# Nur signieren, nicht verifizieren (Verifizierung ├╝bernimmt Amavis)
Mode                s

KeyTable            /etc/opendkim/keytable
SigningTable        refile:/etc/opendkim/signingtable

Im n├Ąchsten Schritt wird zur besseren ├ťbersichtlichkeit ein neues Konfigurationsverzeichnis erstellt:

mkdir /etc/opendkim
cd /etc/opendkim

In einem Unterverzeichnis /etc/opendkim/keys soll der geheime Key f├╝r die Signaturen abgespeichert werden:

mkdir keys

Der Key wird mit dem folgenden Kommando generiert:

opendkim-genkey --selector=key1 --bits=2048 --directory=keys
  • selector: Ein frei w├Ąhlbarer Name f├╝r den Signaturschl├╝ssel. Oft wird statt “key1” die Jahreszahl der Key-Generierung gew├Ąhlt, um das Alter der verwendeten Schl├╝ssel zu erkennen.
  • bits: 2048 Bit Schl├╝ssell├Ąnge sind heutzutage Standard. DNS-Server k├Ânnen l├Ąngere Schl├╝ssel oft nicht aufnehmen, daher sind 2048 Bit die beste Wahl.
  • directory: Der Key wird im Unterverzeichnis “keys” abgespeichert

Nach der Generierung sollten sich im Unterverzeichnis “keys” zwei neue Dateien befinden: “key1.private” und “key1.txt” (oder anders benannt, je nach verwendetem Selektor). Die erste Datei enth├Ąlt den geheimen Schl├╝ssel f├╝r die Signierung. Die zweite Datei enth├Ąlt den ├Âffentlichen Schl├╝ssel in Form eines DNS-Records. Der Inhalt der key1.txt wird am besten wie folgt mit nano ge├Âffnet:

nano -$ keys/key1.txt

ÔÇŽ und sieht z.B. so aus:

2016._domainkey IN  TXT ( "v=DKIM1; k=rsa; "
      "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2VfV+CufdwZOeEGMr2owEtnomcsiELEOdYSpf
6WUHo0PqjVsm6ftsRu+7f45WZXyXCE/BL/FPRPL71M9CXCMNTkJgCCA061U29KT2q9dPyi8j6Kb64yDxeRq/RrSQQu
yarGnR7a/rvTjMS69FUCOeRYQfJQMRKEQ4bD/NFdEUKqaFFuDRObEY+V57yEdBEJ1oP6cyeGnj8IXKN"
      "0XfxCQOdDI16KpueA4uXLtyEpol+GBpTBr94yqt4u+RnwFSbIJhJUh4Aw/KuZzvFu4ikTbNC/EF/IwSsREd
3MhUcjXAhIbuO5XslAFvv7o06mLSWGekDslb11JoR2DjUfp9IAVJQIDAQAB" )  ; ----- DKIM key 2016 for
localhost

F├╝r alle verwendeten Domains (mysystems.tld, domain2.tld, domain3.tld) m├╝ssen auf Basis der vorherigen Ausgabe DNS-Records im jeweiligen Zonefile der Domains angelegt werden, z.B.:

key1._domainkey.mysystems.tld. 3600 IN TXT "v=DKIM1; k=rsa; " "p=MIIBIjANBg [...] AVJQIDAQAB"
key1._domainkey.domain2.tld. 3600 IN TXT "v=DKIM1; k=rsa; " "p=MIIBIjANBg [...] AVJQIDAQAB"
key1._domainkey.domain3.tld. 3600 IN TXT "v=DKIM1; k=rsa; " "p=MIIBIjANBg [...] AVJQIDAQAB"

Mit den beiden Konfigurationseinstellungen “KeyTable” und “SigningTable” in der Konfiguration oben wird bestimmt, welche Domain mit welchem Schl├╝ssel signiert werden soll. In der “KeyTable” werden alle verf├╝gbaren Keys aufgef├╝hrt: (Datei /etc/opendkim/keytable erstellen:)

keytable Inhalt:

default    %:key1:/etc/opendkim/keys/key1.private

Bedeutung: Der Key namens “default” gilt f├╝r alle Domains (%) in Kombination mit dem Selektor “key1” und befindet sich in der Datei key1.private.

Das %-Zeichen f├╝hrt dazu, dass bei einer Verifizierung der DKIM-Signatur durch einen fremden Mailserver das Zonefile der Absenderdomain nach einem DKIM-Record mit Public-Key durchsucht wird. (% wird bei der Verarbeitung von OpenDKIM durch die Absenderdomain ersetzt). Das hei├čt nichts anderes, als dass f├╝r jede Absender-Domain (mysystems.tld, domain2.tld und domain3.tld) ein DKIM-Record im DNS existieren muss. Es ist auch m├Âglich, das %-Zeichen durch eine fixe Domain z.B. mysystems.tld zu ersetzen. Es spielt dann keine Rolle mehr, unter welche Domain ein Absender f├Ąllt: Es wird immer unter mysystems.tld nach einem passenden DKIM-Publickey gesucht. Das bedeutet weniger Aufwand, weil nur noch ein einziger DKIM-Eintrag verwaltet werden muss, und nicht mehr f├╝r jede Absenderdomain ein eigener. Allerdings ist diese Vorgehensweise umstritten und wird nicht von allen Mailprovidern unterst├╝tzt. Es ist daher besser, die Variante mit “%” zu nutzen und f├╝r jede Domain den entsprechenden DKIM-Eintrag im DNS zu hinterlegen.

Eine weitere Datei “/etc/opendkim/signingtable” wird erstellt. Sie teilt bestimmten Absendern bestimmte Schl├╝ssel zu. In unserem Fall sollen alle E-Mails unter den eigenen Domains mit dem “default”-Schl├╝ssel signiert werden:

signingtable Inhalt:

*@mysystems.tld default
*@domain2.tld default
*@domain3.tld default

Der erste Teil in jeder Zeile ist dabei ein regul├Ąrer Ausdruck. *@mysystems.tld f├╝hrt also dazu, dass f├╝r alle Absender mit @mysystems.tld-Adresse der default-Key benutzt wird. Wenn f├╝r bestimmte Personen ein eigener Key verwendet werden soll, kann man das mit der vollst├Ąndigen Angabe einer E-Mail-Adresse so spezifizieren.

Da wir zum Signieren sowieso immer denselben Key verwenden, kann der Inhalt der signingtable auch durch diese Zeile ersetzt werden:

* default

Damit werden alle ausgehenden E-Mails f├╝r alle Domains signiert. Das ist vor allem dann praktisch, wenn man sehr viele Domains mit seinem Server betreut und die OpenDKIM-Konfiguration nicht st├Ąndig aktualisieren will. Allerdings wird wirklich alles signiert, was nach drau├čen geht ÔÇô das kann unter Umst├Ąnden Probleme geben, wenn Postfix eine E-Mail im Namen eines fremden Users weiterleitet. Andererseits sind solche Weiterleitungen allein wegen SPF schon eine haarige Angelegenheit. Wenn ihr sicher gehen wollt, benutzt die ausf├╝hrlichere Syntax (*@mysystems.tldÔÇŽ) oben. So k├Ânnt ihr f├╝r jede Domain einzeln und explizit DKIM ein- und ausschalten.

Nachdem die Konfiguration komplett ist, m├╝ssen noch Berechtigungen korrekt gesetzt werden. OpenDKIM ben├Âtigt Zugriff auf den DKIM-Schl├╝ssel:

chown opendkim /etc/opendkim/keys/key1.private

ÔÇŽ und Postfix wird Teil der opendkim-Gruppe, um auf den OpenDKIM-UNIX-Socket zugreifen zu k├Ânnen:

usermod -aG opendkim postfix

Amavis installieren und konfigurieren

Das Content Filter Framework Amavis bekommt eingehende E-Mails von Postfix via Milter (amavisd-milter) zur ├ťberpr├╝fung ├╝bermittelt, bevor sie vollst├Ąndig angenommen und in die Queue aufgenommen werden (=> Pre-Queue-Filter).

Amavis installieren:

apt install amavisd-new libdbi-perl libdbd-mysql-perl

Amavis stoppen:

systemctl stop amavisd-new

Die Konfigurationsdatei /etc/amavis/conf.d/50-user soll folgenden Inhalt haben:

use strict;

##
## Die Kommunikation mit Amavis soll ├╝ber einen Unix-Socket und ├╝ber das AM.PDP-Prokoll erfolgen.
## amavisd-milter nimmt E-Mails von Postfix ├╝ber die Milter-Schnittstelle bereit und ├╝bersetzt das Milter-Protokoll
## in das AM.PDP-Protokoll, da Amavis selbst kein Milter-Protokoll unterst├╝tzt.
## Postfix === Milter-Protokoll ===> Amavisd-Milter === AM.PDP-Protokoll ===> Amavis (und zur├╝ck)
##
$protocol = "AM.PDP";
$unix_socketname = "/var/run/amavis/amavisd.sock";
$inet_socket_port = undef;


##
## Policy-Bank f├╝r E-Mails von Mailclients
## E-Mails, die durch den Submission-Port f├╝r Mailclients in das Mailsystem gelangen, bekommen via Postfix-Option
## -o milter_macro_daemon_name=ORIGINATING eine "Markierung" mit "ORIGINATING". Amavis soll diese "Markierung" erkennen
## und in diesem Fall keine Untersuchung auf Spam durchf├╝hren.
## Lokale Absender (z.B. via mailx-Kommando) sind von der Spam-Untersuchung nicht betroffen, da Amavis sie automatisch als
## solche (Client 127.0.0.1) erkennt.
##

$policy_bank{'ORIGINATING'} = {
    originating => 1,
    bypass_spam_checks_maps => [1]
};


###
### F├╝r welche Domains ist der Mailserver zust├Ąndig?
### => Datenbank befragen
###

@local_domains_maps = ( [] );

@lookup_sql_dsn = ( ['DBI:mysql:database=vmail;host=127.0.0.1;port=3306', 'vmail', 'vmaildbpass'], );

$sql_select_policy = 'SELECT "Y" as local, 1 as id FROM domains WHERE CONCAT("@",domain) IN (%k)';
$sql_select_white_black_list = undef;


##
## DKIM-Verifizierung aktivieren
## Amavis pr├╝ft DKIM-Signaturen eingehender E-Mails (falls vorhanden).
## Ist die Signatur in Ordnung, wird der Spam-Score nach unten korrigiert.
##

$enable_dkim_verification = 1;

###
### Spamassassin settings
###

### Spam-Checks aktivieren
@bypass_spam_checks_maps = (\%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re);
$sa_tag_level_deflt = -999;         # Informationen zu Spam-Score ab diesem Level (hier: immer) in den Header schreiben
$sa_tag2_level_deflt = 6.2;         # Ab diesem Level E-Mails als Spam markieren
$sa_kill_level_deflt = 6.9;         # Ab diesem Level E-Mails nicht annehmen, sondern Aktion in "final_spam_destiny" ausl├Âsen (REJECT)

$sa_spam_subject_tag = undef;       # Kein ***SPAM*** in den Betreff schreiben, falls Spam
$spam_quarantine_to = undef;        # Spam nicht in die Quarant├Ąne verschieben
$final_spam_destiny = D_REJECT;     # Aktion, wenn kill_level erreicht wurde: E-Mail nicht annehmen und REJECT ausl├Âsen


###
### Falls Benachrichtigungsmails an User geschickt werden sollen (z.B. bei geblockter Mail)
###

$notify_method  = 'smtp:[127.0.0.1]:25';


#------------ Do not modify anything below this line -------------
1;  # ensure a defined return

Die Amavis-Konfiguration enth├Ąlt Datenbank-Zugangsdaten und wird deshalb vor dem Zugriff durch nicht privilegierte Systemuser gesch├╝tzt:

chmod 770 /etc/amavis/conf.d/50-user

Amavisd-Milter installieren

Amavisd-Milter ist der Vermittler zwischen Postfix und Amavisd und ├╝bersetzt das Milter-Protokoll in das AM.PDP-Protokoll. Leider enthalten die Ubuntu-Repositories nur eine veraltete Version von amavisd-milter, die mit der “ORIGINATING”-Markierung (siehe oben) nicht umgehen kann. Deshalb m├╝ssen wir Amavisd-Milter Version 1.6.1 von Hand herunterladen, kompilieren und installieren:

cd ~
wget 'https://github.com/ThomasLeister/amavisd-milter/archive/master.zip' -O amavisd-milter.zip

Zum Kompilieren werden GCC, die Library “libmilter-dev” und “make” ben├Âtigt ÔÇô zum Entpacken “unzip”:

apt install gcc libmilter-dev make unzip

Entpacken, konfigurieren, kompilieren und installieren:

unzip amavisd-milter.zip
cd amavisd-milter-master
./configure
make
make install
make clean

Die Quelldateien k├Ânnen gel├Âscht werden:

cd ~
rm -r amavisd-milter-master
rm amavisd-milter.zip

Unter /usr/local/sbin/ sollte jetzt das Binary “amavisd-milter” zu sehen sein. F├╝r die komfortablere Steuerung von amavisd-milter wird noch Init-Script f├╝r systemd unter /etc/systemd/system/amavisd-milter.service angelegt:

[Unit]
Description=Amavis Milter Interface amavisd-milter
Requires=amavisd-new.service
After=amavisd-new.service

[Service]
User=amavis
Group=amavis
PermissionsStartOnly=true
Type=forking
PIDFile=/var/run/amavis/amavisd-milter.pid

ExecStart=/usr/local/sbin/amavisd-milter -B -p /var/run/amavis/amavisd-milter.pid -w /var/lib/amavis -s /var/run/amavis/amavisd-milter.sock -S /var/run/amavis/amavisd.sock -m 2
ExecStartPost=/bin/chown postfix:postfix /var/run/amavis/amavisd-milter.sock
ExecStartPost=/bin/chmod 0660 /var/run/amavis/amavisd-milter.sock

KillMode=process

[Install]
WantedBy=multi-user.target

Skript aktivieren:

systemctl enable amavisd-milter

(Wer nicht mit Ubuntu 16.04 arbeitet, sondern z.B. mit Ubuntu 14.04, kann alternativ dieses init.d-Script nutzen, das ein Leser bereitgestellt hat: https://gist.github.com/anonymous/b1744df1533bd59ead8b5d70e2769de3) Spamassassin installieren

Spamassassin installieren:

apt install spamassassin

Spamassassin f├╝r MySQL konfigurieren

Spamassassin kann anhand von Beispielen besser auf die Erkennung von Spammails trainiert werden. Erlernte Spammails und harmlose Mails werden dazu in einer Datenbank abgespeichert. Standardm├Ą├čig nutzt Spamassassin eine BerkeleyDB in Form einer Datei, was die Performance allerdings stark einschr├Ąnkt und das Teilen der vorhandenen Datenbasis erschwert. Sinnvoller ist es, die Trainingsdaten in einer MySQL-Datenbank abzuspeichern. F├╝r diese Zwecke wird eine separate Datenbank auf dem DB-Server angelegt. Loggt euch als MySQL-root ein, legt eine neue Datenbank “spamassassin” an und gebt einem neuen User Zugriff auf diese Datenbank:

mysql -u root -p

create database spamassassin;
grant all on spamassassin.* to 'spamassassin'@'localhost' identified by 'spamasspwd';

quit;

Nun muss noch das passende Tabellenschema in die neue Datenbank geladen werden:

cat /usr/share/doc/spamassassin/sql/bayes_mysql.sql | mysql -u root -p spamassassin

(Passwort f├╝r MySQL-User root wird abgefragt)

In der Postfix-Konfigurationsdatei /etc/mail/spamassassin/local.cf wird Spamassassin auf eine MySQL-Anbindung umgestellt. Der Inhalt der Konfigurationsdatei besteht zu diesem Zeitpunkt nur aus Kommentaren, die via

> /etc/mail/spamassassin/local.cf

entfernt werden k├Ânnen. Gebt der Datei danach folgenden Inhalt:

bayes_store_module Mail::SpamAssassin::BayesStore::MySQL
bayes_sql_dsn DBI:mysql:spamassassin:localhost
bayes_sql_username spamassassin
bayes_sql_password spamasspwd
bayes_sql_override_username vmail

Das Datenbank-Passwort muss selbstverst├Ąndlich angepasst werden. Von nun an speichert Spamassassin s├Ąmtliche Trainingsdaten in der performanten MySQL-Datenbank. Ein weiterer Vorteil liegt darin, dass verschiedene User nun unkompliziert ├╝ber das sa-learn-Tool Spamassassin-Training mit Spammails durchf├╝hren k├Ânnen. Das nutzen wir mit Dovecot und dem Antispam-Modul bereits aus.

local.cf enth├Ąlt Zugangsdaten zur Datenbank und wird deshalb besonders gesch├╝tzt. Standardm├Ą├čig hat jeder Systembenutzer Lesezugriff auf die Datei. Dieser wird nun entfernt:

setfacl -m o:--- /etc/mail/spamassassin/local.cf

Die User “vmail” und “amavis” ben├Âtigen dennoch Zugriff auf die Datei, um korrekt mit Spamassassin arbeiten zu k├Ânnen. Ihnen wird Lesezugriff ├╝ber eine ACL gew├Ąhrt:

setfacl -m u:vmail:r /etc/mail/spamassassin/local.cf
setfacl -m u:amavis:r /etc/mail/spamassassin/local.cf

(u.U muss zuvor noch das Paket “acl” installiert werden: “apt install acl”)

Spamassassin Wartungsscript erstellen

Das Wartungsscript wird via Cronjob t├Ąglich ausgef├╝hrt und die Aufgabe, die offiziellen Filterregeln von Spamassasson.org und die Netzwerk-eigenen Filterregeln von mailbox.org zu aktualisieren.

Das Script wird unter /root/sa-care.sh angelegt und hat diesen Inhalt:

#!/bin/bash

sa-update --nogpg --channel spamassassin.heinlein-support.de
sa-update --channel updates.spamassassin.org

Script ausf├╝hrbar machen:

chmod u+x sa-care.sh

Das Script wird in die Cronjobs von root aufgenommen:

crontab -e

# Spamassassin care
@daily /root/sa-care.sh

F├╝hrt das sa-care.sh abschlie├čend einmal aus, um die Filterregeln zu aktualisieren:

./sa-care.sh

Razor und Pyzor installieren

Das gemeinschaftliche Razor-Netzwerk hilft, Spam ├╝ber Pr├╝fsummen zuverl├Ąssiger zu erkennen:

apt install razor pyzor

Als User “amavis” einloggen:

sudo -i -u amavis

Bei Razor registrieren und Serverliste downloaden:

razor-admin -create
razor-admin -register
pyzor discover

“amavis”-User wieder verlassen:

exit

Spamassassin wird das Razor-Netzwerk f├╝r die Spamerkennung automatisch nutzen.

Datenbank mit Datens├Ątzen f├╝llen

Bevor der Mailserver sinnvoll genutzt werden kann, m├╝ssen noch Domains und Benutzer im der MySQL-Datenbank registriert werden. Loggt euch wieder auf der MySQL-Kommandozeile ein:

mysql -u root -p

ÔÇŽ und wechselt in die vmail-Datenbank:

use vmail

Neue Domain anlegen

Damit ein neuer Benutzeraccount oder ein neuer Alias angelegt werden kann, muss die zu nutzende Domain zuvor im Mailsystem bekannt gemacht werden. Postfix verarbeitet nur E-Mails an Domains, die in der “domains”-Tabelle eingetragen sind:

insert into domains (domain) values ('mysystems.tld');

Neuen E-Mail-Account anlegen

Wenn die Benutzerdomain in der Domain-Tabelle angelegt ist, kann ein neuer Benutzeraccount f├╝r den Mailserver erstellt werden:

insert into accounts (username, domain, password, quota, enabled, sendonly) values ('user1', 'mysystems.tld', '$kgid87hdenss', 2048, true, false);

$kgid87hdenss steht hier stellvertretend f├╝r einen SHA512-CRYPT String, der vor Abschicken des SQL-Statements mit dem Kommando

doveadm pw -s SHA512-CRYPT

in der Linux-Kommandozeile generiert werden kann. Statt das Passwort im Klartext in der Datenbank zu hinterlegen, wird ein starker kryptographischer Hash des Passworts hinterlegt. Das bringt den Vorteil, dass Passw├Ârter von einem Eindringling nicht aus der DB ausgelesen werden k├Ânnen (Wichtiges Sicherheitsfeature!). Der Hash-String h├Ąngt nicht nur von dem verwendeten Passwort ab und ver├Ąndert sich deshalb von Mal zu Mal. Wundert euch also nicht, wieso ihr jedes mal einen anderen Hash-String bekommt, obwohl ihr dasselbe Passwort nutzt ;-) Tipp: Speichert am besten nicht nur den eigentlichen Hash ab “$6$” ab, sondern nehmt den vorderen Teil ({SHA512-CRYPT} ÔÇŽ) mit. Das hilft Dovecot, zu erkennen, welcher Hash-Typ vorliegt und kann bei der Migration von Passwort-Schemata sehr hilfreich sein!

Neuen Alias anlegen

insert into aliases (source_username, source_domain, destination_username, destination_domain, enabled) values ('alias', 'mysystems.tld', 'user1', 'mysystems.tld', true);

ÔÇŽ legt einen Alias f├╝r den Benutzer “user1@mysystems.tld” an. E-Mails an “alias@mysystems.tld” werden dann an die Mailbox dieses Users zugestellt.

Als Zieladressen k├Ânnen auch E-Mail-Konten auf fremden Servern angegeben werden. Postfix leitet diese E-Mails dann weiter. Dabei kann es allerdings zu Problemen mit SPF-Records kommen ÔÇô schlie├člich schickt Postfix unter bestimmten Umst├Ąnden E-Mails unter fremden Domains, f├╝r die er laut SPF-Record nicht zust├Ąndig ist. SRS (Sender Rewriting Scheme) ist eine L├Âsung f├╝r dieses Problem. Von Erweiterungen, die schwerwiegende Design-Fehler einer Technik wie SPF korrigieren, halte ich allerdings nicht besonders viel, sodass ich euch empfehle, den SPF-Record (wie oben) auf einem “?all” gestellt zu lassen und auf Weiterleitungen zu fremden Servern m├Âglichst zu verzichten. Aliase von lokalen Adressen auf andere lokale Adressen sind kein Problem.

Wenn ein E-Mail-Verteiler eingerichtet werden soll, m├╝ssen mehrere Datens├Ątze mit derselben Quelladresse eingerichtet werden, also so:

team@domain.tld => user1@domain.tld
team@domain.tld => user2@domain.tld
team@domain.tld => user3@domain.tld

… etc

Neue TLS-Policy anlegen

Mithilfe der TLS Policy-Tabelle kann festgelegt werden, mit welchen Sicherheitsfeatures mit den Mailservern einer bestimmten Domain kommuniziert werden soll. Wenn f├╝r die Domain “thomas-leister.de” beispielsweise “dane-only” in “policy” festgelegt wird, wird die Verbindung zu Mailservern dieser Domain nur noch g├╝ltig sein, wenn sie DANE-authentifiziert und verschl├╝sselt ist. M├Âgliche Policies sind:

  • none: Keine Verschl├╝sselung nutzen, auch wenn der andere Mailserver das unterst├╝tzt.
  • may: Verschl├╝sseln, wenn der andere Server dies unterst├╝tzt, aber keine Zertifikatspr├╝fung (self-signed Zertifikate werden akzeptiert).
  • encrypt: Zwingend Verschl├╝sseln, allerdings keine Zertifikatspr├╝fung (self-signed Zertifikate werden akzeptiert).
  • dane: Wenn g├╝ltige TLSA-Records gefunden werden, wird zwingend verschl├╝sselt und das Zertifikat mittels DANE verifiziert. Falls ung├╝ltige TLSA-Records gefunden werden, wird auf “encrypt” zur├╝ckgegriffen. Falls gar keine TLSA-Records gefunden werden, wird “may” genutzt.
  • dane-only: Nur verschl├╝sselte Verbindungen. G├╝ltige TLSA-Records f├╝r den Hostnamen m├╝ssen existieren (DANE)
  • verify: Nur verschl├╝sselte Verbindungen + Pr├╝fung der CA. Der Hostname aus dem MX DNS-Record muss im Zertifikat enthalten sein. (Basiert auf Vertrauen in korrekte DNS-Daten)
  • secure: Nur verschl├╝sselte Verbindungen + Pr├╝fung der CA. Der andere Mailserver muss (standardm├Ą├čig) einen Hostnamen haben, der “.domain.tld” oder nur “domain.tld” entspricht. Dieser Hostname muss im Zertifikat enthalten sein. Auf das DNS wird nicht zur├╝ckgegriffen (Sicherheitsvorteil gegen├╝ber “verify). Beispiel: Eine E-Mail an user@web.de soll gesendet werden. Der MX-Mailserver von Web.de d├╝rfte dann nur den Hostnamen “web.de” oder eine Subdomain davon als Hostnamen haben, z.B. mx.web.de. Eine Verbindung zu mx.web.net w├Ąre nicht zul├Ąssig.

F├╝r Domains der gro├čen Anbieter wie gmx.de, web.de und der Telekom kann man “secure” w├Ąhlen. Bei Posteo und Mailbox.org sogar “dane-only”. F├╝r alle Provider, die keine g├╝ltigen TLS-Zertifikate einsetzen, kann “encrypt” gew├Ąhlt werden. Standardeinstellung f├╝r alle anderen Mailserver ist “dane” (siehe main.cf der Postfix Config).

Das Feld “params” wird mit zus├Ątzlichen Infos gef├╝llt, wenn sie f├╝r einen Policy-Typ erforderlich sind, z.B. f├╝r einen “secure” Eintrag zu GMX:

insert into tlspolicies (domain, policy, params) values ('gmx.de', 'secure', 'match=.gmx.net');

Standardm├Ą├čig ├╝berpr├╝ft Postfix bei “secure” ÔÇô wie oben bereits erw├Ąhnt ÔÇô ob die Empf├Ąngerdomain (gmx.de) im Zertifikat des Zielservers vorhanden ist. Bei GMX (und vielen anderen gro├čen Anbietern) ist das allerdings nicht der Fall: Die Mailserver-Zertifikate von GMX sind nur f├╝r gmx.net + Subdomains g├╝ltig. Lie├če man den Datenbank-Eintrag f├╝r GMX ohne weitere Einstellungen auf “secure” stehen, k├Ânnten an GMX keine Mails mehr ├╝bermittelt werden. Deshalb ist es wichtig, f├╝r GMX festzulegen, dass im Zertifikat nicht nach “gmx.de” sondern nach “gmx.net” gesucht werden soll. Das k├Ânnen wir mithilfe des Felds “params” und der “match=ÔÇŽ” Zeichenkette tun. Wenn nach mehreren Domains gesucht werden soll, k├Ânnen auch mehrere angegeben werden, z.B. so: “match=.gmx.net:.gmx.ch”. Die zus├Ątzlichen Angaben in “params” sind allerdings nicht f├╝r jeden Mailprovider notwendig. GMX ist eine Ausnahme ÔÇô genauso wie z.B. Yahoo. Ob ihr in “params” einen “match”-String angeben m├╝sst, k├Ânnt ihr z.B. ├╝ber https://de.ssl-tools.net/ herausfinden. Wenn die 2-nd-Level-Domain des Mailservers von der Domain der Mailadressen abweicht, muss ein passender match-String angegeben werden.

Andere Einstellungen wie “dane-only” erfordern keine zus├Ątzlichen Angaben in “params”:

insert into tlspolicies (domain, policy) values ('mailbox.org', 'dane-only');

In diesem Fall wird mit den Mailservern von mailbox.org nur noch DANE-gesichert und verschl├╝sselt kommuniziert.

Die MySQL-Kommandozeile kann mit einem “quit” wieder verlassen werden.

Hier hat jemand auf GitHub eine Liste mit verschiedenen Mailprovidern und den m├Âglichen TLS Policies zusammengestellt: https://github.com/csware/postfix-tls-policy/blob/master/tls_policy-dane

Lukas Zorn (siehe Kommentare, Danke!) hat sich die M├╝he gemacht, fertige SQL Inserts f├╝r einige Mailprovider zu erstellen. Ich habe eine Kopie als Github Gist ver├Âffentlicht: https://gist.githubusercontent.com/ThomasLeister/c9d16205318ab3dc68b13923a6ceab93/raw/6ae2ee86d42ec280f3459d09d20f4ef800da4cab/tlspolicies.sql

Hinweis vom 30.05.2017: Die genannten Listen sind nicht mehr aktuell!

Start all the things!

Euer neuer Mailserver ist jetzt fertig konfiguriert. Zeit f├╝r einen ersten Start!

systemctl start dovecot
systemctl start amavisd-new
systemctl start amavisd-milter
systemctl start opendkim
systemctl start postfix

Kontrolliert am besten gleich die Logfiles nach auff├Ąlligen Fehlern. Ich empfehle das “tail” Tool in einer separaten Terminal-Sitzung. Neue Log-Eintr├Ąge erscheinen damit sofort auf dem Bildschirm:

tail -f /var/log/syslog

Wenn ihr hier Fehler entdeckt, seht nach, ob ihr alle erforderlichen ├änderungen an den Konfigurationsdateien durchgef├╝hrt habt. (Siehe auch: “Thomas, mein Mailserver funktioniert nicht!” weiter unten) Eine Verbindung zum Mailserver herstellen

Eine Verbindung k├Ânnt ihr ├╝ber jeden IMAP-f├Ąhigen E-Mail-Client und den folgenden Verbindungsparametern herstellen:

  • IMAP-Server: mail.mysystems.tld | Port: 143 | STARTTLS (auch f├╝r domain2 und domain3!)
  • SMTP-Server: mail.mysystems.tld | Port: 587 | STARTTLS (auch f├╝r domain2 und domain3!)
  • (optional Managesieve: mail.mysystems.tld | Port: 4190 | STARTTLS) (auch f├╝r domain2 und domain3!)
  • Benutzername: Die volle E-Mail-Adresse
  • Passwort: Sollte bekannt sein ;-)

Spamfilter testen

Schickt einfach eine E-Mail mit dem Text

XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X

an einen Account eures neuen Mailservers. Die E-Mail sollte nicht ankommen. In den Logs sollte zu lesen sein, dass die Mail von Amavis wegen Verdachts auf Spam abgelehnt wurde.

Hat dir diese Anleitung geholfen?

Wenn ich dir mit dieser Anleitung helfen konnte, deinen Mailserver aufzusetzen, ist dir das vielleicht ein paar Euros wert. Wie du dir sicherlich vorstellen kannst, war es eine Menge Arbeit, diese Anleitung zu erproben und zu formulieren. Da freue ich mich nat├╝rlich riesig ├╝ber ein wenig finanzielle Unterst├╝tzung, sodass ich beispielsweise Testserver f├╝r diese und andere Anleitungen mieten kann. Wie du mir etwas zukommen lassen kannst, erf├Ąhrst du hier: Unterst├╝tzen

Herzlichen Dank! :-)

Passend zu dieser Anleitung …

Rainloop-Plugin f├╝r Aliase

Neomedes hat ein Rainloop-Plugin ver├Âffentlicht, ├╝ber das sich innerhalb der beliebten Webmail-Oberfl├Ąche neue Aliase f├╝r das eigene Konto anlegen lassen: https://github.com/Neomedes/rainloop-plugin-aliaslist-mysql


“Thomas, mein Mailserver funktioniert nicht!”

Das passiert leider hin und wieder. Diese Anleitung habe ich nach Fertigstellung zwar selbst nochmals auf einem jungfr├Ąulichen System Schritt f├╝r Schritt (und mehrmals) ausprobiert, dennoch kann es sein, dass du dich beim Konfigurieren vertippt hast oder einen Schritt versehentlich ├╝bersprungen hast. In dem Fall kannst du deinen kompletten Server einstampfen und alles neu einrichten ÔÇô oder du suchst gezielt nach dem Fehler und versuchst, ihn zu beheben:

Schritt 1: Logfiles analysieren

Das Mailsystem ist ziemlich mitteilungsfreudig und loggt s├Ąmtliche Vorg├Ąnge das Syslog. Nutze “tail -f”, um die neuesten Log-Eintr├Ąge zu sehen:

tail -f /var/log/syslog

Fehlermeldungen sollten auch f├╝r unge├╝bte relativ schnell auffindbar sein. Meistens kommt in solchen Meldungen irgendwo “error” oder “failed” vor.

Schritt 2: Fehlerquelle finden

Das ist leichter gesagt, als getan. Trotzdem k├Ânnen einige Fehler schnell gefunden und behoben werden. Ein

Connect failed to database

oder

table lookup problem

deutet beispielsweise stark darauf hin, dass mit der Datenbankverbindung etwas nicht stimmt. Welche Ursachen kommen daf├╝r in Frage? Z.B.:

  • Nicht erreichbarer Datenbank-Server
  • Falscher DB-Benutzername, Passwort oder DB-Name
  • Fehlende Tabellenstrukturen
  • Nicht ausreichende Berechtigungen f├╝r den Zugriff auf die DB

Ihr glaubt gar nicht, wie viele “Hilfe, nichts geht!”-E-Mails ich schon von Lesern bekommen habe, weil Passw├Ârter falsch in die Konfiguration ├╝bertragen wurden ;-)

Wenn du die Ursache selbst nicht finden kannst

  • ÔÇŽ f├╝hrt der Weg immer zuerst zu Google. Einfach die Fehlermeldung oder das Symptom (am besten in englischer Sprache) suchen, und das erste Stackoverflow-Ergebnis anklicken ;-) Die meisten Probleme k├Ânnen durch Stackoverflow-Threads oder Eintr├Ąge aus Mailinglisten gefunden und behoben werden. Wenn du an dem Problem verzweifelst

  • ÔÇŽ lohnt es sich oft, einen Kollegen oder Freund / bekannten zu Rate zu ziehen. Am besten jemanden, der sich mit Mailservern besch├Ąftigt, und das Symptom vielleicht schon kennt. Alternativ kann man sich auch Hilfe in Foren wie forum.ubuntuusers.de oder nat├╝rlich auf Stackoverflow und anderen bekannten Plattformen holen.

“Kannst du mir nicht helfen?”

M├Âglicherweise. Ich m├Âchte allerdings nicht ÔÇô und ich denke das ist verst├Ąndlich ÔÇô t├Ąglich mit der Fehleranalyse von Mailsystemen besch├Ąftigt sein. Schreibe mir bitte nur, wenn …

  • Selbst versucht hast, das Problem zu l├Âsen
  • Sonst keinen Rat mehr wei├čt

Lieber ist es mir, wenn Hilfe in den daf├╝r vorgesehenen Linux-Foren, z.B. auf ubuntuusers.de gesucht wird. Eine evtl. Probleml├Âsung ist dann auch anderen Nutzern zug├Ąnglich.

Fragen und Antworten

“Danke f├╝r die Anleitung. Kann ich mich irgendwie revanchieren?”

├ťber ein “Dankesch├Ân” via E-Mail freue ich mich, aber z.B. auch ├╝ber eine kleine Finanzspritze f├╝r meinen Blog via Bitcoin, PayPal oder auf anderem Wege. Damit kann ich beispielsweise meine Server bezahlen. Vielleicht magst du diesen Beitrag auch weiterempfehlen? Auch daf├╝r bin ich dankbar :-)

“Kannst du mir meinen Mailserver aufsetzen?”

Klar! Gegen einen angemessenen Obolus bin ich dazu gerne bereit. Schreibe mir dazu einfach eine E-Mail.

“Wieso noch eine Mailserver-Anleitung? Es gibt doch schon so viele!”

Tats├Ąchlich kann man den Eindruck haben, zu jedem Linux-Blog geh├Âre mittlerweile ein E-Mail Tutorial. Nat├╝rlich habe ich dar├╝ber nachgedacht, ob es ├╝berhaupt sinnvoll ist, den Aufwand zu betreiben, und die tausendste Anleitung dazu zu schreiben. Aber nat├╝rlich habe ich gute Gr├╝nde: Ich bin w├Ąhrend meiner ersten Schritte zum eigenen Mailserver fast verzweifelt: Es gibt zwar Unmengen an Mailserver-Anleitungen im Netz, und trotzdem gibt es zu viele How-Tos, die nie wirklich getestet wurden oder schon veraltet sind. Diese Anleitung wurde mehrmals auf einem frisch installierten Ubuntu Server getestet. Ich kann also bis zu einem gewissen Grad garantieren, dass euer Mailserver funktioniert, wenn ihr die Anleitung exakt durcharbeitet. Einige Artikel zum Thema finde ich auch nicht ausf├╝hrlich genug. Wie Eingangs schon erkl├Ąrt, geht es mir bei diesem Beitrag auch darum, ein wenig zu erkl├Ąren, was hier eigentlich passiert. Und nicht zuletzt: Es gibt diese Anleitung, weil ich der Meinung bin, dass es nicht genug geben kann. Jeder Autor erkl├Ąrt etwas anders, jeder stellt ein leicht ver├Ąndertes Setup vor. Ich hatte Lust, mein eigenes Setup in diesem Beitrag zu erkl├Ąren, weil es gut funktioniert.

“Darf ich deine Anleitung ├╝bernehmen?”

Nein. Du kannst dir sicherlich vorstellen, dass hinter meiner Anleitung viel M├╝he und Arbeit steckt. Ich stelle sie nicht frei zur Verf├╝gung und bitte darum, meinen Text nicht ohne ausdr├╝ckliche Zustimmung zu re-publizieren (auch nicht in privaten, aber ├Âffentlich zug├Ąnglichen Blogs!). Also ein klares “Nein” zu Copy & Paste + Wiederver├Âffentlichung. Private, nicht-├Âffentliche Kopien oder Kopien f├╝r den Firmen-internen Gebrauch sind nat├╝rlich erlaubt. Es geht mir auch darum, diesen Beitrag nicht auf irgendeinem fremden Blog wiederzufinden, der wom├Âglich sogar noch Geld mit fremden Content verdient. Verlinken ist nat├╝rlich absolut erlaubt und ausdr├╝cklich erw├╝nscht ;-)

“Wieso ver├Âffentlichst du deine Anleitung auf deinem Blog und nicht in einem Wiki?”

Weil ich hier die volle Kontrolle habe. Was hier steht, ist in sich konsistent und kein Flickenteppich. In den g├Ąngigen Wikis darf dieser Beitrag nat├╝rlich gerne erg├Ąnzend verlinkt werden.

“Gibt es f├╝r dieses neue Mailserver-Setup schon einen Web-Client zur Verwaltung?”

Aktuell ist WebMUM nicht mit dieser Anleitung kompatibel. Solltet ihr das ├Ąndern wollen ÔÇô nur zu. Der Code ist auf GitHub unter der MIT Lizenz frei verf├╝gbar. Vielleicht beginne ich demn├Ąchst mit der Entwicklung eines neuen Verwaltungstools speziell f├╝r dieses Setup. Ansonsten steht es nat├╝rlich jedem frei, selbst ein solches Werkzeug zu entwickeln und vielleicht sogar frei verf├╝gbar zu machen. Im Wesentlichen m├╝ssen nur Datens├Ątze erstellt, bearbeitet und gel├Âscht werden. Das kann man z.B. auch als PHP-Anf├Ąnger gut umsetzen.

Update am 14.07.2017: Andreas Bresch hat ein Webinterface zu dieser Anleitung entwickelt: https://github.com/Andreas-Bresch/vmailManage/

Wie kann ich mit diesem Setup Catch-All Adressen realisieren?

Dazu sind ein paar Änderungen notwendig. Ich habe mich mit der Thematik noch nicht selbst befasst, aber ein Leser hatte hiermit Erfolg:

1) source_username in aliases Tabelle als nullable (= null bei catchall) konfigurieren. In der MySQL-Kommandozeile:

alter table aliases modify source_username varchar(64) null;

2) Die Query in aliases.cf anpassen

query = SELECT concat(destination_username, '@', destination_domain) as destinations FROM aliases WHERE source_username ='%u' and  source_domain ='%d' and enabled = true UNION ALL SELECT concat(destination_username, '@', destination_domain) as destinations FROM aliases WHERE source_username is null and  source_domain ='%d' and enabled = true AND not exists (SELECT id FROM aliases WHERE source_username ='%u' and  source_domain ='%d' and enabled = true);

Ich habe das nicht getestet!

“Wieso benutzt du nicht einfach Amavis als Content-Filter? Wieso das umst├Ąndliche Setup mit Amavis als Milter?”

Amavis kann als Content-Filter keine E-mails Pre-Queue abweisen, d.h. unerw├╝nschte Mails werden von Postfix erst angenommen, um dann in der Queue zu landen und letztendlich nur gel├Âscht zu werden. Der Absender einer betroffenen E-Mail erh├Ąlt keine Information dar├╝ber, dass seine E-Mail beim Empf├Ąnger nicht angekommen ist. Das ist rechtlich bedenklich, denn solche E-Mails gelten als zugestellt. Filtert der Server wichtige E-Mails f├Ąlschlicherweise weg und erleidet der Empf├Ąnger dadurch einen Schaden, haftet der Provider. Die bessere L├Âsung ist es daher, E-Mails direkt beim Eingang wieder abzuweisen, sodass der Absender eine entsprechende Benachrichtigung zur Unzustellbarkeit erh├Ąlt. Das direkte Abweisen beim Empfang ist im Betrieb als content_filter nicht m├Âglich, deshalb muss Amavis Pre-Queue eingebunden werden. Dazu gibt es zwei M├Âglichkeiten: Amavis kann als smtpd_proxy_filter in dem smtpd-Service eingebunden werden (h├Ąufig gew├Ąhlte L├Âsung) oder als Milter (Underground-L├Âsung) integriert werden. Ich habe mir f├╝r die wenig dokumentierte Milter-L├Âsung entschieden, denn auf amavis.org wird darauf hingewiesen, dass Amavis eigentlich nicht f├╝r den Betrieb als smtpd_proxy_filter konzipiert ist und es deshalb zu Problemen kommen k├Ânnte:

“The Postfix Before-Queue Content Filter setup, also known as smtpd_proxy setup, is not a supported or recommended setup with amavisd-new, which is not a transparent SMTP proxy by design. See caveats in README_FILES/SMTPD_PROXY_README. This setup might work amavisd-new for low-traffic sites which do not use authentication, but is not recommended.” ÔÇô amavis.org

Der zweite Grund f├╝r die Integration als Milter statt smtpd_proxy_filter ist, dass SMTP-Filter nicht zusammen mit Miltern genutzt werden sollten. Man sollte sich f├╝r eines entscheiden: Nur smtpd_proxy_filter oder nur Milter. Da ich OpenDKIM als Milter einsetzen will, sollte auch Amavis als Milter eingebunden werden. Ich hatte eine kurze Zeit lang Amavis als smtpd_proxy_filter integriert und OpenDKIM als Milter. Das hat dazu gef├╝hrt, dass OpenDKIM eingehende E-Mails nicht mehr als solche erkennen konnte und alles nur noch “ausgehend” war. Das Ergebnis war, dass Spammails, bei denen der Absender auf meine eigene Domain gef├Ąlscht war, beim Eingang von meinem eigenen Server DKIM-Signiert wurden. Dass das nicht der Sinn von DKIM ist, brauche ich euch nicht zu erkl├Ąren.

Einen dritten Grund habe ich auch: Die Integration als Milter sieht in der Postfix-Konfiguration sauberer aus: Statt eines Reinjection-Services auf Port 10025 und einiger -o Parameter werden nur wenige milter_-Zeilen in der main.cf ben├Âtigt. Die Konfiguration wird dadurch schlanker und ├╝bersichtlicher.

“Wieso nutzt du OpenDKIM, und nicht die integrierten DKIM-Funktionen von Amavis?”

OpenDKIM als funktional getrennter Dienst, der alleine f├╝r die DKIM-Signierung ausgehender E-Mails zust├Ąndig ist, gef├Ąllt mir besser. Die Konfiguration ist ├╝bersichtlicher, und s├Ąmtliche E-Mails, die den Server unter den verschiedensten Domains verlassen, k├Ânnen mit wenigen Einstellungen signiert werden. Dazu kommt, dass Amavis bei sehr vielen eingehenden E-Mails bereits ausgelastet sein k├Ânnte. E-Mails, die nach drau├čen gehen sollen, k├Ânnen dann nicht gleich versendet werden und der Absender erh├Ąlt in seinem Mailclient eine Fehlermeldung. ich habe lange ├╝berlegt, wie und ob ich Amavis / OpenDKIM / Milter nutze, und bin letztendlich zu dem Ergebnis gekommen, dass mir dieses getrennte Setup mit Miltern am besten gef├Ąllt: Amavis filtert eingehende E-Mails ÔÇô OpenDKIM signiert ausgehende Mails.

“Wieso nutzt du UNIX-Sockets statt lokaler TCP-Sockets?”

UNIX-Sockets sind wesentlich performanter und ihrem Zweck schneller zuzuordnen.

H├Ąufige Fehler

“fatal: no SASL authentication mechanisms” / “SASL: Connect to private/auth failed: No such file or directory”

Das Problem: Postfix kann Benutzer nicht authentifizieren, weil in /var/spool/postfix/private kein “auth” Socket verf├╝gbar ist. Eigentlich sollte Dovecot diesen Socket bereitstellen. Der Fehler ist also bei Dovecot zu suchen ÔÇô nicht bei Postfix. Leider hat die Erfahrung gezeigt, dass ein Vertipper nicht zwingend in der Socket-Konfiguration

unix_listener /var/spool/postfix/private/auth {
    mode = 0660
    user = postfix
    group = postfix
}

vorhanden sein muss. Es kommt immer wieder vor, dass der Fehler irgendwo anders in der Dovecot-Konfiguration liegt. Dovecot verschweigt einem dann den Fehler und erstellt den auth-Socket f├╝r Postfix nicht. Es lohnt sich in so einem Fall, noch einmal die ganze Dovecot-Konfiguration nach Fehlern abzusuchen. “5.7.1 Service unavailable; client [1.3.3.7] blocked using zen.spamhaus.org”

Das Problem: Der Mailserver akzeptiert keine E-Mails vom Mailclient und gibt die oben genannte Fehlermeldung zur├╝ck.

Das Problem l├Ąsst sich sehr einfach l├Âsen, indem statt SMTP-Port 25 der Submission-Port 587 f├╝r den Mailversand im Mailclient konfiguriert wird. Auf Port 25 ist eine Blacklist aktiv, welche viele IP-Adressen z.B. aus DSL-Adressbereichen enth├Ąlt. Diese Einschr├Ąnkung gilt f├╝r Port 587 nicht. Mailclients sollten immer port 587 f├╝r den Versand nutzen.

Mailclient verbindet sich nicht zum Server

  • Evtl. blockiert der Virenschutz die Verbindung?
  • Blockiert die Server-Firewall die Verbindung von au├čen?
  • Ist die richtige Serveradresse angegeben? (siehe Verbindungseinstellungen oben)

Changelog

  • 22.04.2016

    • Spamassassin Training (sa-learn) entfernt: Siehe Kommentare
  • 26.04.2016

    • Amavis / Spamassassin via smtpd_proxy_filter eingebunden, um Spammails direkt beim Empfang ablehnen zu k├Ânnen
    • F├╝r DKIM-Signierung wird jetzt OpenDKIM statt Amavis eingesetzt. Amavis kann seine Worker so zu 100% der Spamabwehr widmen. Durch den Einsatz von smtpd_proxy_filter h├Ątte Amavis bei gro├čer Inbound-Auslastung m├Âglicherweise keine Worker mehr f├╝r die DKIM-Signierung bereitgestellt und E-Mails h├Ątten den Mailserver nicht mehr verlassen k├Ânnen. Daher werden f├╝r Spamabwehr und DKIM-Signierung nun zwei verschiedene Softwarekomponenten eingesetzt.
    • Oracle MySQL statt MariaDB: MariaDB befindet sich nicht im “main” Repository von Ubuntu 16.04 und wird daher nicht von offizieller Seite Langzeit-unterst├╝tzt ÔÇô MySQL hingegen schon. Aus dem Wechsel zu MySQL ergibt sich auch, dass f├╝r Amavis zus├Ątzlich libdbi-perl und libdbd-mysql-perl installiert werden m├╝ssen, welche vorher automatisch durch MariaDB mitgeliefert wurden.
    • Ausf├╝hrung von “newaliases” nach der Postfix-Installation ausf├╝hren, um Fehler im Log zu verhindern.
  • 28.04.2016

    • “newaliases” erst nach main.cf-Konfiguration, um Fehler bei der Ausf├╝hrung des Kommandos zu vermeiden.
    • Cipherlists von bettercrypto.org aktualisiert
  • 01.05.2016

    • Amavis als Milter eingebunden (amavisd-milter hinzugef├╝gt)
    • Wildcard-Hinweis zu OpenDKIM erg├Ąnzt
    • Unn├Âtige oder veraltete Postfix-Einstellungen entfernt
    • Dovecot iterate_query korrigiert
  • 02.05.2016

    • -o receive_override_options=no_address_mappings entfernt. Hat dazu gef├╝hrt, dass Aliase nicht mehr funktioniert haben und war ein ├ťberbleibsel, das so nicht mehr in der Config sein sollte. Sorry!
  • 04.05.2016

    • Systemd-Service f├╝r Amavisd-Milter funktioniert nun auch nach Reboots zuverl├Ąssig.
    • In Dovecot-Config:
      • mail_max_userip_connections = 20 gesetzt
      • postmaster_address in lmtp-Bereich gesetzt
  • 05.05.2016

    • Weitere mailboxes “Trash”, “Sent” und “Drafts” zur Dovecot-Config hinzugef├╝gt
  • 09.05.2016

    • Spamassassin-Datenbank: MySQL statt BerkeleyDB f├╝r einfacheren Zugriff und bessere Performance
    • Dovecot-Antispam f├╝r Spamassassin-Training bei Verschiebevorgang
  • 14.05.2016

    • $notify_method zu Amavis-Config hinzugef├╝gt, damit Amavis Benachrichtugungsmails senden kann
  • 15.05.2016

    • certbot statt letsencrypt-auto
    • Dovecot Logging in dovecot.log entfernt, Logs werden nur noch in syslog geschrieben
    • dovecot-sql.conf, /etc/postfix/sql und /etc/mail/spamassassin/local.cf vor Zugriff durch andere Systemuser gesch├╝tzt
    • Installation von “make” zum Kompilieren von amavisd-milter hinzugef├╝gt
  • 16.05.2016

    • Amavis-Config 50-user durch chmod gesch├╝tzt
    • Git-Installation hinzugef├╝gt
  • 28.05.2016

    • Dateirechte f├╝r /etc/mail/spamassassin/local.cf korrigiert
    • Header Cleanup zu Postfix hinzugef├╝gt f├╝r besseren Datenschutz
  • 03.06.2016

    • Postfix: message_size_limit auf 50 MB gesetzt. Standard war 10 MB, ÔÇŽ ist in einigen F├Ąllen zu wenig.
    • Hinweis zu E-Mail-Verteilern ├╝ber Aliase erg├Ąnzt
  • 06.06.2016

    • Postfix: mailbox_size_limit = 0 gesetzt
  • 04.07.2016

    • OpenDKIM: Hetzner akzeptiert auch l├Ąngere DKIM-Schl├╝ssel, wenn diese in einzelne Strings unterteilt werden. Abschnitt zu den DKIM-Records wurde verbessert.
  • 10.07.2016

    • SQL-Dateien in /etc/postfix/sql ben├Âtigen keine x-Flag. Berechtigung angepasst.
  • 13.07.2016

    • Init.d-Script f├╝r Amavisd-Milter als Systemd-Alternative hinzugef├╝gt
    • Amavisd-Milter auf eigene GitHub-Seite gespiegelt. Projektseite auf Sourceforge war nicht mehr erreichbarÔÇŽ. schnell noch den Code gesichert ;-)
  • 08.08.2016

    • Vor der Kompilierung von amavisd-milter muss GCC installiert werden.
  • 22.08.2016

  • 31.08.2016

    • Hinweis auf fertige TLS-Policy-Liste als SQL Inserts erg├Ąnzt.
  • 03.10.2016

    • -m 2 Argument zu Amavisd-Milter Service hinzugef├╝gt.
  • 26.11.2016

    • dovecot-sql.conf: Connection-string in Anf├╝hrungszeichen gesetzt, um Passw├Ârter mit Sonderzeichen zu erm├Âglichen

Anleitung zuletzt vollst├Ąndig gepr├╝ft: 15.05.2016

Danksagung

Ich m├Âchte mich f├╝r alle Vorschl├Ąge, Ideen und gemeldete Fehler bedanken, die mir von meinen Lesern bisher zugetragen worden sind. Speziell Sebastian Rager bin ich dankbar f├╝r den regen Austausch und die vielen Verbesserungsvorschl├Ąge. :-)

Kommentare aus der alten Blog-Version

Nachdem ich den Blog umgestellt habe, sind die Kommentare zu diesem Beitrag nicht mehr auf dieser Seite enthalten. Es gibt jedoch eine Archiv-Version dieser Anleitung, in der die Kommentare eingesehen werden k├Ânnen: https://legacy.thomas-leister.de/sicherer-mailserver-dovecot-postfix-virtuellen-benutzern-mysql-ubuntu-server-xenial/