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.
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.
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
- Flexible 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, selbst lernendem Mechanismus 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
Verwendete Software
Diese Anleitung basiert auf Software der folgenden Versionen (Versionierung nach Ubuntu Server Paketquellen):
- Ubuntu Server 16.04 LTS
- Postfix 2.11
- Dovecot 2.2
- Amavis 2.7
- MariaDB 5.5
- Spamassassin 3.4
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 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:
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
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 wird mitgeteilt, alle E-Mails zunächst durch Amavis zu schleifen, 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. Außerdem übernimmt Amavis die DKIM-Signierung für ausgehende E-Mails.
Aufgaben: Vermittlung zwischen Postfix und Content-Filter, DKIM-Signierung.
Spamassassin
Spamassassin ist ein Content-Filter, der zusammen mit Amavis genutzt werden kann. Er erkennt und markiert Spam-Emails anhand von Filterregeln und selbst erlernten Spam-Merkmalen (=> Bayes-Filter).
Aufgaben: Erkennung und Markierung von Spammails.
Pyzor
Pyzor ist die Python-Implementierung eines Razor-Clients. Mit Razor kann die Erkennungsrate von Spamassassin verbessert werden.
Vorbereitung des Ubuntu Servers
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:
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 Crojob eingefügt:
# DH parameter re-generation @daily FILE=`mktemp` ; openssl dhparam 2048 -out $FILE && 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 2048 -out $FILE && 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!):
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 er sich nur für eingeschränkt brauchbar erwiesen hat, erwarten die meisten Mailprovider SPF-Records für andere Mailserver. Diese 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 sende-berechtigt 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 Server für mysystems.tld eine Sendeberechtigung, der im A-Record mail.msystems.tld definiert ist. E-Mails von anderen Servern, die versuchen, unter dem Namen „mysystems.tld“ zu senden, werden abgelehnt.
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:
git clone https://github.com/letsencrypt/letsencrypt cd letsencrypt ./letsencrypt-auto certonly --standalone --rsa-key-size 4096 -d mail.mysystems.tld -d imap.mysystems.tld -d smtp.mysystems.tld
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 MariaDB (eine MySQL-kompatible Datenbank) genutzt. Wer will, kann stattdessen natürlich auch einen anderen MySQL-kompatiblen Datenbankserver oder den MySQL-Datenbankserver von Oracle nutzen.
apt install mariadb-server
Nach der Installation sollte der MySQL-Server bereits gestartet worden sein. Ein „systemctl status mysql“ gibt einige Informationen zum Serverbetrieb aus. Wenn MariaDB nicht läuft, könnt ihr es via „systemctl start mysql“ starten (achtet auf “ mysql“ statt mariadb!). Ein Passwort für den DB-User „root“ muss übrigens nicht angelegt werden. Über das Unix Socket Authentication Plugin bekommt der Systemuser „root“ Passwort-freien Zugriff auf sein gleichnamiges MySQL-Benutzerkonto.
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“ an der MySQL-Kommandozeile an:
mysql
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.
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-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
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+SHA384:EECDH+aRSA+SHA256:EECDH:+CAMELLIA256:+AES256:+CAMELLIA128:+AES128:SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!ECDSA:CAMELLIA256-SHA:AES256-SHA: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 mail_max_userip_connections = 10 imap_idle_notify_interval = 29 mins } protocol lmtp { 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 } } ### ### 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. } ### ### Logging ########################### log_path = /var/log/dovecot.log
„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“ und „quota“ 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.
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 AS user, 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.
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:
rm -r /etc/postfix/sasl rm /etc/postfix/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+SHA384:EECDH+aRSA+SHA256:EECDH:+CAMELLIA256:+AES256:+CAMELLIA128:+AES128:SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!ECDSA:CAMELLIA256-SHA:AES256-SHA: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_host_lookup = dns, native smtp_tls_note_starttls_offer = yes 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 # smtp_tls_loglevel = 2 ### 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 # smtpd_tls_loglevel = 2 ## ## Lokale Mailzustellung an Dovecot ## virtual_transport = lmtp:unix:private/dovecot-lmtp ## ## 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 ## ### 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 = +
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.
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 -o content_filter=amavisfeed:[127.0.0.1]:10024 -o receive_override_options=no_address_mappings ### ### 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 broken_sasl_auth_clients=yes -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_reject_unlisted_recipient=no -o smtpd_client_restrictions=permit_mynetworks,permit_sasl_authenticated,reject -o smtpd_helo_required=no -o smtpd_helo_restrictions= -o content_filter=amavisfeed:[127.0.0.1]:10026 ### ### 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 ### ### Amavis Feed Dienst: Übergibt E-Mails an Amavis ### amavisfeed unix - - n - 2 lmtp -o lmtp_data_done_timeout=1200 -o lmtp_send_xforward_command=yes -o disable_dns_lookups=yes ### ### Der Dienst auf Port 10025 führt E-Mails nach der Verarbeitung durch Amavis wieder zu Postfix zurück ### 127.0.0.1:10025 inet n - n - - smtpd -o content_filter= -o local_recipient_maps= -o relay_recipient_maps= -o smtpd_delay_reject=no -o smtpd_restriction_classes= -o smtpd_client_restrictions= -o smtpd_helo_restrictions= -o smtpd_sender_restrictions= -o smtpd_recipient_restrictions=permit_mynetworks,reject -o smtpd_data_restrictions=reject_unauth_pipelining -o smtpd_end_of_data_restrictions= -o mynetworks=127.0.0.0/8 -o smtpd_error_sleep_time=0 -o smtpd_soft_error_limit=1001 -o smtpd_hard_error_limit=1000 -o smtpd_client_connection_count_limit=0 -o smtpd_client_connection_rate_limit=0 -o smtpd_tls_security_level=none -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks -o strict_rfc821_envelopes=yes
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.
Zwei erwähnenswerte Stellen sind noch die „content_filter=amavisfeed:[127.0.0.1]:10024″-Zeilen. Einmal im smtpd-Dienst, und ein zweites mal im Submission-Dienst (mit anderem Port). Diese Zeilen sorgen dafür, dass empfangene E-Mails (von anderen Servern (=> smtpd) oder von Mailclients (=>submission) an Amavis weitergereicht werden. Falls sie bei Amavis auf Port 10024 eintreffen, weiß Amavis, dass es sich um eintreffende E-Mails von außerhalb handelt. Spamassassin wird diese E-Mails dann auf Spam hin überprüfen und ggf. markieren. Falls Amavis E-Mails auf Port 10026 erhält, weiß es, dass es sich um eine ausgehende E-Mail von einem Mailclient handelt. In diesem Fall wird die E-Mail DKIM-signiert. In beiden Fällen findet die E-Mail nach der Verarbeitung in Amavis über den „Amavis output“ Dienst auf Port 10025 wieder zurück zu Postfix.
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'
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.
Amavis installieren und konfigurieren
Das Content Filter Framework Amavis bekommt eingehende E-Mails von Postfix zur Überprüfung übermittelt, und schickt sie nach erfolgter Überprüfung an Postfix zurück. Neben der Überprüfung auf Spam hat Amavis aber noch eine zweite Aufgabe: Das Versehen von ausgehenden E-Mails mit einer DKIM-Signatur.
Amavis installieren:
apt install amavisd-new
Amavis stoppen:
systemctl stop amavisd-new
Die Konfigurationsdatei /etc/amavis/conf.d/50-user soll folgenden Inhalt haben:
use strict; # Auf welche Sockets lauschen? # Port 10024: Eingehende Nachrichten (=> Spamfilter) # Port 10026: Ausgehende Nachrichten (=> DKIM-Signierung) $inet_socket_port = [10024,10026]; ### ### Spam checks aktivieren ### @bypass_spam_checks_maps = ( \%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re); ### ### 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; ### ### E-Mails, die auf Port 10026 eintreffen, kommen von den Mailusern auf diesem Server. ### Diese Mails speziell behandeln: DKIM-Signatur anfügen. ### $interface_policy{'10026'} = 'OUTGOING'; $policy_bank{'OUTGOING'} = { originating => 1, smtpd_discard_ehlo_keywords => ['8BITMIME'], }; ### ### DKIM-Signierung aktivieren ### $enable_dkim_signing = 1; @dkim_signature_options_bysender_maps = ( { '.' => { ttl => 21*24*3600, c => 'relaxed/simple' } } ); ### DKIM-Schlüssel dkim_key('mysystems.tld', "dkim", "/etc/amavis/mail.mysystems.tld.pem"); dkim_key('domain2.tld', "dkim", "/etc/amavis/mail.mysystems.tld.pem"); dkim_key('domain3.tld', "dkim", "/etc/amavis/mail.mysystems.tld.pem"); ### ### Spamassassin-Einstellungen ### $sa_kill_level_deflt = 9999; # E-Mails nicht einfach löschen, sondern nur markieren (default: 6.9) $sa_spam_subject_tag = undef; # Spammails kein "***Spam***" im Betreff voranstellen $spam_quarantine_to = undef; # Keine Quarantäne für Spam #------------ Do not modify anything below this line ------------- 1; # ensure a defined return
DKIM einrichten
DKIM ist ein Signaturverfahren, das helfen soll, Spam- und Phishingserver zuverlässiger zu erkennen. 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. DKIM wurde in der Konfiguration oben bereits aktiviert. Der geheime Schlüssel zur Signierung muss aber noch generiert werden:
amavisd-new genrsa /etc/amavis/mail.mysystems.tld.pem
Welche Keys eingerichtet sind, kann so überprüft werden:
amavisd-new showkeys mysystems.tld
Die Ausgabe sieht in etwa so aus:
; key#1 1024 bits, i=dkim, d=mysystems.tld, /etc/amavis/mail.mysystems.tld.pem dkim._domainkey.mysystems.tld. 3600 TXT ( "v=DKIM1; p=" "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCobe5aaqYeaUxLG3lTV3rcUP8O" "nB1KfGAOUU4/yYj/Fy0uOJNWajyGeAS9s3IEOhb5Zl8t0q4CB20ani3WfxhWQUGL" "Cd3tkmira4nD8k5HMeCzUD5XbB1pmd3xTfdD03ahAm11Ii6skHYvZxJ+HOLdDaog" "DK8nkQw9cnydCZOTJwIDAQAB")
Damit der Empfängerserver die Signatur einer eingehenden E-Mail überprüfen kann, muss der öffentliche Schlüssel in der DNS-Zone der jeweiligen Domain (hier: mysystems.tld) bekannt gemacht werden. Die Ausgabe zeigt schon einen fertigen DNS-Record. Ein fertiger DKIM-Eintrag in eurem Zonefile sollte so aussehen: („-Zeichen und Zeilenumbrüche entfernt)
dkim._domainkey.mysystems.tld. 3600 IN TXT v=DKIM1; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCobe5aaqYeaUxLG3lTV3rcUP8OnB1KfGAOUU4/yYj/Fy0uOJNWajyGeAS9s3IEOhb5Zl8t0q4CB20ani3WfxhWQUGLCd3tkmira4nD8k5HMeCzUD5XbB1pmd3xTfdD03ahAm11Ii6skHYvZxJ+HOLdDaogDK8nkQw9cnydCZOTJwIDAQAB
Wenn ihr die Änderungen im DNS durchgeführt habt, könnt ihr die Funktion mit
amavisd-new testkeys
überprüfen. Die Ausgabe sollte sein:
TESTING#1 mysystems.tld: dkim._domainkey.mysystems.tld => pass
Spamassassin installieren
Spamassassin installieren:
apt install spamassassin
Spamassassin Wartungsscript erstellen
Das Wartungsscript wird via Cronjob täglich ausgeführt und hat zwei Aufgaben
- Integration und Aktualisierung der Filterregeln von Heinlein Support
- Training des Spamfilters mit Samples aus dem Spam-Ordner jeder Mailbox und den harmlosen „Send“-Ordnern
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 sa-learn --spam --progress --username amavis --dbpath /var/lib/amavis/.spamassassin /var/vmail/mailboxes/*/*/mail/Spam/cur/* sa-learn --ham --progress --username amavis --dbpath /var/lib/amavis/.spamassassin /var/vmail/mailboxes/*/*/mail/Sent/cur/*
Script ausführbar machen:
chmod u+x sa-care.sh
Das Script wird in die Cronjobs von Amavis 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
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
… 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 ;-)
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. So könnte eine Weiterleitung realisiert werden.
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.
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 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/mail.err
bzw.
tail -f /var/log/mail.log tail -f /var/log/dovecot.log
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 ;-)
„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 in diese Dateien:
- /var/log/mail.log
- /var/log/mail.err (Error-Log)
- /var/log/dovecot.log (Dovecot-spezifisches Log)
Im Betrieb füllen sich diese Dateien z.T. stark und es fällt schwer, die Übersicht zu behalten. In diesem Fall kannst du die gewünschte Logdatei leeren:
> /var/log/mail.log
… und den Mailserver neu starten (+ ggf. die Fehler-auslösende Aktion ausführen), oder du siehst dir die Log-Datei im einer Live-Ansicht an:
tail -f /var/log/mail.log
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 setze zwar nicht jeden Tag einen neuen Mailserver auf, habe aber mittlerweile schon etwas Erfahrung gesammelt (auch bedingt durch Hilfestellung in der Vergangenheit). Vielleicht kenne ich die Ursache für dein Problem und kann dir einen Tipp geben. In dem Fall kannst du mir eine möglichst detaillierte E-Mail schreiben (Logfiles und Config bitte anhängen).
Eine Bitte habe ich aber noch: Schreibe mir bitte nur, wenn du
- Selbst versucht hast, das Problem zu lösen
- Sonst keinen Rat mehr weißt
Ich helfe gerne und freue mich, wenn ich dazu beitragen konnte, ein Problem zu lösen. Ich möchte allerdings – und ich denke das ist verständlich – nicht täglich mit der Fehleranalyse von Mailsystemen beschäftigt sein. Insofern: Verzeiht mir bitte, wenn ich auch manchmal etwas länger brauche, um zu antworten.
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 an meine Bitcoin-Adresse. 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.
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.
Eine Bitte zum Kommentarbereich
Unter meiner letzten Anleitung wurde viel zu Problemen mit dem Mailserver kommentiert, sodass die Seite extrem in die Länge gezogen wurde. Deshalb will ich mit dieser Anleitung etwas anderes ausprobieren: Wenn ihr Schwierigkeiten mit dem Mailserver habt, seht bitte zunächst weiter oben im Bereich zur Fehlerbehebung nach. Sollte euch das nicht weiterhelfen, oder solltet ihr nur eure Fehlerquellen anderen bekannt machen wollen, schreibt mir bitte an mailserver [ett] thomas-leister.de. Wir können dann vielleicht zusammen eine Lösung erarbeiten und sie im „Häufige Fehler“ Bereich hinzufügen.
Also bitte keine Support-Nachrichten in den Kommentaren, sondern lieber via E-Mail :-) Danke!