Dies ist die archivierte Version des Blogs vom 05.01.2017. Aktuelle Beiträge findest du unter thomas-leister.de
 

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.

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.

Tipp: Wer statt auf Handarbeit lieber auf eine fertige Lösung setzt, sollte sich einmal Mailcow ansehen.
Tipp 2: 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/

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 (+ 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

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 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!):

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:

  1. „Klartext“ tut uns hier nicht weh – schließlich ist die Verbindung sowieso (zwingend) verschlüsselt.
  2. 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

Den pink markierten Teil der Ausgabe kopiert ihr euch in die Zwischenablage und verwendet ihn jeweils als Wert für die nachfolgenden DNS-Records. Für alle verwendeten Domains (mysystems.tld, domain2.tld, domain3.tld) muss so ein Record 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.

Übrigens: 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

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! :-)

„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 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

  1. Selbst versucht hast, das Problem zu lösen
  2. 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 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 26.12.2016: Hier hat jemand einen Rails-Anwendung geschrieben, die die Konfiguration des Mailservers über einen Webbrowser ermöglicht: https://github.com/flowryaan/mailman Danke dafür!

„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

  • Hinweis zu TLS Policy-Liste https://github.com/csware/postfix-tls-policy/blob/master/tls_policy-dane ergänzt.

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. :-)

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 Tipps für andere User haben, 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.

Support-Nachrichten also bitte nicht in den Kommentaren, sondern lieber via E-Mail :-) Danke!

 


Post published on 21. April 2016 | Last updated on 26. Dezember 2016
Tags:                     

Diesen Blog unterstützen

Wenn Dir der Beitrag gefallen hat, freue ich mich über einen kleinen Obolus :-) Bitcoin QR Code

PayPal-Seite: https://www.paypal.me/ThomasLeister
Meine Bitcoin-Adresse: 15z8 QkNi dHsx q9WW d8nx W9XU hsdf Qe5B 4s

Siehe auch: Unterstützung

Informationen zum Autor

Thomas Leister

Geb. 1995, Kurzhaar-Metaller, Geek und Blogger. Nutzt seit Anfang 2013 ausschließlich Linux auf Desktop und Servern. Student der Automobilinformatik an der Hochschule für angewandte Wissenschaften in Landshut.

332 thoughts on “Mailserver mit Dovecot, Postfix und MySQL unter Ubuntu 16.04 LTS

  • Hallo Thomas,
    super Anleitung, werde ich mir am Wochenende auf jeden Fall einmal genauer anschauen :)
    Kann man in diesem Setup auch DMARC erfolgreich einbauen (müsste ja dann in Amavis eingebunden werden, oder)?
    Ansonsten werde ich mich dann mal in PHP einarbeiten ;)

  • Für die Leute die kein ganzes Wochenende Zeit finden ist https://github.com/andryyy/mailcow auch ganz cool.
    Macht quasi das alles alleine :)

  • Wieso wird nicht auf webmum verwiesen ?!

  • Denke ich da falsch, oder ist die Kombination von dem Spam-Sieve-Script und dem SA-Learn-Spam Script eine etwas schlechte Kombination? Sollte SpamAssassin eine Mail fälschlich als Spam einstufen, wird diese automatisch in den Spam-Ordner geschoben. Soweit, so gut – verwende ich in meinem aktuellen Setup genauso.

    Nur wenn nun das SpamAssassin-Learn-Script über alle Spam-Ordner aller Mailboxen drüberläuft und die darin befindlichen Mails sich als Spam merkt, wird doch die fälschlich erkannte Mail „noch mehr“ als Spam eingestuft und kann zu längerfristigen fälschlichen Einstufungen führen? Oder denke ich da falsch?

    • Grundsätzlich hast du recht, man hätte hier eine positive Rückkopplung … allerdings meine ich zu wissen, dass Spamassassin gelerntes auch wieder „verlernen“ kann, wenn man die entsprechende Mail zurück in einen anderen Ordner verschiebt. Allerdings müsste man diesen „anderen Ordner“ dann als „ham“ scannen… das fehlt in meiner Anleitung. Jetzt ist aber das Problem, dass man „false positive Mails“ auch nicht einfach zurück in den Posteingang schieben kann und darauf „ham“ anwenden kann… schließlich könnten ja auch Spammails durch den Filter in den Posteingang gelangen, und würden dann als „ham“ gescannt.

      Somit hätte man in beiden Fällen einen Effekt, den man nicht haben will. Schwierige Situation. Ich werde mal ein wenig weiter grübeln, vielleicht kann man das verbessern. z.B. indem man neben dem Ordner „Spam“ noch einen expliziten „learning“-Ordner einführt, in den Nachrichten manuell zum Lernen verschoben werden können. Oder so. Auf dem Spam-Ordner würde man dann nicht scannen, aber auf dem „learning“ Ordner.

      Danke jedenfalls für den Denkanstoß, du hast natürlich vollkommen recht!

      Edit: Der Gedanke, warum ich das trotzdem für mich so gelöst habe ist: Der Nutzer wird es hoffentlich innerhalb von 24h schaffen, False Positives bis zum nächsten, täglichen Scan aus dem Spam heraus zu nehmen. Das kann man freilich nicht von jedem Nutzer erwarten, insofern… Ja, kann ein Problem sein.

      LG Thomas

    • Ich habe den „Spamassassin Learning“ Teil aus der Anleitung entfernt, bis ich eine schöne Lösung dafür habe. Soll ja für den Benutzer auch nicht unnötig kompliziert werden. Zudem habe ich kürzlich gelesen, dass die Lernfunktion von Spamassassin nur stark eingeschränkt wirkt und eher gezielt gegen einzelne Spammails gerichtet werden sollte. Leider kann ich die Quelle nicht mehr finden … :-/

      Das einfachste ist vermutlich, zunächst auf die sa-learn Funktion zu verzichten. Es soll ja sogar Leute geben, die ganz ohne Spamassassin auskommen ;-)

      • Hi Thomas,

        ich kann mich auch wage daran erinnern, dass das ausschließliche Scannen von Spam-Mails eher best-practise ist.

        Hab auch mal etwas darüber nachgedacht (vielleicht sogar gängige Praxis?): Und zwar die Ordner nicht automatisiert scannen, sondern beim Verschieben einer Mail den Scan explizit auf diese Mail anwenden. Wird also eine Mail via „Spam“-Button in Roundcube oder eben einfach in den „Spam“-Ordner gezogen, dann diese Mail bei SpamAssassin als Spam anlernen. Wird jedoch eine Mail aus dem Spam-Ordner in einen anderen Ordner (nicht Trash) verschoben, könnte man da SA die Mail als „Ham“ anlernen. Dürfte glaub ich das vernünftigste sein.

        Hab mal kurz recherchiert, gibt hierfür sogar ein Dovecot Plugin „Antispam“:
        http://wiki2.dovecot.org/Plugins/Antispam

        LG,
        Patrik

  • Wow… Coole Anleitung…
    Habe zwar meinen Mailserver mit mailcow aufgesetzt, aber allein durch das Lesen der Anleitung ist manches nochmals klarer geworden!

    Vielen Dank!

  • Hi Thomas,
    erstmal Kompliment für die gut zusammengefasste Anleitung. Würde ich heute meinen ersten Mailserver aufsetzen, hätte ich schonmal einen tollen Einstieg.
    Ich hätte da spontan zwei Vorschläge zur Verbesserung:

    1) SPF-Records mit „-all“ sind gefährlich, ich würde „?all“ empfehlen (wie in meinem Kommentar zum Blogeintrag „Voraussetzungen für den E-Mail Versand zu großen Providern“ bereits ausgeführt)

    2) die Einbindung von Amavis läuft bei dir als „Post-Queue“ mit „content_filter“. Problematisch dabei ist, dass wir den Empfang erst erfolgreich quittieren und erst anschließend Amavis prüfen lassen. Bounct man mit D_BOUNCE erkannten Spam/Viren, führt das zur Backscatter-Problematik, weil der eigene Mailserver bei einer Spamwelle plötzlich Bounces ohne Ende verschickt und am Ende selbst auf RBL-Listen landet. Nimmt man trotzdem alle Mails in Empfang, taggt und verschiebt sie aber nur in Spamordner, muss der User am Ende doch wieder allen Spam durchschauen, ob nicht doch False Positives reingerutscht sind. Gerade im Unternehmensumfeld ist das kritisch (der Jurist nennt es eine „Unterdrückung anvertrauter Nachrichten“ – das kann strafrechtlich relevant sein). Discarden können wir wegen des gleichen Problems auch nicht, also bleibt die letzte Möglichkeit: der Reject. Allerdings geht das eben nur bei Echtzeitfilterung des Contents („Pre-Queue“), was man mit der Einbindung von Amavis via „smtpd_proxy_filter“ realisieren kann. Damit verweigert Postfix die Annahme gegenüber dem einliefernden Client und dieser hat das Bounce-Problem, nicht wir.
    Kurzum: ich persönlich würde „smtpd_proxy_filter“ dem „content_filter“ vorziehen (außer bei lokal erzeugten Mails (Shell, Webserver…), da greift nur „content_filter“).

    Sollte sich jemand übrigens tiefer in Postfix einlesen wollen, kann ich an dieser Stelle nur empfehlen, sich das Postfix-Buch von Peer Heinlein mal näher anzuschauen.

    Gruß Martin

    • Hi Martin,

      habe die SPF-Records hier auch angepasst. Das habe ich nach der Korrektur im anderen Beitrag vergessen.

      Die Anbindung von Amavis über smtpd_proxy_filter ist klasse! Nach so einer Möglichkeit (Reject statt Quarantäne etc.) habe ich schon gesucht. Ich habe das mal eben auf meinem Testserver ausprobiert: Funktioniert wunderbar. Wenn ich heute noch dazu Zeit habe, wird der Beitrag aktualisiert.

      Danke für dein hilfreiches Feedback! :-)

      LG Thomas

  • Erstmal danke für die Anleitung – eventuell habe ich etwas übersehen, aber bei mir meckert dovecot folgendes:

    Apr 25 16:31:27 lmtp(14062): Fatal: Error reading configuration: Invalid settings: postmaster_address setting not given

    Das Ergebnis war, dass keine Mails in mein Postfach zugestellt wurden.

    Falls jemand das gleiche Problem hat, fügt man einfach am Ende der dovecot.conf noch folgendes hinzu:
    postmaster_address postmaster@domain.tld

    (domain.tld entsprechend austauschen).

    LG Marcel

  • Hi Thomas,

    zuerst einmal natürlich danke für die Anleitung. Sehr interessant zu lesen und auch gut geschrieben, so dass es für viele eine große Hilfe sein wird. Einen Grundgedanken, der mich momentan nur immer wieder umtreibt (ich stehe auch gerade davor, mein komplettes Mailsetup neu aufzusetzen), warum immer wieder auf ein DB-Backend verwiesen/gesetzt wird. Du schreibst ja selbst:
    „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.“
    Gerade Dovecot benötigt über das eigene Passwd-file keine realen Linux-User auf dem System und liest auch ständig dieses File neu ein, so dass Änderungen im laufenden Betrieb direkt erkannt werden. Ich verstehe voll und ganz, wenn in großen Mail-Umgebungen mit Usern im hohem zweistelligen oder dreistelligen Bereich ein DB-Backend das ganze etwas vereinfacht, aber gerade in kleinen Umgebungen, finde ich diese Möglichkeit der Userverwaltung doch weitaus einfacher. Oder habe ich irgendwo einen Denkfehler bzw. etwas übersehen?

    Grüße
    Sven

    • Für mich ist ein ganz wesentlicher Vorteil, dass ich z.B. über eine selbst geschriebene Weboberfläche in PHP sehr schnell und einfach den Server verwalten kann. Ich muss dazu nicht erst via SSH einloggen und Configs editieren. Über eine Weboberfläche, die nur eine SQL-Datenbank bedient, könnten z.B. auch andere Nutzer ihr Passwort einfach ändern.

      Natürlich kann man in kleineren Umgebungen auch ohne SQL Arbeiten und die Daten in Configs hinterlegen… allerdings eignet sich das nicht besonders, wenn z.B. auch Freunde oder Familie ihre Daten ändern wollen. Mit SQL ist man da einfach flexibler.

      LG Thomas

      • Ehrlich gesagt, genau an das Thema Passwortänderung habe ich nicht gedacht. Und genau dafür gibt es anscheinend auch keine Lösung, solange ich nicht a) eine Datenbank verwende, b) vom User das gehashte Password bekomme und dort eintrage oder c) das Password im Klartext vom User bekomme und eintrage. :-( Sehr schade eigentlich, hätte gut und gern auf eine DB an dieser Stelle verzichtet. Danke.

        Grüße
        Sven

  • Ein kleiner Hinweis, was vielleicht auch in die „Hilfe, es tut nicht“ kann …

    Beim ersten Start generiert Dovecot, genauso wie wir es von Hand für Postfix gemacht haben, den Diffie-Hellman-Schlüssel.
    Wer ganz paranoid ist, wie ich, ändert natürlich die Konfiguration von 2048 Bit auf 4096 Bit. Dadurch, das beim ersten Start von Dovecot der Schlüssel generiert wird und dies bei meinem vServer schon mal ein bisschen dauern kann, kam es zu folgendem Problem:

    – Login via IMAP war nicht möglich
    – Dovecot.log sagt: „master: Error: service(lmtp): Initial status notification not received in 30 seconds, killing the process“

    Tipp dagegen: Eine Tasse Kaffee hohlen, das Auto waschen gehen und noch einmal versuchen ;)

  • Hallo,

    vielen Dank für den Beitrag! Ich hätte allerdings noch eine Frage … ist es mit dieser Datenbankkonfiguration möglich Wildcard- oder Regexaliase einzurichten?

    Viele Grüße
    Daniel

    • Hi Daniel,

      Wildcards sind möglich. Bei Regulären Ausdrücken bin ich mir nicht sicher, aber ich vermute, dass diese nicht unterstützt werden.

      LG Thomas

      • Hallo,

        danke für die schnelle Antwort! D.h. ich muss dann nur z.B. test-* als username in der Datenbank angeben?

        Viele Grüße
        Daniel

        • Sorry, jetzt habe ich mich ein wenig verrannt. Wildcards sind nicht möglich, allerdings funktionieren Catch-All-Aliase z.B. von @mail.com auf @mail.de. Dazu wird einfach das Feld für den Benutzernamen leer gelassen. Wenn du richtige Wildcards oder reguläre Ausdrücke einsetzen willst, musst du zu virtual_alias_maps mit regex:/ greifen: http://pisadmin.welaika.com/post/38301383548/postfix-virtual-domain-alias-the-regex-way – allerdings kann ich dir an dieser Stelle spontan nicht weiterhelfen. Habe mich noch nicht damit befasst.

          • Hi Thomas,
            Catch-All so wie du es beschreibst (Username leer, kann ja kein NULL) klappt nicht (User unknown in virtual mailbox). Mit einem Namen klappt der Alias, allerdings eben kein Catch-All was für mich sehr wichtig ist :(

            • Habe es „pfuschig“ gelöst, funktioniert aber bisher in meinem Falle…

              query = select concat(destination_username, ‚@‘, destination_domain) as destinations from aliases where source_username = ‚%u‘ and source_domain = ‚%d‘ and enabled = true union select concat(destination_username, ‚@‘, destination_domain) as destinations from aliases where source_username = “ and source_domain = ‚%d‘ and enabled = true;

            • poeserdaddler

              Dank an Thomas für diese gute Anleitung, ich habe mich auch gerade damit beschäftigt eine catchall Adresse einzurichten, komme aber trotz Jochen’s Query nicht weiter:
              Mein Alias:
              INSERT INTO aliases (source_username, source_domain, destination_username, destination_domain, enabled) values (“, ‚example.de‘, ‚catchall‘, ‚example.de‘, true);
              Mein Alias Query (Jochen’s + Typofix):
              query = SELECT CONCAT(destination_username, ‚@‘, destination_domain) AS destinations FROM aliases WHERE source_username = ‚%u‘ AND source_domain = ‚%d‘ AND enabled = true UNION SELECT CONCAT(destination_username, ‚@‘, destination_domain) AS destinations FROM aliases WHERE source_username = ‚%u‘ AND source_domain = ‚%d‘ AND enabled = true;

              Leider bekomme ich immer noch die Meldung: „Recipient address rejected: User unknown in virtual mailbox table;“
              (newaliases && service postfix restart wurden vor dem überprüfen ausgeführt).

              Wäre super wenn mir jemand einen Tipp geben kann, Ziel ist es das:
              @example.de => catchall@example.de
              gibtesnicht1@example.de => catchall@example.de
              gibtesnicht2@example.de => catchall@example.de
              ….

            • poeserdaddler

              Der Query von Jochen klappt, ich habe nur Zwei Hochkommata als Anführungszeichen gelesen und für einen Fehler gehalten. Hier ein snippet um Leuten zu helfen denen es evtl. so wir mir ergeht:
              http://pastebin.com/5FB89Qk6

              Ich habe das snippet als unlisted ge-posted, vielen dank nochmal an Thomas für die gute Anleitung und an Jochen für den Query!

            • Hallo zusammen,

              Jochens Lösung ist nicht ganz korrekt. Folgende Ausgangslage:

              @domain1.de => info@domain2.de
              test@domain1.de => info@domain3.de

              Die Lösung von Jochen würde nun eine Mail an beide Weiterleitungsempfänger raushauen. ;)
              Besser finde ich daher meine Lösung, da diese das Problem klar trennt:

              SELECT IFNULL((SELECT CONCAT(destination_username, ‚@‘, destination_domain) AS destinations FROM aliases WHERE source_username = ‚%u‘ AND source_domain = ‚%d‘ AND enabled = true), (SELECT CONCAT(destination_username, ‚@‘, destination_domain) AS destinations FROM aliases WHERE source_username = “ AND source_domain = ‚%d‘ AND enabled = true));

              Viele Grüße,
              Matthias

            • Die Lösung von Matthias hat aufgrund falscher Anführungszeichen nicht funktioniert, deswegen hier die query, welche bei mir funktioniert (nicht existierende Adressen an catchall@example.com):

              /etc/postfix/sql/aliases.cf

              query = SELECT IFNULL((SELECT CONCAT(destination_username, ‚@‘, destination_domain) AS destinations FROM aliases WHERE source_username = ‚%u‘ AND source_domain = ‚%d‘ AND enabled = true), (SELECT CONCAT(destination_username, ‚@‘, destination_domain) AS destinations FROM aliases WHERE source_username = “ AND source_domain = ‚%d‘ AND enabled = true));

            • Also hier ist einiges nicht i.O. mit den geposteten quierries.
              Anstelle eines UNION könnte man einfach (source_username = ‚%u‘ OR source_username = “) einsetzen.
              Bei der Version mit ISNULL fliegt einem die query um die Ohren wenn man an mehr als einen weiterleiten möchte.
              Im allgemeinen funktioniert es aber auch nicht immer die catchall auszugeben wie das bei dem UNION gemacht wird.
              Bei der Variante mit dem ISNULL wiederum bekommt eine mailbox in der accounts tabelle die nachricht nicht mehr.
              Sofern man in der postfix config nichts weiter tweaken kann müsste man eine stored procedure nehmen die das alles überprüft.

            • Der Query funktioniert zwar, schickt aber ALLE Mails an die Catchall zusätzlich zum eigentlichen Adressaten. Das will ich natürlich nicht, sondern nur die Mails abfangen die keinen Empfänger haben. Darum habe ich zum Query noch ein NOT EXISTS für „echte“, non-catch-all-User hinzugefügt. Sieht dann so aus und funktioniert bei mir:

              https://nopaste.me/view/38022f8e

              Hab’s nur ausführlich getestet aber es ist noch nicht live, Feedback darum sehr gerne willkommen.

          • Das mit den Catch-All Adressen muss ja irgendwie gehen, geht bei MailCow auch.
            Nur wie ist jetzt die Frage…

            • warum postfix nicht nach Mail alias mit leerem User schaut, keine Ahnung. Postfix unterstützt de facto aber keine stored procedures (siehe Diskussion in der mail list https://groups.google.com/forum/#!topic/mailing.postfix.users/MyFoVUWr9rY) die helfen könnten und auch keine multi statements.
              Deswegen habe ich jetzt eine query gebaut (ein statement) die dafür sorgt das der catchall nur greift wenn weder eine alias noch eine Mailbox für die Zieladresse vorhanden ist und auch mit der alias Tabelle Weiterleitungen möglich sind (gleichzeitige Zustellung an Mailbox). Die ist aber so hässlich und skaliert nicht linear das ich die niemandem zumuten möchte der nicht selbst in der Lage ist so was zu bauen.
              Nur soviel als Tipp; Man muss die normale mit OR so erweitern das man falls keine direkte alias gefunden wurde (Count(*) = 0) auch die aliase mit username = “ einen match ergeben.
              Um dann noch Kopien weiterleiten zu können obwohl Mailboxen vorhanden sind muss noch ein UNION mit einem SELECT über die accounts Tabelle gemacht werden die im Prinzip für jeden account nochmal eine alias erzeugt; mailbox@d.tld -> mailbox@d.tld

            • Hallo Zusammen,

              ich habe vorgestern in einer Nacht und Nebelaktion unser komplettes Live Mailsystem neu machen müssen da das Filesystem wohl schon seit einem Monat defekt war aber das System nichts davon mitbekommen hat. Dadurch war auch das Backup im gleichen zustand.

              Ich habe mich für die Anleitung von Thomas entschieden und muss sagen echt super, er hat mir am nächsten morgen sogar noch kurz geholfen da ich zu übermüdet war die Tips zu lesen. ;)

              Vielen Dank nochmal hierfür!

              Ich habe was mir noch gefehlt hat mailtransports rein genommen, da das die meisten unserer Kunden haben zu ihrem Exchange.
              Und das mit dem Catchall habe ich nun ander gelößt.

              Ich habe die Tabelle anders aufgebaut:

              CREATE TABLE mailalias (
              address varchar(255) NOT NULL default “,
              goto text NOT NULL,
              domain varchar(255) NOT NULL default “,
              created datetime NOT NULL default ‚0000-00-00 00:00:00‘,
              modified datetime NOT NULL default ‚0000-00-00 00:00:00‘,
              active tinyint(1) NOT NULL default ‚1‘,
              PRIMARY KEY (address),
              KEY address (address)
              )

              dazu der virtual_alias.cf angepasst:

              user = vmail
              password = vmailpass
              hosts = 127.0.0.1
              dbname = vmail
              table = mailaliases
              select_field = goto
              where_field = address
              additional_conditions = and active = ‚1‘

              Dadurch habe ich folgende Vorteile:
              anlegen von Domain weiterleitungen @example.de => @example.net
              anlegen von mehreren Empfängern in einer Spalte durch Komma getrennt.

              LG Carsten

    • Ich habe dazu die Datei /etc/postfix/sql/aliases.cf so geändert:user = vmail
      password = vmaildbpass
      hosts = 127.0.0.1
      dbname = vmail
      query = select concat(a1.destination_username, ‚@‘, a1.destination_domain) as destinations from aliases a1 where a1.source_username=’%u‘ and a1.source_domain=’%d‘ and a1.enabled=1 union (select concat(a2.destination_username, ‚@‘, a2.destination_domain) as destinations from aliases a2 where (a2.source_username=“ or a2.source_username is null) and a2.source_domain=’%d‘ and a2.enabled=1 and (select count(a3.source_username) from aliases a3 where a3.source_username=’%u‘ and a3.source_domain=’%d‘ and a3.enabled=1)=0 and (select count(a4.username) from accounts a4 where a4.username=’%u‘ and a4.domain=’%d‘ and a4.enabled=1)=0)

      Dieses SQL-Stmt nimmt einen leeren oder null Eintrag in der Spalte source_username als catch-all Adresse. Aber nur dann wenn kein Alias und keine passende Mailbox vorhanden ist. Bei den anderen Lösungen hier ging entweder das dann immer auf die catch all Adresse oder die normalen Mailboxen funktionierten nicht mehr.

  • Hi und Danke für diese großartige Anleitung.

    Ein einziges Problem habe ich mit amavisd und amavisd-milter.
    Nach einem Reboot des Server, startet amavisd-milter nicht automatisch, soll das so sein? Enabled ist er.
    Dann sehe ich in den Logs sowas: warning: connect to Milter service unix:/var/run/amavis/amavisd-milter.sock: No such file or directory
    Nun kann ich aber erstmal Mails versenden und auch empfangen.
    Wenn ich dann amavisd-milter starte, geht kein Empfang/Versand mehr und es gibt eine Fehlermeldung: amavisd-milter[972]: ipb21850af.dynamic.kabel-deutschland.de: could not connect to amavisd socket /var/run/amavis/amavisd.sock: No such file or directory
    Habe alles mehrmals geprüft und auch Google bemüht, leider nix.

    Grüße,
    Tony

    • Oh je, du bist leider nicht der einzige mit dem Problem :-/ Im Moment kann ich den Fehler nicht nachvollziehen. Auf meinem Testsystem hat das gut funktioniert… Ich werde heute oder morgen nochmal einen Blick darauf werfen. Sorry, da ist offenbar noch etwas nicht korrekt in der Anleitung :S

      Edit: Es liegt wohl daran, dass amavisd-milter vor Amavisd startet. Leider kenne ich mich mit systemd -initfiles nicht besonders gut aus. Ich werde mal nachsehen, wie sich ein Warten auf Amavisd einbauen lässt. Bis dahin sollte nach einem Reboot ein systemctl restart amavisd-milter helfen.

      LG Thomas

      • Das hatte ich schon versucht aber sobald milter läuft, geht garnix mehr. „Content Filter Malfunction“ da er die amavisd.sock nicht findet.

        • Starte mal deinen Server neu und starte nicht den milter, sondern warte einige Sekunden und tippe diese Befehle (mit etwas Zwit zwischendurch) hintereinander ein:
          ———-
          /bin/su — amavis -c „/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“

          /bin/chown postfix:postfix /var/run/amavis/amavisd-milter.sock

          /bin/chmod 0660 /var/run/amavis/amavisd-milter.sock
          ———-

          Das klappt aktuell bei mir ganz gut, dann läuft der Milter, gehört postfix und es gibt keine Fehler im Log.

          • Kannst du die Befehle noch mal überprüfen? Ich bekomme immer ‚illegal option -B“ -c etc…

            Grüße,
            Tony

          • Bekomme leider wieder: amavisd-milter[932]: could not connect to amavisd socket /var/run/amavis/amavisd.sock: No such file or directory. Der Socket wird halt nicht gestartet von amavisd. es gibt nur einen amavisd-milter socket.

            PS: kann ich denn hier keine Beiträge editieren?

            • Editieren habe ich hier leider auch schon vergebens gesucht.

              Hast Du denn auch die Konfigurationsdatei „50-user“ angelegt? Bei dir scheint der generelle Socket von amavis nicht vorhanden zu sein und nicht der amavis-milter-Socket. Starte mal via „systemctl start amavisd-milter“ und führe den Befehl „ls -lah /var/run/amavis“ aus, sind dort die jeweiligen Dateien da? Wenn ja, wem gehören Sie?

    • Das Problem mit dem nicht startenden Milter-Service ist behoben. Ich habe den Teil rund um die Servicedefinition aktualisiert.

  • Ich denke es liegt daran, dass amavisd-new ja sowieso keinen Socket erstellt oder?

  • @Sascha, das hatte ich schon gecheckt. Eine amavisd.sock war noch nie vorhanden.
    Nach VOR und NACH Start vom Milter: ls -lah
    root@mail:~# ls -lah /var/run/amavis/
    total 4.0K
    drwxr-xr-x 2 amavis amavis 80 May 4 08:55 .
    drwxr-xr-x 23 root root 660 May 4 11:27 ..
    -rw-r—– 1 amavis amavis 0 May 4 08:55 amavisd.lock
    -rw-r—– 1 amavis amavis 4 May 4 08:55 amavisd.pid

    root@mail:~# ls -lah /var/run/amavis/
    total 8.0K
    drwxr-xr-x 2 amavis amavis 120 May 4 11:28 .
    drwxr-xr-x 23 root root 660 May 4 11:27 ..
    -rw-r–r– 1 amavis amavis 5 May 4 11:28 amavisd-milter.pid
    srw-rw—- 1 postfix postfix 0 May 4 11:28 amavisd-milter.sock
    -rw-r—– 1 amavis amavis 0 May 4 08:55 amavisd.lock
    -rw-r—– 1 amavis amavis 4 May 4 08:55 amavisd.pid

    50-user ist angelegt, ja

    • Sehr merkwürdig, wo doch in der 50-user explizit konfiguriert ist, dass ein Socket „amavisd.sock“ unter /var/run/amavis/ angelegt werden soll. Dafür habe ich gerade leider auch keine Erklärung. Was das defekte Systemd-Skript angeht, habe ich die Anleitung aktualisiert.

      • Hallo,
        Erstmal. Top Anleitung !!
        Das Problem mit dem nicht startenden Amavi-milter nach einem reboot habe ich auch. Ein manueller Neustart von amavis-new und amavis-milter half nicht. Erst als ich vor dem Neustart der beiden Dienste den Postfix stoppte, konnte ich diese Dienste fehlerfrei, und danach Postfix, starten.
        Gruß
        Dominik

        • Hallo Dominik,

          eigentlich sollten die Probleme mit dem Amavisd-Milter-Service mit der Aktualisierung vom 04.05. behoben sein. Vor 4 Tagen habe ich meinen Testserver noch einmal komplett nach dieser Anleitung aufgesetzt und habe nach einem Reboot keinerlei Probleme. Der Amavisd-Milter-Service startet bei mir korrekt – ich kann das Problem nicht nachvollziehen. :-/

          LG Thomas

  • Steven Luscher

    The first time I sent a number of emails to the spam folder to be analyzed by `sa-learn` it ate up all the memory on my sever and crashed MySQL.

    Here’s a modification to `spampipe.sh` that makes all calls to `sa-learn` run in series.

    https://gist.github.com/steveluscher/3916c4f2530a4de8ed391bf967839b2b

  • Steven Luscher

    If you don’t want email deleted from the Spam/Junk folder to get un-learned, you must add the following to the antispam config in `dovecot.conf`:

    antispam_trash = Trash

  • Mein Gott, endlich mal eine wirklich perfekt geschriebene Anleitung für ein Thema, von dem ich nur Tuten und Blasen verstehe. Ich betreibe selber jetzt seit einigen Jahren diverse Linux-Server und bin auch für deren Sicherheit zuständig. Aber das einzige wichtige Thema, mit dem ich mich nie auseinander setzen musste, war ein Mailserver….zumindest bis vor ein paar Stunden. :D Es gibt so dermaßen viele Anleitungen im Netz, die einfach blind von 14.04 oder 15.10 kopiert sind und Null auf die Änderungen, besonders durch systemd, eingehen. Aber das hier ist endlich mal richtig recherchiert und geprüft!

  • Hallo Thomas, super Anleitung. Hat wirklich alles super funktioniert.
    Habe nur 1 Frage zum Erneuern der letsencrypt Zertifikate.
    Gebe ich den Befehl

    /root/letsencrypt/letsencrypt-auto renew –dry-run

    ein, werden alle Zertifikate erfolgreich simuliert, bis auf das mail.domain.de
    Hier kommt der Hinweis, das der apache2 den Port 80 bereits in Benutzung hat.

    Hast Du hier einen Tipp für mich? Der Apache hat ja mit mail.domain.de nix zu tun.

    Besten Dank
    Frank

    • Anscheinend läuft auf der Maschine, auf der du den LE-Client ausführst, ein Apache. Anders kann ich mir das nicht erklären. Unter welchen Domains der Apache läuft, spielt keine Rolle. Es darf auf derselben Maschine keiner laufen, weil dieser sonst Port 80 belegt und der LE-Client nicht an ihn binden kann.

      LG Thomas

      • Vielen Dank für die tolle Anleitung. Habe ein ähnliches Problem mit cerbot-auto und apache. Funktioniert ein Mailserver generell nicht mit Apache auf der selben Maschine oder nur während dem laufen lassen von certbot-auto für den Apapache?

  • Hallo,

    ich habe gerade Probleme mit den Sender Login Maps … an sich funktioniert alles (fast) so wie es soll, so lange man sich in Horde / Thunderbird / … Identitäten anlegt. Dann schickt Postfix nur die Mails, die es auch schicken soll. Wenn ich aber in Thunderbird die Option „customize mail address“ benutze, kann ich von beliebigen Mailadressen schicken (und die Mailadresse steht dann auch im From Header). Und die Mailadresse taucht auch nicht im Debuglog von Postfix auf (was sie tut, wenn ich mir statt dessen eine Identität anlege).
    Was könnte da der Unterschied sein, bzw. wie kann man das beheben?

    Viele Grüße
    Daniel

  • Das werde ich nächstes WE mal in die Tat umsetzen. Das einzige Problem… Ich nutze CentOS ^^ Wird schon schiefgehen :)

  • Hallo Thomas,
    vielen Dank für diesen super Artikel. Nachdem ich dann meine Fehler bei der Eingabe beseitigt habe, hat alles Funktioniert.

    Das ist das beste Tutorial im Netz zum Thema Mailserver. Und sogar mit der aktuellsten Ubuntu Version geschrieben.

    Nun habe ich doch noch eine Frage:
    Ich habe mir auf dein empfehlen einen Server bei active-servers.com gemietet inkl. einer de-Domain. Wenn ich es richtig sehe, erfolgt die Behandlung der DNS-Zone-Einträge auf dem Ubuntu-Server, da es bei active-server keine direkte Verwaltung der Domain gibt. Ich habe dafür die Software bind verwendet. Ist das so okay? Vielleicht findest du kurz Zeit ein paar Worte dazu zu verlieren.

    Vielen Dank schonmal!

    • Hi Michael,

      in meiner Zeit bei active-servers.com habe ich dort keine Domains bestellt, deshalb weiß ich nicht, wie AS die Domain-Sache realisiert. Fest steht, dass du auf irgendeine Art und weise die Zonefiles deiner Domains bearbeiten musst. Der AS Support kann dir dabei sicherlich behilflich sein :-) Welchen Nameserver du einsetzt, ist egal.

      LG Thomas

  • Hallo Thomas, erst einmal vielen Dank für die tolle Anleitung. Bin auch sehr zufrieden wie alles läuft, habe jedoch zwei Fragen. Zum einen habe ich die folgende Fehlermeldung über sieve die ich unter Port 4190 nachschauen kann.

    „IMPLEMENTATION“ „Dovecot Pigeonhole“
    „SIEVE“ „fileinto reject envelope encoded-character vacation subaddress comparator-i;ascii-numeric relational regex imap4flags copy include variables body enotify environment mailbox date index ihave duplicate mime foreverypart extracttext“
    „NOTIFY“ „mailto“
    „SASL“ „“
    „STARTTLS“
    „VERSION“ „1.0“
    OK „Dovecot ready.“
    NO „Error in MANAGESIEVE command received by server.“
    NO „Error in MANAGESIEVE command received by server.“
    BYE „Too many invalid MANAGESIEVE commands.“

    Leider kann ich nichts passendes zur Fehlerbehebung finden. Evtl. hast du ja eine Idee. Zum anderen würde ich auch gerne pop verwenden, da ich die Mails auch gern unabhängig vom Server auf meinem lokeale Rechner speichern würde. Gibt es hierfür eine einfache Möglichkeit das einzubinden? Bin auf diesem Gebiet noch Anfänger und denke das es sehr sehr schwierig ist da was auf die schnelle hinzubekommen. Nochmalmal herzlichen Dank für die sehr gut gemachte Anleitung.

    Gruß
    Christoph

    • Hi Christoph,

      welchen Sieve-Client verwendest du? Für mich sieht es danach aus, als seien Sieve-Server und Client nicht vollständig zueinander kompatibel.
      Dovecot ist zwar eigentlich nicht als POP-Server konzipiert, allerdings kann man das so nachrüsten:

      ###
      ### Aktivierte Protokolle
      #############################
      protocols = imap lmtp sieve pop3

      + Paket „dovecot-pop3d“ muss nachinstalliert werden.

      (Nicht getestet!)

      LG Thomas

      • Hallo Thomas, danke für die Info. Bei dem Problem mit sieve have ich es gemäß deiner Anleitung herunter geladen. Somit habe ich doch garkeine Möglichkeit eine andere oder falsche Version zu benutzen oder?

  • Ein wirklich gutes Tutorial. Ich habe nur eine Frage: Und zwar verwende ich Ubuntu Server 14.04 LTS. Dort ist systemctl nicht verfügbar. Welche Entsprechung kann ich hier verwenden. Ich konnte auch mit längerem Googlen nichts praktikables finden.

    Vielen Dank,
    David.

    • Hi David,

      systemd (=>systemctl) ersetzt das alte Init-System aus Ubuntu 14.04. Statt des systemd-Scripts in der Anleitung müsstest du dir dann ein eigenes Script schreiben, welches amavisd-milter startet, z.B. via Upstart: https://wiki.ubuntuusers.de/Upstart/

      Die systemctl -Befehle ersetzt du einfach durch „service“-Befehle. Ein „systemctl start postfix“ wäre bei Dir dann ein „service postfix start“ (achte auf die veränderte Reihenfolge!).

      LG Thomas

      • Vielen Dank für deine Hilfe.
        Leider bin ich noch nicht so erfahren mit Linux. So habe ich leider keine wirkliche Vorstellung davon, was du meinst.
        Den Artikel habe ich gelesen. Er konnte mir jedoch auch nicht wirklich weiterhelfen.

      • Also ich habe das Problem jetzt gelöst, indem ich Amavisd-milter aus den offiziellen Paketquellen installiert habe. Zwei Tipps noch, die vielleicht auch zu den häufigen oder zumindest den dummen Fehlern gehören: Der Erste tritt bei Dovecot in der Datenbankverbindung auf, wenn das Passwort ein ‚#‘ beinhaltet, da dieses anscheinend den Rest des Passworts auskommentiert. Von dem Anderen sind alle Speedport-Benutzer betroffen. Die Telekom-Router führen intern eine Liste der „sicheren Mailserver“ und blockieren den Mail-Versand an unbekannte. Das hat mir eine Menge unnötiger Fehlersuche eingebracht.

        Ansonsten vielen, vielen Dank für deine Anleitung. Sie hat mir stark geholfen.

  • Hallo Thomas,
    habe einen neuen Server nach deiner Anleitung aufgesetzt und alles hat problemlos geklappt. Kann ich trotzdem ClamAV anhand deiner alten Anleitung (https://legacy.thomas-leister.de/linux/mailserver-clamav-antivirensoftware-mit-amavis/) einbinden? Amavis wird ja laut Anleitung nicht als Contentfilter verwendet sondern MilteR?

  • Einfach perfekt!

    Wie schon bei der Anleitung für 14.04 LTS hat mein Mailserver gleich beim ersten Mal funktioniert.
    Von wegen „Ein Wochenend-Projekt“. Ich war in 1,5 Stunden fertig.

    Liebe Grüße

  • Hi,

    eine super Anleitung die du hier bereitgestellt hast. Die Installation funktionierte ohne Probleme. Hast du Erfahrungen mit der Integration von SOGo v3 als Groupware-Lösung in ein solches Mailserver Konstrukt? Würde mich sehr interessieren wenn mir jemand dazu Tipps geben kann, wie ich die beiden Dinge verheirate.

    Viele Grüße

  • Hallo Thomas,

    Das system schickt anscheinend eine Mail von root@ zu amavis@ mit folgendem Inhalt:

    Betreff: Cron test -e /usr/sbin/amavisd-new-cronjob && /usr/sbin/amavisd-new-cronjob sa-sync

    config: cannot open „/etc/spamassassin/local.cf“: Permission denied
    config: cannot open „/etc/spamassassin/local.cf“: Permission denied

    Oben genannten amavis-new Cronjob in cron.d Directory ist doch nicht mehr relevant, oder?

    LG
    Erik

    • Hi Erik!

      Danke für deinen Hinweis! Der Cronjob war mir bisher nicht aufgefallen und ist in diesem Fall (in Kombination mit der MySQL-Datenbank) überflüssig. Die E-Mail hast du vermutlich bekommen, weil der Cronjob wegen des Berechtigungsfehlers bei „local.cf“ Output generiert hat. Ich habe die Berechtigungen von local.cf in der Anleitung korrigiert. Da war noch etwas fehlerhaft. Den Cronjob kannst du einfach aktiv lassen … er sollte nach der Berechtigungskorrektur keinen Output mehr generieren. Einen Nutzen hat er allerdings auch nicht, soweit ich das beurteilen kann.

      LG Thomas

  • Hallo Thomas,

    Ich bin dazu auch auf die suche nach:
    Wie kann ich die System Mails root@, amavis@ usw. an mein Account weiterleiten?
    Alias Eintragung funktioniert nicht weil die Accounts nicht existieren in der Datenbank.

    Google hat mir dann gezeigt das ich /etc/aliases anpassen sollte, was ich auch gemacht habe, aber vermutlich wird der File aliases.db nicht benutzt weil umgestellt worden ist auf MySQL… Ist das richtig?

    Wie könnte ich o.g Frage evtl. lösen?

    LG
    Erik

    • Dazu erstellst du einfach in der MySQL Datenbank einen Alias von Root zu deinem Postfach … Und einen zweiten von amavis zu deinem Postfach (wie oben erklärt)

      LG Thomas

      • Hallo Thomas,

        Die Aliases in MySQL dienen nur für eingehende Mails die von Extern kommen, system mails werden anscheinend doch mittels Aliases gesteuert. Habe zur Testfall die Aliases in MySQL ausgeschaltet mittels : enabled = 0.
        Und damit änderte sich nichts.

        Mann muss wirklich die /etc/aliases Datei anpassen mit Aliases für root@, amavis@ und postmaster@.
        und dan mit newaliases an der CLI der aliases.db updaten.

        Habe also folgendes eingetragen:
        # See man 5 aliases for format
        postmaster: root
        root: localuser
        amavis: localuser
        localuser: user@domain.tld

        Trägt mann nur user ein (sowie da root steht) werden mails weitergeleitet an user@mail.domain.tld und dann sagt Postfix natürlich: User unkown, und Bounced die Email, weil es keinen user gibt mit user@mail.domain.tld.

        Daher muss die vollständige Email Adresse eingegeben werden.

        Hoffe das hilft ein wenig weiter, hier funktioniert es endlich.

        Zusätzlich habe ich das Paket pop3 installiert, und habe die Account Tabelle angepasst damit mann für jedes Account einstellen kann ob mittels Imap oder Pop3 oder beides angemeldet werden kann. Funktioniert jedenfalls.

        Wäre noch schön wenn mann für jede Domain in MySQL einstellen könnte ob Quota pro User oder pro Domain gezählt werden muss.

        LG
        Erik

        • Hi Erik,

          deine Schwierigkeiten mit MySQL-Aliasen kann ich nicht nachvollziehen. Ich habe das auf meinem Testsystem (nach dieser Anleitung aufgesetzt) gerade ausprobiert. Aliase gelten genauso auch für Mails, die vom Server selbst kommen (via Mailclient oder lokale Kommandozeile). Auch der „enabled“ Schalter funktioniert einwandfrei.

          LG Thomas

  • Erstmal: Danke für diese tolle Anleitung!
    Dann: kann es sein, dass die Alias Tabelle case sensitive ist? Beispiel: ich habe einen User1 als Account und eine weiterleitung an user1 dann finden sich unter /var/vmail/mailboxes sowohl ein Ordner user1 als auch User1 ..

    MfG
    Sebastian

  • Erst mal danke für die super Anleitung! Es gibt glaube ich momentan nichts besseres im Internet zur Zeit :D

    Noch eine Frage: wie richte ich Mailing-Listen ein? Normalerweise lege ich dafür Einträge in der Datei „/etc/aliases“ an. Funktioniert das bei deiner Konfiguration noch? Falls nicht, lässt es sich ohne große Mühen „nachrüsten“?

    Wäre echt perfekt wenn das auch noch gehen würde, dann wäre es das perfekte Mail-Setup für mich! :)

    Auf jeden Fall mal ein fettes Danke!

    LG Jan

    • Hi Jan,

      das ist auch mit diesem Setup kein Problem. In der MySQL-Datenbank hast du in der „aliases“ Tabelle eine Datenstruktur, mit der du einer Quelladresse genau eine Zieladresse zuordnen kannst. Wenn du mehrere Zieladressen nutzen willst (=> Verteiler / Liste), machst du einfach mehrere Einträge (MySQL-Datensätze) zu derselben Quelladresse:

      team@domain.tld => user1@domain.tld
      team@domain.tld => user2@domain.tld
      team@domain.tld => user3@domain.tld
      u.s.w.

      LG Thomas

      • Hallo Thomas,

        danke für die extrem schnelle Antwort bin echt baff :O

        Der Tipp klingt super, das werde ich gleich mal testen!
        Bisher habe ich immer Mailman oder das „minimalist-Skript“(https://github.com/madroach/minimalist) für Mailing-Listen genutzt, aber das in der MySQL-Datenbank zu machen klingt viel besser, dann kann man sich mit php auch ein schönes Interface zum An/Abmelden bauen.

        Super Arbeit, fettes Dankeschön! und Respekt für die Leistung!

      • Bei mir funktioniert das leider nicht, es wird immer nur der erste Eintrag genommen…

      • Ich habe es jetzt folgendermaßen versucht:

        query = SELECT GROUP_CONCAT(CONCAT(destination_username, ‚@‘, destination_domain)) AS destinations FROM aliases WHERE source_username = ‚%u‘ AND source_domain = ‚%d‘ AND enabled = true GROUP BY source_domain UNION SELECT CONCAT(destination_username, ‚@‘, destination_domain) AS destinations FROM aliases WHERE source_username = “ AND source_domain = ‚%d‘ AND enabled = true

        Das gibt mir die destinations mit Komma separiert zurück, aber auch da wird nur der Erste genommen.

      • Die Kommas waren das Problem. Hier meine Lösung, falls es jemand braucht:
        http://pastebin.com/TTee1XWz

      • Ich habe das Ganze noch ein mal überarbeitet:

        Als erstes habe ich ein View erstell, in dem die Accounts und die Aliase zusammengeführt werden, sonst müsste man die Adresse des Accounts noch einmal bei den Aliase anlegen.
        Außerdem wird jetzt der Catch-All ausgefiltert, falls ein Alias, oder ein Verteiler gefunden wurde.

        Hier ist der Code für das View und das Query:

        http://pastebin.com/9gmrDRVQ

        Konnte nach langem Testen keinen Fehler mehr finden.

  • Hey Thomas,
    ist es möglich eingehende Emails mit einem vom User Hinterlegten GPG schlüssel direkt zu verschlüsseln?

    -Maxi

  • Danke für die Anleitung.

    Würde mich freuen, wenn die Anleitung um die Punkte für einen sekundäreren / Fallback Server erweitert wird bzw. jmd. mir einen Link-Tipp diesbezüglich geben kann.

  • Habe leider Probleme mit dem Milter..

    Hier der Auszug aus dem Log:

    Jun 11 01:48:21 hostnamepostfix/smtpd[7909]: warning: connect to Milter service unix:/var/run/amavis/amavisd-milter.sock: No such file or directory
    Jun 11 01:48:21 hostname postfix/smtpd[7909]: warning: connect to Milter service unix:/var/run/opendkim/opendkim.sock: No such file or directory

    • master.cf und submission_header_cleanup waren plötzlich weg und wurden vom Daemon wieder erstellt. Daher kamen die Fehler. Nun geht alles.

  • Grandiose Anleitung! Danke!

    Ich hätte da aber noch eine Frage:
    Ist dieses Setup ohne Probleme mit VimbAdmin und Sogo verwendbar?

    MFG,
    Dennis Cramer

  • Danke für die Anleitung!

    Allerdings habe ich noch zwei Fragen:
    – Warum verwendest du im Postfix nicht mehr inter_interfaces = all (wie in deiner alten Anleitung) ?
    -Wie sieht es mit Virenschutz aus?

    • 1) inet_interfaces = all verwende ich nicht, weil es besser ist, wenn man die Schnittstellen fest definiert, über die Postfix Mails verschickt. Das hat z.B. den Hintergrund, dass man seinen Server evtl mit einer weiteren IP-Adresse ausstattet, die keinen ReverseDNS-Eintrag hat. Wenn Postfix über diese IP verschickt, landen E-Mails sehr wahrscheinlich in den Spam-Ordnern andere Provider. Legt man die Schnittstellen fest, kann das nicht passieren, weil der Outport damit fest definiert ist. Siehe auch: https://legacy.thomas-leister.de/linux/ptr-record-ungueltig-postfix-verwendet-falsche-ip-adresse-zum-versenden-ipv6/

      2) Virenschutz kann man selbstverständlich z.B. via ClamAV in Amavis integrieren. Dazu gibt es mehr als genug Anleitungen im Netz ;-) Ich habe darauf aus mehreren Gründen verzichtet:
      – ClamAV hat eine Erkennungsrate, die gegen Null geht. Es ist mehr als fraglich, ob die Lösung überhaupt irgendeinen praktischen Nutzen hat
      – Im Allgemeinen haben AV-Programme ausgedient. (siehe z.B. hier: http://www.golem.de/news/symantec-antivirensoftware-ist-tot-1405-106251.html)
      – User haben in vielen Fällen bereits eine wesentlich bessere AV-Lösung auf ihren Endgeräten, sodass ein doppelter Scan + Ressourcenbelastung auf dem Server wenig Sinn macht.

      LG Thomas

  • Servus, Thomas,

    vielen Dank für dieses wirklich spitzenmäßige Tutorial! Es hilft mir, den Aufbau und die Konfiguration Postfix zu verstehen und meinen eigenen kleinen Mail-Server sicher einzurichten – hoffe ich zumindest. :D

    2 Fragen zur Erneuerung der Zertifikate habe ich.

    Muss zum Einen nach jeder Erneuerung eines Zertifikats, das Postfix und/oder Dovecot nutzt, der jeweilige Service neugestartet werden?

    Und zum Anderen: Wenn ich täglich „certbot renewal (…)“ ausführe – unter Arch Linux heißt der Befehl einfach certbot und nicht certbot-auto -, erhalte ich als Ausgabe, dass das entsprechende Zertifikat noch nicht für eine Erneuerung fällig sei. Macht es jetzt Sinn, den jeweiligen Timer dennoch täglich laufen zu lassen, oder laufe ich damit Gefahr, wegen der ständigen unnötigen Anfragen beim Server irgendwann auf eine Blacklist zu rutschen? Ich habe den Service via Systemd-Timer jetzt erst mal auf monatlich gestellt.

    Viele Grüße

    Rüdiger

  • Moin Thomas,

    vielen Dank für deine hervorragende Anleitung!

  • Moin Thomas,
    wie kann ich den für ein Webinterface in PHP das Passwort generieren? Also so das der nutzer sich dann aber auch im Webinterface einloggen kann.

    VIele Grüße,
    MuhPirat

  • Vielen Dank für die ausführliche Anleitung.

    Auf meinem Server nutze ich zusätzlich clamav zum Prüfen der Mails auf Viren. Nach sehr langer Fehlersuche habe ich herausgefunden, dass amavisd-milter besser unter /var/lib/amavis/tmp anstatt unter /var/lib/amavis laufen sollte (siehe auch http://manpages.ubuntu.com/manpages/precise/man8/amavisd-milter.8.html), sonst kann clamav nicht auf die Dateien zugreifen (selbst wenn clamav der Gruppe amavis angehört und umgekehrt). Gibt es einen bestimmten Grund, warum du als working directory /var/lib/amavis anstatt /var/lib/amavis/tmp angegeben hast? Ich hoffe dieser Hinweis hilft all denjenigen, die ebenfalls clamav mit amavis nutzen wollen.

    Viele Grüße
    Julian

  • Hallo,
    ein erstklassiges Tutorial, das Thema war doch viel umfangreicher als gedacht. Ich habe zusätzlich noch solr mit jetty installiert um meine Volltextsuchen zu beschleunigen, jetzt lohnt sich der eigene Mailserver erst so richtig (<100 ms). Ich habe aber noch eine Frage:
    Ich kann mich mit "telnet domain.tld imap" und mit "a login user pw" am imap server voll anmelden, erfolgt dies dann nicht unverschlüsselt? Der Server meldet zwar STARTTLS als capability aber wie kann ich verhindern das clients sich trotzdem unverschlüsselt anmelden?

  • Großartiges Tutorial – vielen Dank.

    Was muss ich auskommentieren, wenn ich Amavis milter & Co nicht benutzen will?

    • Hi Sebastian,

      wenn du Amavis Milter nicht nutzen willst, machst du diese Zeilen in der Postfix main.cf:
      smtpd_milters = unix:/var/run/amavis/amavisd-milter.sock,
      unix:/var/run/opendkim/opendkim.sock
      non_smtpd_milters = unix:/var/run/opendkim/opendkim.sock

      … zu:

      smtpd_milters = unix:/var/run/opendkim/opendkim.sock
      non_smtpd_milters = unix:/var/run/opendkim/opendkim.sock

      Allerdings knipst du damit jede Kontrolle auf Spam aus. Amavis, Spamassassin, Razor und Pyzor kannst du dann auch gleich entfernen ;-)
      LG Thomas

  • hallo,
    ich habe das problem das dovecot den fehler auswürft Jun 22 03:55:15 gamestar-clan dovecot: imap-login: Aborted login (no auth attempts in 0 secs): user=, rip=myip, lip=myip, session=

  • Hallo Thomas,

    super Anleitung.

    Ich bin grade dabei einen Debian 6 durch einen Debian 8 Mailserver abzulösen.

    Der alte läuft mit einer Postfix/Dovecot/MySql-Lösung sehr gut – aber es wird mal Zeit…

    Ich bin etwas verwirrt bei Deiner Anleitung – ich habe das in Debian 6 anders gelöst – in Debian 8 geht das aber so nicht mehr.

    Im Grunde nutze ich in Debian 6 in der main.cf die gleichen Werte wie Du, allerdings habe ich nur eine restriction drin:

    smtpd_recipient_restrictions = permit_mynetworks,
    permit_sasl_authenticated,
    check_client_access hash:/etc/postfix/rbl_override,
    reject_unauth_destination,
    reject_unlisted_recipient,
    reject_unknown_sender_domain,
    reject_unknown_recipient_domain,
    reject_unauth_pipelining,
    reject_non_fqdn_recipient,
    reject_unknown_client_hostname,
    check_recipient_access hash:/etc/postfix/access,
    check_policy_service inet:127.0.0.1:12525,
    check_policy_service inet:127.0.0.1:10023,
    reject_rbl_client zen.spamhaus.org,
    reject_rbl_client hostkarma.junkemailfilter.com=127.0.0.2

    Wenn ich Deine Restrictions alle entferne und nur meine reinsetze, kommt „relay access denied“ – ich kann Mails empfangen aber keine Mails senden.

    Auch die master.cf in Debian 6 ist anders:
    smtp inet n – – – – smtpd -o content_filter=spamfilter

    smtpd pass – – n – – smtpd -o content_filter=spamassassin
    dnsblog unix – – n – 0 dnsblog

    pickup fifo n – – 60 1 pickup
    cleanup unix n – – – 0 cleanup
    qmgr fifo n – n 300 1 qmgr
    #qmgr fifo n – n 300 1 oqmgr
    tlsmgr unix – – – 1000? 1 tlsmgr
    rewrite unix – – – – – trivial-rewrite
    bounce unix – – – – 0 bounce
    defer unix – – – – 0 bounce
    trace unix – – – – 0 bounce
    verify unix – – – – 1 verify
    flush unix n – – 1000? 0 flush
    proxymap unix – – n – – proxymap
    proxywrite unix – – n – 1 proxymap
    smtp unix – – – – – smtp
    relay unix – – – – – smtp
    # -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
    showq unix n – – – – showq
    error unix – – – – – error
    retry unix – – – – – error
    discard unix – – – – – discard
    local unix – n n – – local
    virtual unix – n n – – virtual
    lmtp unix – – – – – lmtp
    anvil unix – – – – 1 anvil
    scache unix – – – – 1 scache

    maildrop unix – n n – – pipe
    flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient}

    uucp unix – n n – – pipe
    flags=Fqhu user=uucp argv=uux -r -n -z -a$sender – $nexthop!rmail ($recipient)

    ifmail unix – n n – – pipe
    flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
    bsmtp unix – n n – – pipe
    flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient
    scalemail-backend unix – n n – 2 pipe
    flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension}
    mailman unix – n n – – pipe
    flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py
    ${nexthop} ${user}

    dovecot unix – n n – – pipe flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/dovecot-lda -f ${sender} -d ${recipient}

    spamassassin
    unix – n n – – pipe
    flags=Rq user=nobody argv=/etc/filter.sh -oi -f ${sender} ${recipient}

    retry unix – – – – – error
    relay unix – – n – – smtp -o smtp_fallback_relay=

    spamfilter
    unix – n n – – pipe
    flags=Rq user=nobody argv=/etc/filter.sh -oi -f ${sender} ${recipient}

    Deine Lösung funktioniert super – aber es ist etwas „too much“.

    Ich nutze weder Amavis noch postscreen – ich bevorzuge policyd-weight & postgrey sowie spamassassin. Ich bin da eher rudementärer unterwegs.

    Ich wollte Deine Lösung „downgraden“ – in die etwas einfacherere Version – naja – klappt halt nicht so wirklich :-(

    Hast Du hier eine Idee?

    gruß

    Sebastian

    • Die Fehlermeldung ist übrigens „relay access denied“ – ich kann keine Mails senden.

      Es muss aber an der Konfiguration von mir liegen – die Datenbank & der MySql-Zugriff sind der gleiche wie bei Deiner Konfig – die habe ich ja umgebaut.

    • Hi Sebastian,

      (ohne die Configs jetzt im Detail verglichen zu haben): bei den Restrictions musst du auf die Reihenfolge achten. Wenn ein Client schon bei einer der ersten Bedingungen rausgeworfen wird, wird ein nachfolgendes „permit“ nichts mehr helfen. Möglicherweise führt eine falsche Reihenfolge bei dir dazu, dass du nicht mehr senden darfst. Beachte auch, dass ich manche Restrictions in der master.cf neu setze (z.B. im Submission-Teil), sodass ein Submission-Client dann doch etwas darf, was in der main.cf zuvor noch verboten wurde.

      LG Thomas

  • Bei mir war
    Before=postfix.service
    in der Datei amavis-milter.service nötig, damit postfix nicht vor amavis-milter gestartet wird und dann nicht auf amavisd-milter.sock zugreifen kann. (und den amavis-milter nicht nutzte)

    LG

    • Okay, das
      Before=postfix.service
      hat doch zufällig nix gebracht. Aber chown und chmod in ein Shell-Skript (das mit ExecStartPost aufgerufen wird) auslagern und davor mit sleep verzögern brachte die Lösung. Chown konnte nicht auf amavisd-milter.sock zugreifen und damit failte die ganze amavis-milter unit. Ich denke, chown wurde nur zu schnell nach dem Start des amavis-milter ausgeführt.

      #!/bin/bash
      sleep 2
      /bin/chown postfix:postfix /var/run/amavis/amavisd-milter.sock
      /bin/chmod 0660 /var/run/amavis/amavisd-milter.sock

      LG

      • DANKE für die Idee mit dem „sleep“ script! Das hat mir fast den Schlaf geraubt, wie passend ;-)

        Ich hab so ungefähr alle Probleme Amavis betreffend die in dieser Kommentarsektion aufgeführt sind durchexerziert. Nichts hat geholfen (und wenn man so oft gegooglet hat dass *alle* Links schon „lila“ sind weil man alles angeklickt hat ist die Verzweiflung groß).

        Aus irgendeinem Grund hatte ich das Problem dass in meinen Log Files Postfix auf beide Sockets – amavisd.sock und amavids-milter.sock – zugreifen wollte. Eins gehörte dem User amavis, das andere Root. Ich habe einfach beide ins Bash script aufgenommen, in die systemd Datei gepackt, und nun klappt es. Sicherlich nicht so sauber aber am Ende des Tages bin ich froh dass es endlich läuft.

        Alles andere war super einfach gemäß der Anleitung aufzusetzen, zumal auch alles sehr detailliert erklärt ist. Aber dieses Amavis-Problem… davon werd ich noch Albträume haben…

    • I almost missed out on that one! I had the same issue running your samples on a debian 8 installation.
      Please add this line to your how-to.

  • Wie bekomme ich einen Catchall hin ?

    @domain.de als Alias bzw. *@domain.de als Alias funktioniert nicht – „user unknown in virtual table“.

  • Gibt es einen bestimmten Grund warum CHARSET=latin1 verwendet wird und nicht UTF-8?

  • Für Dovecot ist noch die Option „lmtp_save_to_detail_mailbox = yes“ nützlich, dann werden Empfänger a la „name+tag@domain.tld“ direkt den unterordner „tag“ vom user „name@domain.tld“ verschoben

  • Hi nochmal,

    ich war auch schon beim alten Artikel mit dabei! :)
    Folgendes ist aber immer noch hier drin:
    `GRANT ALL ON vmail.* TO ‚vmail’@’localhost‘ IDENTIFIED BY ‚vmailpasswort‘;`
    Da der Benutzer vmail nur Leserechte („SELECT“) benötigt, reicht es vollkommen aus, ihm auch nur Leserechte (und nicht „ALL“ Rechte) zu geben:
    `GRANT SELECT ON vmail.* TO ‚vmail’@’localhost‘ IDENTIFIED BY ‚vmailpasswort‘;`
    Nach so einer Änderung sollte generell immer `FLUSH PRIVILEGES;` ausgeführt werden.

    • Hi Johathan,

      Der Gedanke hinter dem „all“ für die Berechtigungen war, dass dieser Nutzer auch für eine evtl. vorhandene Verwaltungssoftware genutzt wird, wie z.B. ehem. WebMUM. Wenn man über vmail nur lesen will, kann man das natürlich entsprechend umstellen. Ein FLUSH PRIVILEGES braucht es nicht, weil die Berechtigungen bei einem Login von „vmail“ sowieso neu geladen werden. Das Flush Privileges sollte man ausführen, wenn der Benutzer bereits mit dem Server verbunden und aktiv ist.

      LG Thomas

  • smtp_bind_address wäre noch wichtig, da sonst einige Mailserver die E-Mails ablehnen.

    Doch wohin genau gehört das? Ich kann leider überhaupt nicht herausfinden, ob Postfix wirklich die korrekte IP bindet.

    • > Note 1: when inet_interfaces specifies no more than one IPv4 address,
      > and that address is a non-loopback address, it is automatically used as
      > the smtp_bind_address

      http://www.postfix.org/postconf.5.html

      Das passt schätze ich. Ansonsten steht dort noch:

      > This can be specified in the main.cf file for all SMTP clients,
      > or it can be specified in the master.cf file for a specific client

  • Hallo, erstmal vielen Dank für die super Anleitung. Ich habe diese 1zu1 auf meinem Debian 8 Server übernommen. Jedoch bekomme ich immer folgende Fehlermeldung beim empfangen einer Nachricht (hier z.b. von freenet, auch gmail geht nicht):
    postfix/smtpd[25074]: NOQUEUE: reject: RCPT from mout3.freenet.de[195.4.92.93]: 554 5.7.1 : Relay access deni
    ed; from= to= proto=ESMTP helo=
    Habe alles mehrmals geprüft, stimmt alles – DNS, Postfix und Dovecot Konfigurationen

  • Hallo @ll,

    Das klappt auch wunderbar auf einem Debian 8.5 System.

    .. nur mit den IPv6-Adressen komme ich noch nicht so ganz klar … :D

  • Hi,

    wie stelle ich die Verschlüsselung der Passwörter für smtp & imap von SHA1 auf MD5 um?

    gruß
    Claus

    • Hi Claus,

      tu‘ das bitte nicht. MD5 ist schon lange „gebrochen“ und hat in etwa den Sicherheitswert von ROT13-Crypto. … man könnte also eigentlich gleich in Klartext speichern ;-) Grundsätzlich lassen sich Passworthashes nicht einfach konvertieren, da sie ja nicht in Klartext vorliegen. Prinzipiell ist es möglich, nach einem erfolgreichen Login aber einen neuen Hash nach einem neuen Algorithmus zu generieren. Wie das geht, kann ich dir aus dem Kopf heraus nicht sagen – soweit ich weiß gibt es dazu aber How-Tos im Netz.

      LG Thomas

  • Hallo Thomas, vielen Dank für diese Anleitung.
    Eine Frage: Warum verwendest du nicht die Mailbox-Administrations-Lösung „ViMbAdmin (https://github.com/opensolutions/ViMbAdmin)?

  • Hallo Thomas,
    eine Frage zum Thema „Reverse-DNS-Record / PTR für den FQDN des Mailservers“:
    Muss ein Reverse-DNS-Record in jedem Fall angelegt werden, auch dann wenn nur 1 Public IP vom Internetprovider zur Verfügung gestellt wird, diese Public IP aber für diverse Webservices mittels relevanter Subdomains genutzt werden soll, z.B. Mailserver, Webserver, ect.?
    Ich werde im lokalen Netzwerk einen Reverse-Proxy einrichten, damit ich die Anfragen unter Verwendung einer Subdomain auf die entsprechenden Server umleiten kann.

    THX

    • Hi Thomas,

      Ja, dieser PTR Record muss zwar nicht zwingend, _sollte_ aber angelegt werden. Der IP, über die der Mailserver nach draußen funkt (also deine eine IP), muss ein Hostname via rDNS zugeordnet werden. Und zwar ein Hostname, der im öffentlichen DNS verfügbar ist und wieder zurück auf eben diese IP-Adresse zeigt. Hostname und IP-Adresse zeigen also jeweils auf den anderen. Du kannst auch auf einen rDNS-Eintrag verzichten – musst dann aber damit leben, dass einige Provider von dir ausgehende Mails als Spam einstufen werden.

      LG Thomas

      • Hallo Thomas,
        ich habe jetzt einen Reverse DNS Eintrag auf meinen FQDN.
        Allerdings kann ich keine Emails zu web.de oder GMX senden.
        telnet mx01.emig.gmx.net 25
        Trying 212.227.17.5…
        Connected to mx01.emig.gmx.net.
        Escape character is ‚^]‘.
        554-gmx.net (mxgmx113) Nemesis ESMTP Service not available
        554-No SMTP service
        554-IP address is black listed.
        554 For explanation visit http://postmaster.gmx.com/en/error-messages?ip=46.5.14.14&c=bl

        telnet mx-ha03.web.de 25
        Trying 212.227.15.17…
        Connected to mx-ha03.web.de.
        Escape character is ‚^]‘.
        554-web.de (mxweb008) Nemesis ESMTP Service not available
        554-No SMTP service
        554-IP address is black listed.
        554 For explanation visit http://postmaster.web.de/error-messages?ip=46.5.14.14&c=bl

        Hängt das damit irgendwie zusammen?

  • Danke für die ausführliche Anleitung. Ich habe einmal begonnen einen Mailserver mit tine20-integration aufzusetzen. Dazu hier der Installer:
    http://smartrns.net:8080/smartrns-team/install-mailserver.git
    Es fehlen noch einige Komponenten (Spamschutz, Antivirus), aber im Kern läuft es.

  • Hey, danke für den Guide.
    Hättest du vielleicht noch eine Anleitung, wie oder ob sich Mails direkt lokal beim Eintreffen verschlüsseln lassen? Also das die Mails praktisch nur verschlüsselt auf dem Mailserver existieren und der jeweilige User der einzige ist, der darauf zugreifen kann.

    • Hi Daniel,

      so eine Verschlüsselung macht Prinzip-bedingt keinen Sinn. Als Betreiber des Servers, der die Hoheit über die Verschlüsselung hat, kannst du die Mails nicht vor dir selbst schützen. Die einzig sinnvolle Art der Verschlüsselung wäre hier eine End-to-End Verschlüsselung: Absender und Empfänger der Mail verschlüsseln, bevor die Mail überhaupt zum Server gelangt. Alles, was Crypto-mäßig auf dem Server geschieht, lässt sich durch jemanden, der Server-Zugriff hat (du oder ein Angreifer) abschalten oder manipulieren. Derjenige, der Crypto anwendet, darf niemals derjenige sein, der sie vielleicht umgehen wird – sonst wird das ganze ad absurdum geführt ;-)

      LG Thomas

      • Hey,
        danke für die Antwort. Würde das nicht einfach per PGP gehen? Die Mails werden ja mit dem Passwort des einzelnen Kontos verschlüsselt und die Passwörter kennt der Serverbetreiber ja nicht oder? Hast du dich schon mal mit dem Verschlüsselungskonzept von Posteo befasst? https://posteo.de/site/verschluesselung
        So ungefähr hab ich mir das vorgestellt.
        Siehe dazu auch: https://grepular.com/Automatically_Encrypting_all_Incoming_Email oder http://sealedabstract.com/code/nsa-proof-your-e-mail-in-2-hours/

        • Hi Daniel,

          das kann man machen – ich kann dir aber nicht sagen, wie genau. Für mich steht fest, dass das Konzept „verschlüssle eingehende, unverschlüsselte Mails auf dem Mailserver“ mehr oder weniger sinnlos ist. Das ist auch bei Posteo mehr Marketing, als eine vernünftige Maßnahme. Wie schon gesagt: Die Verschlüsselung MUSS – wenn man es ernst meint – auf den Systemen des Anwenders stattfinden, sonst führt man das ganze ad absurdum. Wenn Posteo eingehende Mails mit dem Mailaccount-Passwort verschlüsseln will, muss entweder ein Hash des Passwortes vorliegen, der wiederum für PGP als Passwort dient, oder das Passwort in Klartext. Im ersten Fall hätte Posteo den Key ohnehin in den eigenen Datenbanken, im zweiten Fall kommt das Passwort auch im Klartext bei Posteo an und kann genutzt werden, um zu entschlüsseln. In beiden Fällen kann Posteo selbst (oder die Exekutive) Mails entschlüsseln.

          Es wird immer wieder damit geworben: „Wir verschlüsseln ihre Daten für sie“ – nur wenn das jemand anderes für mich macht und nicht ich selbst – dann ist das schon keine ernst gemeinte Verschlüsselung, sondern ein Marketingversprechen, das Kunden anziehen soll. Natürlich kann man das machen, und dafür gibt es ja auch schon Anleitungen im Netz… nur Sinn macht es nicht. Der Anwender muss seine Mails _vor dem Transport_ selbst absichern, sonst gibt es sehr schnell sehr viele Möglichkeiten, Sicherheit kaputt zu machen.

          Edit: Um das Problem nochmal zu veranschaulichen: Du würdest auch nie auf die Idee kommen, einen fremden auf der Straße zu bitten, dein Haus abzusperren. Natürlich kann es sein, dass der fremde seinen Auftrag zuverlässig erledigt – es kann aber genausogut sein, dass er vorher in deinem Haus herumschnüffelt. Deshalb wird man nie so jemanden beauftragen, sondern das Haus immer selbst beim Verlassen absperren. (=> Nicht jemand anderen die Verschlüsselung erledigen lassen, sondern selbst machen! => PGP auf dem Mailclient)

          LG

          • Naja obwohl, die Aussage mit dem Passwort war mein Fehler. Theoretisch wird ja einfach nur verschlüsselt, wie jede Mail mit PGP verschlüsselt wird, also bei Maileingang mit dem Public Key und ich entschlüssele mit meinem Private Key. Auf den Private Key hat der Server ja an sich keinen Zugriff. Das ganze soll wie gesagt auch nur eine Ergänzung zu Ende-zu-Ende sein und natürlich kein Ersatz o.ä.

  • Der Guide ist echt cool, bei mir funktioniert tatsächlich auch fast alles. Kann mich per Emailclient anmelden, E-mails empfangen aber leide keine senden:

    Folgende Fehlermeldung bekomme ich in der syslog beim Versuch eine Email über meinen Emailclienten zu senden:
    Jul 21 03:14:38 mail postfix/postscreen[6361]: CONNECT from [MEINEIP]:57881 to [37.120.190.104]:25
    Jul 21 03:14:38 mail postfix/dnsblog[6364]: addr MEINEIP listed by domain zen.spamhaus.org as 127.0.0.10
    Jul 21 03:14:44 mail postfix/postscreen[6361]: DNSBL rank 2 for [MEINEIP]:57881
    Jul 21 03:14:44 mail postfix/postscreen[6361]: DISCONNECT [MEINEIP]:57881

    Hab mal meine lokale IP rausgenommen und durch MEINEIP ersetzt.

    Hab versucht Google zu bemühen, bin aber ziemlicher Neuling und wenn ich es richtig verstanden habe, stört sich spamhaus.org an meiner Email?
    Würde mich über Lösungvorschläge und Erklärung des Problems freuen ;)

    MfG KingEldarion

    • Hi KingEldarion,

      anscheinend verbindest du nicht (wie in der Anleitung am Ende angegeben) via Port 587 (Submission) zu deinem Mailserver, sondern via Port 25. Mailclients sollen und können sich mit diesem Setup allerdings nur via Submission mit dem Mailserver verbinden, da der andere Port für Server-Server Verbindungen eingerichtet ist und keine Authentifizierung zulässt. Da du Port 25 nutzt, wo der Spamhaus-Filter aktiv ist, wird deine DSL-IP blockiert. Der Submission-Port ist von den Spamfiltern ausgenommen. Wenn du die Einstellungen in deinem Mailclient so änderst, dass nicht Port 25, sondern 587 zum Versenden genutzt wird, sollte das Versenden funktionieren.

      LG Thomas

  • Hallo Thomas,
    ich möchte meine Emails mit PGP verschlüsseln.
    Muss ich hierfür zusätzliche Software auf dem Mailserver installieren?
    Oder ist das ausschließlich Sache des Mailclients?

    THX

  • Vielen Dank für die neue Anleitung. Ich habe bereits seit Jahren einen Server nach deiner alten Anleitung in Betrieb und bin höchst zufrieden damit. Nun steht bei mir ein Plattform Wechsel an und ich würde den neuen Server gerne entsprechend der neuen Anleitung aufsetzen. Wichtig hierbei ist mir jedoch die Migration der Daten, sowohl der Benutzer als auch der vorhandenen E-Mails. Ist eine derartige Migration ohne weiteres möglich?

  • Hallo Thomas!

    VIelen Dank für diese tolle Anleitung, hat mir ohne weiteres funktioniert. Ich wollte noch fragen, ob du einen einfachen Weg kennst, dass jeder eingerichtete Nutzer direkt über den Mail-Server (also nicht über einen Client) seine E-Mails signieren und verschlüsseln kann, also mit eigenem Schlüssel. Außerdem wollte ich Wissen, ob auch eine Authentifizierung mittels Zertifikat möglich ist.

    Besten Dank!

    • Hallo Frank!

      zu beidem kann ich dir leider aus dem Kopf heraus nichts sagen. Ersteres ist theoretisch bestimmt möglich, allerdings kann ich dir dazu keinen Tipp für eine Umsetzung geben.

      LG Thomas

    • Eine Verschlüsselung/Signierung direkt am Server ist meiner Meinung nach absolut kontraproduktiv.
      – Was, wenn der Empfänger keine Verschlüsselung unterstützt?
      – Zum Entschlüsseln und signieren einer Nachricht wird der private key benötigt – den müsste man dann für jeden user am server hinterlegen, was ein riesengrosses Sicherheitsrisiko darstellt
      – es gibt aber eine Kombination aus webmail-dienst (zB rainloop) und browser-plugin, was das ganze dann recht transparent macht, vielleicht schreibe ich irgendwann mal eine Anleitung dafür, wenn es soweit sein sollte, werd ich das hier posten

  • Hallo Thomas,
    ich bin eher zufällig über deine Anleitung gestolpert, weil ich gefragt wurde, ob die Anleitung was taugt.
    Ich hab sie jetzt nur grob überflogen, aber auf den ersten Blick macht sie schon einen sehr soliden Eindruck. Was mir besonders gefällt ist die Tatsache, daß du an vielen Stellen erklärende Worte findest, so daß auch weniger versierte Admins verstehen können, was sie da machen und eben nicht nur blindes Copy/Paste abarbeiten.

    Allerdings hätte ich doch noch einige Anmerkungen dazu:
    1. Spamschutz
    Wenn Postscreen richtig konfiguriert ist, bleiben sicher schon >99% aller unerwünschten Mails außen vor. Insoweit sehe ich den Einsatz weiterer Schutzmaßnahmen schon fast als überflüssig an.
    Ich betreue mehrere Mailserver, die (bis auf einen wo der Kunde es explizit anders gewünscht hatte) alle nur mit Postscreen als Schutzmechanismus arbeiten und trotzdem kein wirklich nennenswertes Spamaufkommen zu verzeichnen ist.
    Außerdem ist die „Geiz ist geil“-Mentalität auch nicht an der IT vorbeigegangen und für viele (Hobby-)Admins sind 5 Euro für einen kleinen eigenen vServer schon viel Geld. Bei dem Preis sind dann natürlich die zugeteilten Hardwareressourcen schon sehr beschränkt, was zur Folge hat, daß solche Kisten beim Einsatz von Spamassassin, Amavis und Co. schnell mal an ihre Leistungsgrenzen stoßen oder völlig in die Knie gehen.
    2. MySQL
    Speziell wieder im Hinblick auf kleinere Kisten wäre ein Hinweis auf eine Optimierung des MySQL-Daemons wünschenswert, da in der Standardinstallation sehr großzügige Werte eingestellt sind, was u.U. die Systemstabiltät gefährden könnte…gerade auch dann, wenn Amavis und Co. sich auch noch ihren Teil der eh schon spärlichen Ressourcen genehmigen.
    3. Web-GUI
    Da deine Eigenentwicklung laut deiner Aussage nicht mehr kompatibel ist, wäre hier eine nahtlose Einbindung eines alternativen Web-GUI (z.B. Postfix Admin oder ViMbAdmin) in deine Anleitung wünschenswert.
    Hier sollte berücksichtigt werden, daß deine Anleitung möglichst „DAU-tauglich“ sein sollte und daß man bei weniger versierten Admins nicht immer voraussetzen kann, daß sie Domains, Postfächer und andere userspezifische Änderungen problemlos über das CLI verwalten können.

  • Hallo Thomas,

    mein Mail-Server funktioniert, große Probleme gab es nicht. Ich habe jetzt eine Domain und ein paar User eingerichtet, was auf Dauer doch sehr mühselig sein kann. Kennst du eine gute Weboberfläche mit der man das machen könnte und die auf vorhadene Domains aufsetzen kann? Ich habe schon Vimbadmin probiert, jedoch kann diese die bisherigen Domains nicht importieren :-\

  • Hallo, erstmal vielen Dank für das Tutorial, hat mir echt sehr geholfen.
    Habe noch einen Verbesserungsvorschlag.
    Bei der Installation von opendkim (auf Ubuntu 14.04LTS) wird standardmäßig inet:8891@localhost genutzt,
    Da amavid-milter aber für /var/run/opendkim/opendkim.sock konfiguriert wurde, wäre es sicherlich sinnvoll den Socket in der /etc/opendkim.conf einzutragen mit „Socket /var/run/opendkim/opendkim.sock“

  • Moin Thomas,
    nutze jetzt schon mehrere Jahre meinen eigenen Mailserver, den ich mit deinem Tutorial konfiguriert habe ;) Läuft super – vielen Dank dafür!

    Jetzt habe ich eine komische Email bekommen. Und zwar ist die Email von meinem eigenem Server via LMTP versendet worden, von einem Benutzer den es nicht gibt. Die Mail enthält ein docx Makro, welches ich natürlich nicht geöffnet habe.
    Als Sender-IP ist eine indische IP eingetragen:

    Return-Path:
    Delivered-To:
    Received: from meinserver
    by meinserver (Dovecot) with LMTP id 5OEfMsuojVfedgAAoG8ARw
    for ; Tue, 19 Jul 2016 06:12:59 +0200
    Received: from [103.220.210.9] (unknown [103.220.210.9])
    by meinserver (Postfix) with ESMTP id C982D36502881
    for ; Tue, 19 Jul 2016 06:12:55 +0200 (CEST)
    Mime-Version: 1.0
    X-Mailer: Internet FAX, MGCS
    Content-Type: multipart/mixed; boundary=“+-+-+-+-MGCS-+-+-+-+“
    Date: Tue, 19 Jul 2016 09:42:52 +0530
    Message-Id:
    From:
    Subject: Scanned image
    To: ich@meinserver.de

    –+-+-+-+-MGCS-+-+-+-+
    Content-Type: text/plain; charset=iso-8859-1
    Content-Transfer-Encoding: Quoted-Printable
    Content-X-CIAJWNETFAX: IGNORE

    Image data has been attached to this email.

    –+-+-+-+-MGCS-+-+-+-+
    Content-Type: application/vnd.ms-word.document.macroEnabled.12; name=“18-07-2016_52758682.docm“
    Content-Transfer-Encoding: base64
    Content-Disposition: attachment; filename=“18-07-2016_52758682.docm“
    Content-Description: 18-07-2016_52758682.docm

    In den Log sind nur diese vier Zeilen zu finden:
    ./mail.log.1:Jul 19 06:12:54 meinserver postfix/smtpd[30418]: connect from unknown[103.220.210.9]
    ./mail.log.1:Jul 19 06:12:55 meinserver postfix/smtpd[30418]: C982D36502881: client=unknown[103.220.210.9]
    ./mail.log.1:Jul 19 06:13:00 meinserver postfix/smtpd[30418]: disconnect from unknown[103.220.210.9]
    ./mail.info.1:Jul 19 06:12:54 meinserver postfix/smtpd[30418]: connect from unknown[103.220.210.9]
    ./mail.info.1:Jul 19 06:12:55 meinserver postfix/smtpd[30418]: C982D36502881: client=unknown[103.220.210.9]
    ./mail.info.1:Jul 19 06:13:00 meinserver postfix/smtpd[30418]: disconnect from unknown[103.220.210.9]

    Kannst du einschätzen wie kritisch das ist? Es wurden keine Emails nach außen geschickt.

    • Hi Tobi,

      die E-Mail ist auf jeden Fall verseucht. Das ist ganz klar Locky drin o.Ä. drin. Was den Mailtransport angeht, kann ich dich beruhigen: Dein Server hat einfach nur eine Spammail empfangen – mehr nicht. Dass bei LMTP steht, dass die Mail von deinem eigenen Server stammt, ist ganz normal und kommt daher, dass die Mail innerhalb des Servers relayed wird. Der eigentliche Ursprung der Mail ist aber der Server mit der IP-Adresse 103 … , also der Server, der im untersten Received-Header aufgelistet wird.

      LG Thomas

      • Hi Thomas,
        vielen Dank für die schnelle und beruhigende Antwort. Dachte schon ich müsste jetzt alles neu machen.
        Danke, dass du überhaupt auf solche Problemberichte antwortest ;)

        Weiter so!
        Gruß
        Tobi

  • Hallo Thomas,

    vielen Dank für das wirklich gelungene Tutorial, welches bei mir auf einer Debian 8 Kiste direkt auf Anhieb lief.
    E-Mails kommen an und können auch bereits gesendet werden, soweit so gut allerdings
    stehe ich aktuell noch vor dem Problem dass Mails scheinbar nicht durch Spamassassin geschleift werden,
    so wurde die Testmail mit dem Text: XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X
    einfach durchgelassen.

    In den Logs finde ich nichts auffälliges dazu, hast du eine Idee wo ich am besten mit der
    Fehlersuche ansetzen soll?

    Vielen Dank schon mal für deine Rückmeldung und ein schönes (Rest)Wochenende noch.

  • Hallo Thomas,
    dein Tutorial funktioniert super. Kann ich Postfix auch so konfigurieren, dass Mails an eine spezielle Domain an eine spezielle IP versendet werden? Wir haben zwei Netzwerke mit jeweils eigenen Mail-Servern über VPN verbunden und die Mails sollen nicht über das Netz versendet werden.

    MfG

    Lars

    • Du könntest den Hostnamen doch in der hosts-Datei mit der speziellen IP eintragen, das sollte doch funktionieren?

  • kann mich nicht zum server mit dem client einloggen bekomme diesen Feher im Mail.err log

    SSL routines:ssl3_get_client_hello:no shared cipher

    einer ne Idee?

  • Hey Thomas,

    vielen Dank nochmal für das wirkliche gelungene Tutorial.
    Mittlerweile läuft mein Mailserver soweit auch und kann bereits mit Thunderbird E-Mails abrufen und versenden.
    Jetzt wollte ich allerdings das Konto auf meinem Android einrichten und hänge beim Schritt für die SMTP Details dort
    erhalte ich nur die folgende Meldung: „Sichere Verbindung mit Server kann nicht hergestellt werden.“

    Ich verwende als Sicherheitstyp TLS und als Port 587.
    Das Gerät ist übrigens ein Samsung Galaxy S3.

    Hättest du eine Idee wie ich das Problem lösen könnte, ohne dass ich das Gerät in den nächsten Fluss werfen muss? =)

  • Hi Thomas,

    danke für deine schnelle Antwort! Das hilft mir weiter!

    LG

    Andreas

  • Hi,
    danke für die Anleitung, ich hab aber ein paar Anmerkungen:
    – an mehreren Stellen wird um das db-passwort zu schützen eine config-datei mit chmod 770 konfiguriert, was meiner meinung nach auf jeden fall besser mit chmod 640 wäre.
    – warum ein eigener mirror von amavisd-milter? ich sehe dort keine changes, nur ein commit und allem Anschein nach kann version 1.6.1 das eh auch schon alles: https://sourceforge.net/projects/amavisd-milter/
    – eine Konfiguration der user per SQL ist finde ich doch etwas mühsam, vor allem wenn man viele aliases hat (so wie ich – jeder popel-dienst bekommt ein eigenes alias … unglaublich nützlich, wenn man rausfinden will, welche verdammte Firma nun die email-Adresse verkauft hat), ich setze hierbei auf postfixadmin. Es gibt auch andere, zB ViMbAdmin (https://github.com/opensolutions/ViMbAdmin/wiki) aber damit hab ich mich noch nicht beschäftigt.
    Das dumme ist aber, dass man postfixadmin erst beibringen muss, dass ein SHA-encrypted passwort auch gesalzen sein kann, das hat der user sleepdead hier (https://sourceforge.net/p/postfixadmin/discussion/676076/thread/38834a33/ – siehe http://pastebin.com/qjs7iHiu) getan und bei mir funktionierts. Postfixadmin wurde vorher per apt install geholt (Ubuntu 16.04)
    Und selbstverständlich muss man die datenbank-queries für postfix entsprechend anpassen.
    Ich bin gerade mitten drin in der Konfiguration, zzt wird mir noch die IMAP-auth verweigert (stand: vor Umstellen auf postfixadmin, also mit 1:1 dieser Anleitung), aber ich komm da schon noch drauf, was die Ursache ist.

    • Hi nochmal,

      Konfiguration ist fertig, Integration von Rainloop und postfixadmin steht ebenfalls.
      Falls Interesse an einer Anleitung besteht, bitte gerne bei mir melden. :-) mailserver-einrichten [at] gelse.net
      und ja, das ist bereits ein über den postfixadmin eingerichteter alias. ;-)

  • Hallo Thomas,

    Erst mal vielen Dank für diese sehr gut geschriebene Anleitung.
    Ich bin gerade mitten drin sie durchzuarbeiten und hänge beim Punkt Amavis fest.
    Ich habe mich wie beschrieben per „sudo -i -u amavis“ angemeldet und bekomme nach der Eingabe „razor-admin -create“ die Ausgabe „nextserver: Bootstrap discovery failed. Giving up.“.

    Hast Du evtl. eine Idee was da falsch läuft?

    Gruß Michael

  • Hallo Thomas,

    vielen Dank für das Tutorial. Es hat soweit alles geklappt bei der Einrichtung.

    im Abschnitt „Spamassassin für MySQL konfigurieren“ jedoch, bin ich mir nicht sicher, welche Kommentare in der Datei „/etc/mail/spamassassin/local.cf“ ich entfernen kann bzw. sollte. Das Anfügen der MySql-Konfiguration ist ja klar.

    Kannst du zu diesem Punkt vielleicht noch etwas sagen?

    Gruß

    Andreas

  • Hi Thomas,
    kann man deinen Mailserver auch hinter einem nginx Reverse-Proxy, den ich bereits anderweitig nutze, betreiben? Das Zertifikat Handling wäre dort bereits vorgeschaltet.
    LG Stefan

    • Hi Stefan!

      Ja, mit ein paar Anpassungen ist das möglich. In dem Fall müsstest du Postfix und Dovecot via Config anweisen, keine Verschlüsselten Verbindungen zu erzwingen, da das ja schon Nginx übvernimmt. Wie gut das dann funktioniert, kann ich dir allerdings nicht sagen, weil ich mit einem solchen Setup keine Erfahrungen habe.

      LG Thomas

  • Hallo! Vielen Dank für die ultimative Anleitung!

    Ist es normal, dass ich mit Root-Rechten alle Mails (von allen Mail-Adressen) auf dem Mailserver lesen kann? Und bedeutet das, falls man nicht mit end-to-end verschlüsselt, dass alle Admins da draußen (gmx, web.de, googlemail…) die Mails auf ihren Servern lesen können?

    • Hubert Schölnast

      Ja, das ist normal. Eine E-Mail besteht aus den Header-Zeilen gefolgt vom eigentlichen Inhalt (dem Body). Wenn der Absender den Body, also den Text einer E-Mail nicht selbst verschlüsselt, und mit dem Empfänger ein Verfahren zur Entschlüsselung vereinbart, dann wird dieser Inhalt ganz gleich behandelt wie die Headerzeilen, denn Header und Body bilden eine Einheit.

      Der Mailserver des Empfängers (Postfix im hier beschriebenen Fall) muss aber zumindest die Headerzeilen lesen können, damit er entscheiden kann, ob er die E-Mail annimmt, oder zurückweist. Ein anderes Programm muss auch wissen, in welches Empfänger-Postfach die E-Mail zustellen soll, und ein drittes (z.B. Spamassassin) muss sogar den Inhalt lesen können, um zwischen Spam und Not-Spam (Ham) unterscheiden zu können.

      Stunden oder Tage nachdem die E-Mail gespeichert wurde, muss auch der Spam-Learner nochmal den Inhalt lesen, um seine Filterregeln anpassen zu können.

      All das macht notwendig, dass der Inhalt so wie er übertragen wurde, gespeichert wird. Also unverschlüsselt, und somit von root lesbar.

      Generell sollte man immer davon ausgehen, dass nicht nur der Mensch, der das Passwort für root hat, alles lesen kann, sondern auch viele andere Mitarbeiter, die den Server betreuen. Selbst wenn es allgemein üblich ist, z.B. Passwörter verschlüsselt zu speichern, darfst du nicht davon ausgehen, dass das auch jeder wirklich macht. Gehe stattdessen sicherheitshalber immer davon aus, dass alles, was du über das Internet versendest (vertrauliche E-Mails, Passwörter, …) unverschlüsselt auf den Servern gespeichert wird, und von dutzenden Menschen im Klartext gelesen werden kann.

      Gehe auch davon aus, dass das Löschen von E-Mails nur bewirkt, dass deine E-Mail als gelöscht markiert wird, aber weiterhin auf dem Server liegen bleibt. Das ist zwar nicht die Standard-Vorgehensweise, aber angeblich (Vorsicht: unbestätigtes Gerücht!) soll das Google mit seinen gmail-Konten genau so machen. Du siehst die gelöschte Mail zwar nicht mehr, aber Google kann sie weiterhin benutzen, um deine Gewohnheiten zu analysieren, mit dem Ziel, dir Werbung zuzustecken, die genau deinen Gewohnheiten entspricht.

      Ich selbst habe früher als Softwareentwickler für eine Bank gearbeitet, und dort waren bis 2008 die Losungswörter aller Sparbücher unverschlüsselt gespeichert, und auf die Datenbank mit den Losungsworten hatten rund 100 Mitarbeiter lesenden Zugriff.

      Eine Organisation, die dem österreichischen Arbeitsamt nahe steht, hat die Passwörter ihrer Kunden ebenfalls im Klartext gespeichert. Als ich meine eigene Firma gegründet habe, hatte ich mit dieser Organisation zu tun, und bei einem Beratungsgespräch hat mich der Berater für mein vorbildliches Passwort gelobt. Er hatte es nämlich zusammen mit meinen anderen Stammdaten im Klartext auf seinem Bildschirm stehen. Wenn ich mit demselben Passwort meine Bankgeschäfte abgesichert hätte, hätte er problemlos und unerkannt Geld von meinem Konto abheben können, denn meine Kontonummer gehörte auch zu den Daten, die auf seinem Bildschirm zu sehen waren.

  • Hubert Schölnast

    (Sorry, beim vorigen Kommentar ist mir ein Fehler beim Posten passiert.)

    Frage zu TLS-Policies:

    Wenn ich den Zweck der Tabelle tlspolicies richtig verstehe, hängt deren Inhalt nicht von der Konfiguration meines eigenen Mailservers ab, sondern von gewissen Aspekten der Konfiguration fremder Mailserver. Auf diese fremden Server habe ich aber keinen Einfluss. Das wirfst zwei Fragen auf:

    1. Wie erfahre ich, welche Einträge in der Tabelle tlspolicies ich z.B. für die Domain example.com machen soll?

    2. Wenn der Postmaster von example.com die Konfiguration seines Mailservers ändert, kann das Änderungen in meiner Tabelle tlspolicies notwendig machen. Wie erfahre ich, das solche Änderungen notwendig sind? Wie erfahre ich, was die neuen Werte sein sollen?

    Da nicht nur ich alleine Antworten auf diese Fragen brauche um die Tabelle tlspolicies sinnvoll nutzen zu können, frage ich mich, ob es da nicht irgendwo eine zentral gepflegte (und sichere) Tabelle im Internet gibt, mit der ich z.B. einmal pro Woche meine bisherigen Einträge überschreiben kann.

    Deine wirklich hervorragende Anleitung (bravo! und danke!) wäre noch um einen Tick besser, wenn du für die wichtigsten Mailserver Einträge für die Tabelle tlspolicies veröffentlichen würdest.

    • Hi Hubert,

      was die TLS-Policies angeht, ist leider etwas Handarbeit angesagt. Ein Bekannter und ich wollten unter http://tlspolicy.org mal eine solche zentral verwaltete Stelle aufbauen, allerdings ist das Projekt aus Zeitmangel eingeschlafen. Vielleicht nehmen wir das aber auch mal wieder auf. Bisher habe ich meine Einträge einfach über den Mailcheck von https://de.ssl-tools.net geschrieben. Einfach verschiedene Anbieter eingegeben und geschaut, mit welchen Parametern man eine Verbindung sichern kann. Wenn du dir die Mühe sparen willst: Hier hat sich schon jemand eine kleine Liste zusammengebastelt: https://github.com/csware/postfix-tls-policy/blob/master/tls_policy-dane

      LG Thomas

      • Hallo Likas,
        Danke für dein Post. Hat mir bei der Konfiguration meines Servers sehr geholfen. Ich habe aber ein Problem. Ich kann kein Mail an google.com, googlemail.com oder auch yahoo.de/fr.. abschicken. Ich habe gemerkt, dass alle Einträge in der tlspolicy Tabelle nicht aufgenommen werden. Also ich habe in meine Policy Tabelle alle Einträge mit deinem Link gefüllt.

        „Undelivered Mail Returned to Sender“ – Content:

        This is the mail system at host mx.domain.tld.

        I’m sorry to have to inform you that your message could not
        be delivered to one or more recipients. It’s attached below.

        For further assistance, please send mail to postmaster.

        If you do so, please include this problem report. You can
        delete your own text from the attached returned message.

        The mail system

        : host googmail.com[109.201.135.34] refused to talk to
        me: 421 Downstream server error

        This is the mail system at host mx.domain.tld.

        I’m sorry to have to inform you that your message could not
        be delivered to one or more recipients. It’s attached below.

        For further assistance, please send mail to postmaster.

        If you do so, please include this problem report. You can
        delete your own text from the attached returned message.

        The mail system

        : TLS is required, but was not offered by host
        mx-eu.mail.am0.yahoodns.net[188.125.69.79].

        Die Logs-Files zeigen:
        (TLS is required, but was not offered by host mx-eu.mail.am0.yahoodns.net[188.125.69.79])
        (TLS is required, but was not offered by host googmail.com[109.201.135.34])

        Hast du vielleicht ein Idee woran es liegen kann? Oder soll ich einfach die Einträge für google und yahoo von meiner tslpolicy Tabelle löschen? (Wenn ja, dann macht kein Sin diese Tabelle zu haben.)

  • Danke für deine gute und ausführliche Anleitung.
    Als ich sie nachinstalliert habe (auf einem Debian 8) scheint soweit alles funktioniert zu haben. Allerdings habe ich ein Postfach, das seinen Quota erreicht hat und ich kann von einer anderen Adresse aus noch immer munter Mails dorthin schreiben. Lediglich über IMAP bekomme ich einen Hinweis. Ist dieses Verhalten normal/gewollt oder habe ich da irgendwo einen Fehler, den ich übersehen habe?

  • Hubert Schölnast

    Ich habe deine Anleitung befolgt, und es klappt auch alles so weit recht gut. Aber der Systemuser root bekommt von verschiedenen anderen Systemusern lokale E-Mails zugeschickt. Diese landen derzeit aber in der Datei /var/mail/root (eine Datei in der hintereinander mehrere Mails stehen)

    So schaut ein typischer Header einer solchen E-Mail aus:

    From root@mail.mysystems.tld Mon Aug 22 14:43:06 2016
    Return-Path:
    X-Original-To: root
    Delivered-To: root@mail.mysystems.tld
    Received: by mail.mysystems.tld (Postfix, from userid 0)
    id B2465A9C17C6; Mon, 22 Aug 2016 14:43:06 +0200 (CEST)
    From: root@mail.mysystems.tld (Cron Daemon)
    To: root@mail.mysystems.tld
    Subject: Cron /usr/lib/cgi-bin/fbComm.pl
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    X-Cron-Env:
    X-Cron-Env:
    X-Cron-Env:
    X-Cron-Env:
    Message-Id:
    Date: Mon, 22 Aug 2016 14:43:06 +0200 (CEST)

    In der Tabelle aliases habe ich einen Eintrag, der root@mail.mysystems.tld eigentlich nach postmaster@mysystems.tld umleiten sollte, aber das passiert nicht. Ich habe zur Sicherheit in aliases auch Umleitungen von root@localhost, root@localhost.localdomain und root@mysystems.tld nach postmaster@mysystems.tld, aber keine davon greift. Wo macht es Sinn, nach einem Fehler zu suchen?

    Andere Frage:

    Wie wichtig ist es, dass hostname -f das Ergebnis »mail.mysystems.tld« ergibt? Ich arbeite nämlich auf einem virtuellen Server, und da wird bei jedem reboot die Datei /etc/hosts überschrieben.

    Das war der Inhalt von /etc/hosts nachdem ich die Datei gespeichert habe (der Server hat keine IPv6-Adresse):

    —– Beginn der Datei —–
    ff02::1 ip6-allnodes
    ff02::2 ip6-allrouters

    127.0.0.1 mail.mysystems.tld mail localhost.localdomain localhost
    123.45.67.89 mail.mysystems.tld mail localhost.localdomain localhost
    ::1 mail.mysystems.tld mail localhost.localdomain localhost ip6-localhost ip6-loopback
    —– Ende der Datei —–

    Nach dem Reboot sieht /etc/hosts so aus:
    —– Beginn der Datei —–
    ff02::1 ip6-allnodes
    ff02::2 ip6-allrouters

    127.0.0.1 localhost.localdomain localhost mail mail.mysystems.tld
    # Auto-generated hostname. Please do not remove this comment.
    123.45.67.89 mail localhost mail mail.mysystems.tld localhost.localdomain
    ::1 mail.mysystems.tld mail localhost.localdomain localhost ip6-localhost ip6-loopback
    —– Ende der Datei —–

    p.S.: Danke für die TLS-Policies-Antwort!

  • Ein Vorschlag für eine kleine Änderung in /etc/dovecot/dovecot.conf (hinzufügen):
    ### Global Plugins ###
    mail_plugins = quota

    Danach kann man doveadm nutzen um die Quotas bequem ausgeben zu können:
    doveadm quota get -u user@example.de
    Quota name Type Value Limit %
    User quota STORAGE 2336120 3145728 74
    User quota MESSAGE 6941 – 0

  • Erstmal vielen Danke für die Anleitung, Thomas.

    Es hat bei mir fast ein Monat gut gelaufen. Ich habe heute bei einem test herausgefunden. Dass der SMTP client ohne Authentigizierung mit Postfix verbinden und Mail verschicken kann. Hast du eine Idee, wie man es verbessern kann?

    • Hi Tanu,

      wenn der Mailclient auf dem Localhost läuft, muss nicht authentifiziert werden. Das ist Absicht und soll so sein (z.B. für sendende PHP-Scripts etc). Von außerhalb des Server ist eine Authentifizierung zwingend notwendig. Falls trotzdem keine Authentifizierung notwendig sein sollte, (das kann man z.B. hiermit prüfen http://www.mailradar.com/openrelay/) .. ist dein Server falksch konfiguriert. Ich kann dir garantieren, dass diese Anleitung korrekt ist. Vielleicht hast du selbst Änderungen durchgeführt oder dich vertippt?

      LG Thomas

    • Hi Thomas,
      danke für die schnelle Antwort. Ich habe es jetzt geschafft, als ich die Einstellung `permit_mynetworks` für `smtpd_sender_restrictions` in der Datei `master.cf` rausgenommen habe.

      Mein Server läuft auf Amazon AWS.

      Ich habe `postconf -d | grep mynetworks` ausgeführt und kriege zurück:
      mynetworks = 127.0.0.0/8 172.31.16.0/20 [::1]/128 [fe80::]/64

      Hast du Ahnung, warum es so ist. Ich dachte immer, dass `permit_mynetworks` erlaubt nur die Verbindungen von localhost.

      MFG
      Tanu

      • Hi,

        permit_mynetworks erlaubt alles, was in „mynetworks“ definiert, ist, also in deinem Fall:
        – Alle IPs, die mit 127. beginnen, oder
        – … mit 172.31.16 sowie
        – … IPv6-IPs ::1 (localhost und fe80:: (link-local)

        Vermutlich fällt der Client in dein 172.31.16.0/20 -Netz (oder er telefoniert mit einer lokalen IP-Adresse nach außen) – anders ist das nicht zu erklären.

        LG Thomas

      • besten Dank, Thomas!!!!!!

        Ich habe meinen Fehler gefunden. In `mynetworks` habe ich irgendwann (keine Ahnung wann und wieso :)) ) den Eintrag `0.0.0.0/0` hinzugefügt. Das hat alles erklärt.
        Jetzt funktioniert alles super. Ich versuche noch die Sicherheit zu verbessern und den Back-up zu aumatisieren. Dann ist mein Mail-Server ifür produktiven einsatz bereit.

        Weiter so…

        MFG
        Tanu

  • Hallo Thomas,

    ich hänge hier seit einigen Stunden an einem Problem:
    Mails senden: funktioniert
    Mails empfangen: funktioniert laut LOG-Files auch, es werden jedoch keine im Postfach angezeigt

    Ich habe herausgefunden, dass die E-Mails unter /var/mail/{username} gespeichert werden (nicht wie konfiguriert unter /var/vmail/mailboxes/{domain}/{username}

    Ich finde jedoch meinen Fehler nicht, fällt dir evtl. etwas spontan ein?

    Schönen Gruß,
    Philipp

    • Hallo nochmal,

      Fehler gefunden, dumm von mir:
      Mein Hostname war nicht mail.example.com sondern nur example.com und damit kommt Postfix nicht zurecht.

      Gruß,
      Philipp

  • Noch eine Information zu OpenDKIM.
    Opendkim kann die Schlüsselverwaltung auch in der Datenbank ablegen. Es ist meiner Meninung nach weniger sicher für viele Domains den gleichen Key zu verwenden, gerade wenn man mehrere Domains verwendet.

    In /etc/opendkim.conf lassen sich SigningTable und KeyTable auch z.B. in folgendem Format ablegen:
    SigningTable dsn:mysql://USER:PASSWORD@SERVER/DB/table=dkim_signing?keycol=author?datacol=dkim_id
    KeyTable dsn:mysql://USER:PASSWORD@SERVER/DB/table=dkim?keycol=id?datacol=domain_name,selector,private_key

    Weitere Informationen dazu auch unter: https://sourceforge.net/u/brablc/opendkim/ci/master/tree/opendkim/README.SQL

    Die Schlüssel können übrigens auch ganz einfach mit OpenSSL generiert werden.

    openssl genrsa -out mydomain.com.private.pem 1024 -outform PEM
    openssl rsa -in mydomain.com.private.pem -out mydomain.com.public.pem -pubout -outform PEM

  • Wahnsinn! In den 90ern haben wir uns mit sendmail herumgeärgert, dann mit qmail,… aber wenn ich das hier alles lese und mal auf einem Test-Server durcharbeite… das ist ja noch viel schlimmer. Für eine private Mail-Domain völlig unnötig und überladen. Als wenn man mit einem Schützenpanzer zum Einkaufen fährt, weil der Supermarkt mal überfallen wurde… Viele unnötige Scheunentore werden noch mit Web-Interfacen geöffnet. Fehlt nur noch der Tipp mit Plesk als Einfallstor. Also, trotzdem vielen Dank für deine bestimmt große Energie und Zeit, die du hier hereingesteckt hast – kenne das aus den Usenet-Foren noch, aber jeder sollte wissen, ob er so kompliziert einen Mail-Server anlegen möchte. Sorry…

    • Natürlich kann man sich auch in 5 Minuten schnell einen Mailserver zusammenschustern. Der hier ist allerdings flexibel, gut erweiterbar und kommt mit einigen Features, die man gut brauchen kann. Wer mit weniger auskommt, kann immer auch weniger umsetzen. Ich finde das Setup so ganz gut – weniger wäre mir schon zu wenig.

      LG Thomas

      • Natürlich kann man so einen Mailserver *unnötig* mit einer Datenbank und Viren- / Spam-scans (ich hatte seit 25 Jahren keinen Virenscanner übrigens…) aufblasen, was den dann noch viel langsamer macht und etliche Vorabschecks durchführen mit zu viel scharfen relay_checks – man nimmt HELO vorab!, Mails dann noch der Anwender auf seinem PC durchscannt und und und… alles doppelt . Du löscht GNU / Ubuntu-Systemverzeichnisse und nachher wundern sich alle, warum fehlen die Standard-Configs. Aber, das geht viel einfacher und genauso sicher.

  • Hey Thomas,

    erstmal Danke für das super Tutorial! :-)
    Ich hab mir mal die Mühe gemacht und alle Einträge der GitHub-Liste mit den verschiedenen Mailprovidern und deren TLS Policies in dein SQL Schema importiert.

    Hier sind die dazugehörigen 240 Inserts, falls die jemand braucht:
    http://www.file-upload.net/download-11897156/tlspolicies.sql.html

    Grüße,

    Lukas

  • Vielen Dank für die wunderbare Anleitung :) Funktioniert wunderbar. Nur gibt es einen Fehler in deiner SPF Syntax sowie eine Anmerkung.

    setfacl und getfacl kann man zwar installieren sind aber nicht auf allen vservern zu verwenden da man nicht immer die fstab editieren kann und somit die mountpoints mit acl support versehen kann. Diejenigen müssen einfach auf die Gruppenrechte zurückgreifen um die Leserechte zu gewähren.

    v=spf1 … ?all
    es gibt kein ?all sondern nur +all und -all. Alles was vor all steht wird ja sowieso erlaubt von der domain. -all bedeutet das nichts anderes erlaubt wird und +all das alles erlaubt wird. Also sollte hier -all verwendet werden.

    viele Grüße
    Björn G.

    • Hi! Bei der Sache zu SPF muss ich dir widersprechen: Nach RFC 7208 gibt es sehr wohl ein „?all“, welches eine neutrale Einstellung bedeutet: https://tools.ietf.org/html/rfc7208#section-4.6.2

      Ein „-all“ setze ich absichtlich nicht (und gilt auch als best practise, das nicht zu setzen!), weil es damit zu Problemen bei Mailinglists kommen kann. Stattdessen wird die neutrale Einstellung genutzt, sodass der eigene Server in anderen Systemen wegen des vorhandenen SPF-Records aufgewertet wird, ohne dass SPF Ärger macht. Kurz: Ich tue nur so, als würde ich SPF nutzen wollen. In der Praxis bleibt es im Bezug auf Spam nutzlos. Und das ist wie gesagt Absicht, weil es zu viele Gründe gibt, die gegen den ernsthaften Einsatz von SPF sprechen: https://de.wikipedia.org/wiki/Sender_Policy_Framework#Probleme_bei_Mail-Umleitung ff.

      LG Thomas

      • Ok da habe ich nicht in die offiziellen Dokumente geschaut.

        Noch eine Verbesserung. Ich bekomme gerade täglich E-Mails von meinem Cronjob das die DH Parameter neu generiert wurden. Das nervt und liegt daran das openssl standardmäßig auf die stderr die Benutzerausgabe schreibt und ein Cron schreibt dann eine Mail wenn auf der was ankommt.

        Diese Zeile wäre besser:
        @daily FILE=`mktemp` ; openssl dhparam 2048 -out $FILE > /var/log/dhgenerate.log 2>&1 && mv -f $FILE /etc/myssl/dh2048.pem

        Das Logfile kann natürlich auch weggelassen werden.

  • Hubert Schölnast

    Wie wichtig ist es, dass `hostname -f` das Ergebnis »mail.mysystems.tld« ergibt?

    Ich arbeite nämlich auf einem virtuellen Server, und da wird bei jedem reboot die Datei /etc/hosts überschrieben. Ich verstehe ohnehin nicht, warum ich /etc/hosts überhaupt verändern soll. Weder eingehende noch ausgehende E-Mail werden, soweit ich das verstehe, irgendwie von /etc/hosts beeinflusst. Diese Datei ist doch nur relevant, wenn lokale Prozesse z.B. die Adresse mail.mysystem.tld auflösen wollen. Wenn diese Adresse nicht in /etc/hosts zu finden ist, wird die Adresse wie jede andere auch via DNS aufgelöst. Also ist der Eintrag meinem Verständnis nach völlig unnötig.
    Aber selbst wenn er wichtig wäre: Warum muss er so in /etc/hosts eingetragen werden (nämlich als erster Name in der Liste der Namen hinter der IP-Adresse meines Servers), dass `hostname -f` später genau mail.mysystem.tld auswirft? Wenn der Grund einfach nur der Befehl
    echo $(hostname -f) > /etc/mailname
    ist, dann geht das stattdessen auch recht einfach mit
    echo mail.mysystem.tld > /etc/mailname

    Oder sehe ich da etwas falsch?

  • Hey Thomas
    Danke für diese tolle, klare Erklärung. Genau sowas habe ich gebraucht.
    Alles funktioniert bei mir super. Ich habe aber ein Problem:
    @Daniel hat oben erwähnt, dass er Problem beim Absenden von Mails an google und yahoo hat. Das Problem habe ich auch. Ich bezweifle, es liegt an tslpolicy Tabelle an. Da jede Mail Anbieter die ich in dieser Tabelle definiert habe, kann kein Mails von mir bekommen. Ich bekommen immer ein (von Google zB.) „Undelivered Mail Returned to Sender“ mit The mail system
    : host googmail.com[109.201.135.34] refused to talk to me: 421 Downstream server error“. Und von yahoo: „The mail system : TLS is required, but was not offered by host mx-eu.mail.am0.yahoodns.net[188.125.69.79]“.
    Die Mail Log-Files sagen:
    TLS is required, but was not offered by host mx-eu.mail.am0.yahoodns.net[188.125.69.79]
    TLS is required, but was not offered by host googmail.com[109.201.135.34]
    GIbt etwas falsh an meine tslpolicy Tabelle die ich korrigieren soll? oder soll ich einfach für yahoo.de die „dane“ statt vom „secure“ benutzen?

    Danke im Voraus.

    • Anscheinend sind die Policies für Google und Yahoo fehlerhaft, denn dein Server kann sich aus irgendwelchen Gründen nicht verschlüsselt zu ihnen verbinden. Du könntest die Einträge entfernen oder einfach ein anderes Sicherheitslevel ausprobieren (bzw TLS ganz abschalten). Aber eigentlich sollten Yahoo und vor allem Google TLS sprechen. Irgendetwas stimmt nicht. Bei mir funktioniert das …

      LG Thomas

  • warum genügt die von dovecot vorgegebene cipher list nicht?
    ssl_cipher_list = ALL:!LOW:!SSLv2:!EXP:!aNULL

  • Danke für diesen Artikel, einer der Besten zu diesem Thema, die es gibt.
    Offenbar scheint es updates.spamassassin.org bzw. spamassassin.org nicht mehr zu geben. Ich glaube die sind nach spamassassin.apache.org umgezogen.

  • Funktioniert super nur 2 probleme:

    1. Error bei spamassasin ->
    cat /usr/share/doc/spamassassin/sql/bayes_mysql.sql | mysql -u root -p spamassassin
    Enter password:
    ERROR 1071 (42000) at line 16: Specified key was too long; max key length is 767 bytes
    2.Error beim opendkim ->
    opendkim-genkey –selector=key1 –bits=2048 –directory=keys
    Cloudflare nimmt den key nur ohne die leerzeilen/zeichen an.

  • Hallo Thomas, ich war erfreut über diese Anleitung, weil ich über meinen Server bisher doch sehr viel Schrott bekommen habe ;)
    Allerdings musste ich ordentlich basteln, bis alles einwanfrei lief. Zum ersten verwende ich (noch) ubuntu 14.04 was etwas hinterlich war, weil alle systemctl befehle nicht gehen und ich keinen systmd dienst einrichten konnte – das von dir verlinkte startscript braucht mir leider auch keine besserung- hier dinge die ich noch machen musste:
    ich installierte amavis-milter aus den paketquellen und musste unter /etc/default/amavisd-milter die beiden letzten zeilen und die für die den postfix socket entkommentieren. weiterhin war der amavis nutzer bei mir nicht zu brauchen,, ständig wurde nach den passwort gefragt(obwohl keins gesetzt) oder er konnte keien befehle ausführen wie den amavis-milter dienst starten…. … naja jetzt schneit es zu gehen und ich bin erstaunt wieviele anfragen mein server von blacklist-ips bekommt, und wieviele relay anfragen ich bekomme …
    eine frage habe ich allerdings noch – can die alias funktion auch „halbe“ catchalls ? und kann man Ausnahmen definieren ?
    beispielsweise *****_nutzer1@example.com->nutzer1@example.com und als Ausnahme: idiot_nutzer1@example.com taucht auf spamlisten auf, möchte sie blockiere als gäbe es keinen nutzer/catchall mehr ?

  • Hallo Thomas!

    Ich habe da Mal ein paar (hoffentlich) nicht allzu dumme Fragen zu „Spam“:

    Kann ich in der dovecot.conf den Special-Folder den Du dort „Spam“ nennst einfach „Junk-E-Mail“ nennen, oder muss ich diese Namensänderungen auch noch an anderen Stellen durchführen geben?

    Wenn ich Spam in den Ordner „Spam“ verschiebe wird ja der Assassin trainiert. Wenn ich die Mail nun „lösche“ wird sie ja in den Papierkorb geschoben. Wird die Mail dadurch wieder „de-trainiert“ (als ham behandelt)? Oder sorgt die Angabe „antispam_trash = Trash“ dafür das ein Verschieben von Spam nach Trash den ham nicht auslöst?

    • Hi Mabuse,

      den Spam-Ordner kannst du einfach in „Junk“ oder etwas anderes umbenennen, indem du diese Zeilen entsprechend anpasst, z.B.:

      mailbox Junkmail {
      auto = subscribe
      special_use = \Junk
      }

      Mails, die du wieder in den Papierkorb zurückverschiebst, werden _nicht_ „unlearned“, d.h. sie bleiben nach wie vor als Spam erkannt. Etwas anderes ist es, wenn du eine Mail aus dem Spamordner in einen anderen verschiebst: Dann wird die „Spam“-Markierung wieder aufgehoben.

      Oder sorgt die Angabe „antispam_trash = Trash“ dafür das ein Verschieben von Spam nach Trash den ham nicht auslöst?

      Genau so ist es.

      LG Thomas

  • Hallo Thomas,

    herzlichen Dank für die super Anleitung!!! Endlich habe ich auch meinen eigenen Email-Server ;-)

    Da ich mit meinem Server jetzt 3 mal hintereinander umziehen mußte, ist mir eine Kleinigkeit aufgefallen: Warum hast Du denn in der Postfix main.cf den Parameter „inet_interfaces“ angegeben? Wenn man ihn wegläßt, hört der Server standardmäßig auf allen Interfaces und man muss beim Umzug des Servers, bzw. Änderung der IP-Adresse nicht daran denken an der Stelle die Konfiguration anzupassen (was ich natürlich 3x vergessen hatte…)

    Und noch ein Hinweis aus dieser Umzugserfahrung: Wenn man das ganze mit rsync macht und eine (Standard-) Exclude-Liste verwendet, die „tmp“ beinhält und somit ausschließt, dann werden auch die tmp-Verzeichnisse in jedem Unterverzeichnis einer jeden Mailbox nicht mitkopiert. Fehlen diese allerdings, kann postfix keine Emails mehr in diese Verzeichnisse kopieren. Das schließt leider auch die Inbox ein, womit überhaupt kein Email-Empfang mehr möglich ist. Postfix legt die leider beim Start nicht von selbst an…

    Dagegen kann man wahrscheinlich nichts tun, außer halt beim Server-Umzug darauf zu achten die tmp-Verzeichnisse nicht auszuschließen, denn sonst muss man sie alle von Hand wieder anlegen.

    Ich wollte das nur als Erfahrung weiter geben.

    LG Tom

  • Hallo Thomas,
    ich habe mir einen neuen querry für die aliasabfragen geschrieben um auch sog. „catch all“ postfächer abbilden zu können.

    select concat(destination_username, ‚@‘ ,destination_domain),source_username from aliases where source_username = ‚%u‘ and source_domain = ‚%d‘ and enabled = true or source_username = ‚*‘ and source_domain = ‚%d‘ and enabled=true and 1 > (select count(id) from aliases where source_username = ‚%u‘ and source_domain = ‚%d‘) and 0 = (select count(id) from accounts where accounts.username = ‚%u‘ and accounts.domain = ‚%d‘);

    Voraussetzungen dafur sind: Alias mit * als Username und passender Domain und Postfach an das die Email gehen sollen.
    Solte ein Alias oder Mailbox für die Domain mit dem passenden Username bestehen wird die catch all Regelung ignoriert.

    • die Query funktioniert bei mir leider nicht.
      Die Mails werden zwar zugestellt, aber der Absender bekommt eine Fehler-Mail…

  • Moin Moin,

    eine sehr hilfreiche Anleitung! Danke dafür.

    Ich habe noch mal eine Frage wie könnte man an bestimmte EMails automatisch einen Signatur/Disclaimer anhängen? Amavis kann dies ja so nicht.

    Ich habe alterMIME gefunden, damit soll es möglich sein…. aber leider noch keinen Anleitung gesehen die zu dieser Konfiguration passt

  • Sehr gute anleitung, vielen dank dafür!!!!

    Nur noch ein frage. Bei mir klappt nicht mit „DKIM-Signierung mit OpenDKIM einrichten“. DNS-Records mit generierte key. Wenn ich versuche TXT DNS Record zu erstellen (direkt bei Provider) da kommt so ein fehler : Invalid characters in TXT data.

    Wo kann problemme sein?

    Danke.

    • was genau gibst du den in das eingabe feld ein? Bei welchem Anbieter bist du?

      deine eingabe solte umgefähr so aussehen, mit allen “

      „v=DKIM1; k=rsa; “ „p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn+K9kOLC5IyOdyI/qdimH/Y6HOo2OTyZT75LbDiSCnjp0AuqkVtU3zaHllxFqsbBeRLGcYu+Rgw1gTqVZNFRzTptMRbrAc9YdnlyLTdTB9/hRvFOznaAQA7skav9n24nO3vmW0k0n4El0nkSCl2AXT/CCAhdmrm+sTkJz2LkpXICh4NNsLTOmxZOuhFuXt0J1FfoqCK1oxHyOm“ „GYzUblPbS7aynGplGD1CcBl76PN6FHOiuRH//nevmpCcq4gaaS99xxhobLEI1pMYoP55gkc3plTsgOCZcN1d+il0DX5ME15r/1PJAWiniR/IQcCl2Lr2bS0/m0tzMb4y3BR7narwIDAQAB“

      • bin bei contabo.de, habe da vserver. beim eintragen von diese key kommt fehlermeldung “ Invalid characters in TXT data.“

        • Ich musste sehen was du in das Feld eingibs. Sonst kann ich dir nicht sagen on du unglültige zeichen verwendest, wie z.B. “ anstad “ oder “ anstad „

          • Da hat es mir die zeichen zerschossen. Guck am besteb mal mit notepad++ ob deine anfürhungzeichen auch wirklich welche sind. das ist mir zumindest schon ein paar mal beim Copy/Pasten passiert

            • Hab geguckt in notepad++ alles mit obere Anführungszeichen , bei DNS-Record nimmt der die Anführungszeichen nicht. ohne Anführungszeichen funktioniert aber. Ich weiß nun nicht ob das auch akzeptabel ist so zu verwenden.

              da ist key was ich einfüge:
              „v=DKIM1; k=rsa; “
              „p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoziQxMVw8FSn0h5cTx/4XOObQgy60weX9QizW4quLUfrovLliuWPUVpD+xqd6CGvBlLf8ETR8UCT8bZFuI30QuuZZWomcjQpGY8VDu+FiPGQWMrS1me9MMah56I5SGydHJ3Pi99XgxFhsO4knCa9/JNMu091I8xjHaUuQL4li7HKTgt3WcHSB0bX+dVh2QaAvxrdwbU75klV7U“
              „niUtGWNp+xlA4NNqjm3R3Q/nRRe3iuoNCjoc59A0CGrdADK5pgETtwDC+b1O8BUVhZZ3totHrUPlveSo5OoNQSx7pCpPCBD06dw47caEdPIlX2lrOXTDMEk0vP+ykzqjJWB2vOowIDAQAB“

              der geht aber nicht, :( wenn ich Anführungszeichen weg nehme dann geht. ist das Probleme bei Provider? oder….

  • Sebastian Wiesendahl

    Danke für die ausführliche Anleitung!

    Da ich folgendes in meiner syslog hatte,

    Sep 21 18:23:01 mail named[1156]: network unreachable resolving ’smtp.***.mx/A/IN‘: 2400:cb00:2049:1::adf5:3a66#53
    Sep 21 18:23:01 mail postfix/smtpd[6065]: warning: hostname smtp.***.mx does not resolve to address 78.138.117.225: Temporary failure in name resolution
    Sep 21 18:23:01 mail postfix/smtpd[6065]: connect from unknown[78.138.117.225]
    Sep 21 18:23:01 mail postfix/smtpd[6065]: NOQUEUE: reject: RCPT from unknown[78.138.117.225]: 450 4.7.25 Client host rejected: cannot find your hostname, [78.138.117.225]; from= to= proto=ESMTP helo=
    Sep 21 18:23:01 mail postfix/smtpd[6065]: disconnect from unknown[78.138.117.225] ehlo=2 starttls=1 mail=1 rcpt=0/1 quit=1 commands=5/6

    habe ich auch die /etc/postfix/main.cf ein wenig angepasst:

    ### 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

    Auch fand ich den Tipp von Tom „inet_interfaces“ aus der main.cf herauszunehmen hilfreich, da meine IPv6 Adresse von postfix nicht akzeptiert wurde.

  • Hallo, gutes Tutorial,

    allerdings habe ich das Problem, dass ich nicht so recht verstehe, bzw. weiß wie ich die DNS und MX Einträge bei 1und1 ändern kann.
    Hat diesbezüglich schonmal jemand Erfahrungen machen können, geschweige denn es zum laufen gebracht.

    VG

  • Hallo Thomas,

    Echt Klasse Anleitung. Endlich Mails die nicht mehr in Spam gehen bei Gmail, Outlook usw…

    Nun habe ich aber noch ein kleines Problem, welches ich auch ohne Internet nicht lösen konnte.

    Ich kann eine Mail auf eine bestehende Mail Adresse senden, diese wird mir aber nicht zu gestellt.

    Im Log habe ich folgendes gefunden:
    Client host rejected: Server configuration error;

    Ich erhalte aber vom Server auch keine Fehlermeldung zurück.

    Kannst du mir helfen?

    Gruss flavio

    • Hallo Flavio,

      offenbar ist eine Konfigurationsdatei fehlerhaft. Welche das ist (und an welcher Stelle ein Fehler auftzritt) sollte eigentlich aus dem Mail-Log auslesbar sein. Die Fehlermeldung „Client host rejected: Server configuration error;“ ist leider maximal generisch und lässt auf keinen konkreten Fehler schließen. Sieh am besten nochmal das komplette Log an und suche nach weiteren Meldungen, die auf eine fehlerhafte Config schließen lassen. Ohne mehr Details kann ich dir gerade leider nicht weiterhelfen.

      Alles weitere bitte an mailserver [ett] thomas-leister.de

      LG Thomas

      • Hallo Thomas,

        Danke für deine Antwort. Ich habe nun den Fehler gefunden. Habe auf meiner Firewall alle Ports geschlossen gehabt. Ausser Port 143,587,22.

        Damit es nun doch funktionierte, musste ich den SMTP Port 25 noch öffnen.

        Gruss Flavio

  • Hallo Thomas,

    super Anleitung! Bisher hat alles geklappt – hab den Server noch im Testbetrieb, weil ich eine bestehende sendmail Infrastruktur auf meinem alten Server habe, die ich umziehen muss. Das will gut vorbereitet sein…

    Dort habe ich auch einige Mailman-Mailinglisten laufen.

    Diese werden ja über entsprechende Pipes in /etc/aliases angebunden.

    Wie mache ich das denn mit diesem MySQL Setup? Ist ein Mischbetrieb
    mit /etc/aliases Einträgen möglich? Oder muss wirklich alles in die MySQL?

    Vielen Dank!

    Grüße,

    Jörn

    • Hallo Jörn,

      aus dem Bauch heraus: ja, ein Mischbetrieb sollte möglich sein. Details kann ich Dir dazu aber nicht nennen.

      LG Thomas

    • In meiner /etc/postfix/main.cf habe ich folgenden Eintrag ergänzt:
      alias_maps = hash:/etc/aliases

      Und in meiner /etc/aliases sieht es ungefähr so aus:
      root: meine@mailadresse.de
      www-data: root

      Das zumindest funktioniert bei mir sehr gut. Wenn nun lokale Benutzer wie der www-data z.B. aus Cronjobs heraus lokal Mail zugestellt bekommen, dann landet diese auch im „echten“ Postfach.

      Durch den ersten Eintrag sind auch die Warnungen vom Postfix zu NIS-Domains verschwunden („warning: dict_nis_init: NIS domain name not set – NIS lookups disabled“).

  • Hallo Thomas,

    ich bekomme seit neustem immer den folgenden Fehler bei der Ausführung des Spamassassin-Cron:

    /root/sa-care.sh: channel: could not find working mirror, channel failed

    Info zur Datei:

    -rwxr–r– 1 root root 119 Aug 31 00:27 sa-care.sh

    Crontab-Eintrag:

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

    Inhalt der sa-care.sh exakt so wie oben im Tutorial angegeben. Irgendwelche Ideen? Bei manueller Ausführung via /root/sa-care.sh im Terminal kommen keinerlei Fehler.

    Grüße & Vielen Dank!

    Lukas

  • Hi Thomas,
    super Tutorial!!!
    Hast du Erfahrungen mit Sogo? Wie würdest du dein System an Sogo und imapproxy anbinden? Wie würdest du vorgehen wenn du die authentication nicht über mysql sondern über ldap machen würdest? Würdest du das überhaupt machen?
    Danke und lG,

  • Hallo Thomas,

    eine TOP Anleitung. Nach einem totalen Ausfall bei upgrade unter ubuntu bin ich auf diese Anleitung umgestiegen und habe alles auf Dovecot geswitcht nachdem ich mit SASL zu viel Terror hatte.

    Jetzt zu meiner Frage: Ich habe das Problem das bei der Namensauflösung zuerst immer ipv6 gewählt wird und ich dadurch elend lange Wartezeiten (bis zu timeouts) habe. Dieses Problem habe ich erst seitdem ich: einen AAAA Record und einen PTR Record erstellt habe um auch an Gmail etc senden zu können. Ich dachte nun es würde reichen in der dovecot.conf die directive listen = *, :: anzugeben. Irgendwie habe ich aber immer noch das Problem der langsamen Namensauflösung (mit telnet auf 143 probiert (einmal Name, einmal ip Adresse)). Braucht es auch noch einen speziellen Eintrag für den MX in Richtung ipv6? Stehe hier irgendwie auf dem Schlauch.

    Was Postfix angeht habe ich keine Änderung vorgenommen da ich bei Hetzner auf einem CX Server bin der die NAT Thematik hat.

    Ich würde mich über einen Tip von Dir oder jemand anderem Erfahrenen hier sehr freuen.

    Vielen Dank,
    David

  • Hallo,
    tolle Anleitung, vielen Dank dafür.
    Wie könnte man in diese Konfiguration noch einen Autoresponder einfließen lassen? Und lässt sich der Spamschutz vielleicht per User oder per Domain aktivieren/deaktivieren?

  • Hallo,
    Ich habe ein Problem:
    Ich kann mich nicht einloggen aber der Login wird in der Logs Datei angezeigt.
    Das Foto: https://rettlsteiner.net/download/error.PNG
    Wenn ihr eine Lösung findet währe ich dankbar!

  • Sehr gute Anleitung! Seit einigen Monaten betreibe ich danach einen Mailserver mit mehreren Domains und Postfächern.

    Mir ist jetzt aufgefallen, dass diverse Einträge in den Logs sind wie
    „postfix/smtp[]: warning: table „mysql:/etc/postfix/sql/tls-policy.cf“: empty lookup result for: „gmx.net“ — ignored“
    obwohl es einen passenden Eintrag in der tlspolicies Tabelle gibt. Hat jemand eine Idee?

    • wie sieht den dieser eintrag aus wenn ich mal fragen dürfte? Hast du die entsprechende match role auf gmx angepasst. Denn ich kann den Fehler bei mir nicht reproduzieren.

        • Das liegt daran, daß in diesem Gist die leeren „params“ tatsächlich mit einem leeren String “ belegt wurden, anstatt auf null gesetzt zu werden.

          Mach Folgendes in der DB, dann klappt ’s auch mit dem Nachbarn ;)

          mysql> UPDATE tlspolicies SET params = null WHERE params = “;

          • Habe das Problem auch, das füllen mit NULL hat nur zum Teil geholfen. Das hat zwar die oben angegebene Fehlermeldung beseitigt, ich habe aber immer noch:

            postfix/smtp[30624]: warning: TLS policy lookup for gmx.de/mx01.emig.gmx.net: non DNSSEC destination

            Stimmt da was mit der Policy ‚dane-only‘ aus der git-Liste nicht?

            • Ich hab das Problem auch. Ich bin mir ziemlich sicher, dass es daran liegt, dass für meine Domain selbst kein DNSSEC Eintrag hinterlegt ist (wird von meinem Provider z.Z. nicht unterstützt). Also GMX, Posteo, usw. unterstützen schon DANE, aber deine eigenen DNS Einträge müssen auch einen entsprechenden „DS Record“ haben. Kannst du prüfen mit „host -t ds „. Bei mir kommt halt “ has no DS record“.
              So lange das nicht funktioniert, muss man halt die tlspolicies von „dane-only“ auf „dane“ heruntersetzen. DANE wird dann quasi erst benutzt, wenn du den DS Record für deine Domain hast.

  • Hallo Thomas,
    Ich bin am verzweifeln. Ich habe nun einen Mailserver eingerichtet nach deiner Anleitung. Das Senden von E-Mails und einloggen per imap funktioniert. Habe auch den Client roundcube installiert und da funktioniert das login ebenfalls. Nur werden keine E-Mails empfangen, wenn ich von meinem Gmail-Account oder anderem Account eine E-Mail an einem User von meinem Mailserver sende. Das Senden und empfangen funktioniert nur zwischen zwei User die auf dem Mailserver registriert sind (Gleiche domain). Im Syslog finde ich nichts ob eine Mail blockiert wird vom Server. Es wird mir nichts angezeigt.

    Woran könnte dies liegen? Hast du eine Idee was ich prüfen kann?

    • Habe noch das Login mit Outlook getestet. Dies schlägt fehl. Wenn ich mit http://www.yougetsignal.com/tools/open-ports/ die Ports 25, 587, 143 teste sind diese geschlossen. Auf dem Server sind diese Ports aber offen. Netstat -tulpen liefert dies zurück:
      tcp 0 0 :25 0.0.0.0:* LISTEN 0 31710 2829/master
      tcp 0 0 :587 0.0.0.0:* LISTEN 0 31726 2829/master
      tcp 0 0 0.0.0.0:143 0.0.0.0:* LISTEN 0 33159 2850/dovecot

      Der Server ist ein Virtueller server auf einem Server, der bei Hetzner läuft.

  • Ich denke DMARC könnte man meiner Meinung nach der Anleitung hinzufügen. Gerade für „Hobby-Postmaster“ kann der Report manchmal ein kleiner Lebensretter sein, wenn man etwas an der Konfiguration ändert und vergisst im Zonefile die entsprechenden Änderungen vorzunehmen.
    Hier auch nochmal sauber Zusammengefasst: http://www.nullpointer.at/2014/11/09/domain-based-email-authentifizierung/

  • Ich habe mal eine Frage zur Datenbank:
    In der Tabelle accounts haben wir das Feld sendonly und können damit festlegen, dass der entsprechende Account nur E-Mails versenden darf.

    Gibt es eine Möglichkeit einem Account nur das Empfangen von E-Mails zur erlauben sprich ein Feld receiveonly?

    Oder anders gefragt: Wo kann ich sehen welche Felder man anlegen kann?

    Für eure Hilfe bin ich euch sehr dankbar!

  • Als erstes bekommst Du einen „Daumen hoch“. Da ich seit geraumer Zeit nach einen vernünftig angeleiteten HowTo wie diesem gesucht habe.

    Jedoch hätte ich da ein paar Verbesserungsvorsschläge. Welche sich auf das Anlegen des SystemUserAccount und einbindung in die dovecot.conf beziehen.
    Es soll an diese erwähnt sein das dies kein Ex-Kurs in Unix sein soll, da ich ein gewisses mass an Unix Grundkenntnisse voraussetze. Denn ein solcher Mail-Server kann schnell zu einen Spam- & Virenschleuder werden. Wodurch man sein Server auf allen RBL(XBL), SBL, PBL-Listen, … etc. wiederfindet.

    Erzeugen eines regulären SystemUserAccounts für „vmail“ sollte angestebt werden und nicht das eines invertierten UserAccount zum SystemUserAccount. Welchem man per –disable-login das login entzieht und per -disable-password das Passwort abschaltet. Desweiteren beginnen alle UserAccount ab „ID=1001“ hochgezählt. Und SystemUserAccounts beginnend ab der „ID =101“.

    Also wäre wäre es ratsam das Anlegen des SystemUsers nicht nach
    „adduser –disable-login –disable-password –home /etc/vmail vmail“
    zu erledigen. Sondern wie folgt anzulegen.
    „adduser –system –group –home /etc/vmail mail“
    Mit –system wird der SystemUser erzeugt und definiert.
    Mit –group welches nicht weiter definiert wird, wird automatisch die Gruppe entsprechend angelegt.

    Da ein SystemUserAccount standartmäßig kein „Password“ od. „Login(extern/intern)“ besitzt, könnte die Variablen „–disable-login“ und „–disable-password“ ausgelassen werden. Denn ein nachträgliches zuweisen von Login und Passwort – ist NICHT ohne weiteres möglich.
    Nach dem anlegen des SystemUsers und seiner Gruppe sollte die „UID=UserIdentificationNumber“ und „GID=GroupIdentificationNumber“ Notiert werden. Da diese im späteren Verlauf benötigt werden.

    Desweiteren sollte die Konfiguration von Dovecot „/etc/dovecot/dovcot.conf“ im Abschnitt „Mail location“ wie folgt erweitert werden.

    first_valid_uid = 113 # UID des vmail Systemuser
    last_valid_uid = 113 # UID des vmail Systemuser

    Hierdurch werden keine Fehler und Warnmeldungen durch das nutzen des „vmail“ Users erzeugt.

  • Ich bitte zu entschuldigen für die falsche User & Pfadsetzung im adduser.
    Korrektur::: „adduser –system –group –home /var/vmail vmail“

  • Hallo,

    ich hatte vor ca. 2 Monaten Postfix nach deiner Konfiguration aufgesetzt.

    Da es bei einem Release aus der Quarantäne zu Problemen kam, wandte ich mich an die postfix-users Mailingliste. Das Problem: die Standard-Einstellungen der Amavis im Verzeichnis /etc/amavis/conf.d sorgen dafür, dass Amavis-Milter nicht nur Spam filtert, sondern auch Content. Ein Freund hatte mir im Anhang einer Mail eine unverschlüsselte RAR-Datei gesendet, die eine EXE enthielt. Der Content-Filter von amavis haute, die Mail in die Quarantäne. Über den Befehlt amavis-release konnte ich die Mail aus der Quarantärne holen, jedoch landete sie sofort wieder dort. Dies liegt an den folgenden Dateien im Verzeichnis:

    01-debian
    05-domain_id
    05-node_id
    15-av_scanners
    15-content_filter_mode
    20-debian_defaults
    21-ubuntu_defaults
    25-amavis_helpers
    30-template_localization
    40-policy_banks

    Konkret an den Einstellungen in der Datei „20-debian_defaults“, die für die Content-Filterung sorgt.

    Die Einstellungen, die dann in der „50-user“ vorgenommen werden, überschreiben zwar eventuell vorhandene Einträge in den o. g. Dateien, sorgen aber auch für die Content-Filterung. Ich bin nicht damit unzufrieden, dass auch eine Content-Filterung erfolgt, aber die Zeilen in der „50-user“ Datei sollten angepasst werden, damit es nicht zu einem Loop kommt, und Mails dann wieder aus der Quarantäne geholt werden können:

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

    $notify_method = ’smtp:[127.0.0.1]:25′;

    Zu:

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

    $notify_method = ’smtp:[127.0.0.1]:10025′;

    und in der „master.cf“ im Verzeichnis /etc/postfix der folgende Eintrag hinzugefügt werden:

    # ==========================================================================
    # service type private unpriv chroot wakeup maxproc command + args
    # (yes) (yes) (no) (never) (100)
    # ==========================================================================
    ####
    127.0.0.1:10025 inet n – – – – smtpd
    -o smtpd_milters=

    Nachdem ich diese Einstellungen setzte, funktionierte es dann auch mit dem Release aus der Quarantäne und der erneuten Zustellung der Mail an den Empfänger.

    Gruß

    Andreas

  • Hallo,

    erst einmal Hochachtung für diese gute Anleitung. Wenn Sie noch dmarc enthält, dann wäre das ein Sahnehäubchen. In Deiner postfix Konfiguration gibt es einen Fehler/Unschönheit. Sie wie oben steht, sind auch alle Ciphers erlaubt, die man nicht haben möchte. Ich habe die folgenden Optionen bei mir ergänzt:

    smtp_tls_mandatory_protocols = !SSLv2, !SSLv3
    smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
    smtpd_tls_mandatory_ciphers = high

    Man kann das ganze auch leicht mit nmap prüfen: nmap –script ssl-enum-ciphers -p 587 mail.mysystems.tld -Pn

  • Hallo Michael!

    Danke, für deine Antwort und den entsprechenden Link. Es macht wirklich einen erheblichen Unterschied, was da so passiert, wenn deine Änderungen gesetzt sind.

    Supi!

    Gruß,

    Andreas

  • Hallo,

    erst einmal danke für die super Anleitung!

    wollte mich mit der Adresse einloggen aber ich bekomme diese Fehlermeldung:

    imap(mail@land-laeufer.de): Error: User initialization failed: Namespace “: Mail storage autodetection failed with home=/var/vmail/mailboxes/land-laeufer.de/mail mail_loca
    tion = maildir:~/mail:LAYOUT=fs

    Was ist da falsch?

  • Hallo alle :)
    ich habe ein Problem :(
    Ich bekomme immer wenn ich versuche eine Mail zu versenden diesen Fehler:
    „/etc/opendkim is writeable and owned by uid 117 which is not the executing uid (116) or the superuser“

    Kann mir bitte jemand helfen? :)

    • Ok jetzt hab ichs selbst gelöst :)
      Irgentwie gehörte /etc/opendkim amavis :D
      Nach einem „chmod opendkim /etc/opendkim“ ging das senden auch :)

      BTW: SUUUPER Anleitung! :) Beste die ich finden konnte :)

  • Andere Frage:
    kann ich postfixadmin zur Verwaltung der Mailboxen verwenden?

    Danke im Vorraus :)

  • Hallo,

    ich finde die Anleitung an sich super. Sie hilft sicher vielen, die sich mit der Installation eines Mailservers nicht so gut auskennen und dies gerne lernen möchten (so wie ich).
    Was ich aber zu bemängeln habe ist folgendes:

    In Deiner Anleitung für 14.04 hast Du Dich noch „nur“ auf die Grundinstallation eines Mailservers beschränkt und optionales in einem anderem Beitrag erklärt. Hier hingegen ist man fast schon gezwungen alles möglich mitzuinstallieren, denn weicht man minimal von Deiner Anleitung ab erhöht sich die Fehleranfälligkeit bei der Installation.

    Es gibt ja Leute, die weder eigene DNS-Records setzen können (weil es immer noch Anbieter gibt, die das nicht oder nur gegen Aufpreis zulassen) oder auch Leute die evtl. kein Spamtool haben wollen oder Leute die klein Anfangen und lernen wollen und die optionalen Pakete erst später/bei Bedarf installieren wollen.

    Dennoch: Vielen dank und alles Gute noch.

  • Bekomme folgenden Fehler bei Postfix

    Mai.log:
    Nov 2 10:48:36 marthen postfix/postfix-script[5940]: warning: unable to create missing queue directories
    Nov 2 10:48:36 marthen postfix/postfix-script[5941]: fatal: Postfix integrity check failed!

    mein Server fungiert nicht nur als Mail-Server daher ist der
    hostname =privat
    und Hostname-f = Mydomain.tld ohne den Sub „Mail.“
    alles andere startet nur Postfix will nicht

    die Konfuguration habe ich dementsprechend immer umgeänder sodass „mail.“ von „Mydomain.tld“ wegbleibt.
    Die Records etc habe ich auch demenstrpechen geändert.
    Meine Main.cf: http://pastebin.com/r74YC4Rf

    Habe fast alles was ich bei google gefunden habe ausprobiert und verzweifel so langsam.

    • Keine Ahnung was passiert ist aber 1 Tag später geht es
      kann daran liegen das diesmal länger gedauert hat bist die Domain-Einträge übernommen wurden

  • Das spampipe.sh Skript wird nicht ausgeführt, wenn ich eine Spam-Mail in den Spam-Ordner ziehe?!

  • Super Tutorial!
    Ich habe das ganze Tutorial genommen und ein wenig angepasst, so dass ich mehrere hochverfügbare Mailserver habe, die ich via MX Records anpreise. Jetzt stellt sich mir die Frage wie ich den Mailclients wie Thunderbird oder Outlook begreiflich mache, das ich mehr als einen SMTP Server zur Verfügung habe. Ist hier ha-proxy das richtige Mittel oder gibt es da noch andere Mechanismen um einem Client eine Adresse zur Verfügung zu stellen, wo man eigentlich auf 2,3 oder mehrere Server verteilt wird?

  • hi

    erstmal danke für dieses tut echt stark :)

    nun habe ich aber eine frage und leider wurde ich in google nicht richtig fündig
    und hoffe ihr könnt mir da weiterhelfen

    es geht um quota
    kurz gesagt es wird keine mail versendet wenn das limit erreicht wurde
    User quota STORAGE 41953 31744 132
    User quota MESSAGE 42 – 0

    meine frage fehlt hier etwas?
    quota = maildir:User quota
    quota_exceeded_message = Benutzer %u hat das Speichervolumen überschritten. / User %u has exhausted allowed storage space.

    oder muss eine extra mail angelegt werden wohin dove die nachricht sendet?

    in vielen foren etc. wird oft auf datein hingewiesen in /etc/dovecot/conf.d aber das gibt es hier nicht weil alles in der
    dovecot.conf ist oder

    währe super wenn mir jemand helfen könnte

    vielen dank
    grüße
    andi

  • Hallo Thomas,

    bei mir läuft seit einiger Zeit der Mailserver nach deiner Anleitung für 14.04. Nun habe ich auf 16.04 aktualisiert und würde gerne deine Änderungen im Setup nachvollziehen. Gibt es eine solche Möglichkeit? Wenn ich alles neu aufsetzen muss, wie könnte ich die Anwender und Mailboxen migrieren?

    Liebe Grüße
    Ulf!

    • Hallo Ulf,

      Für eine Migration reicht es aus, sich ein kleines Script zu schreiben, dass das DB-Layout konvertiert (z.B. Sind ja username und Domain im neuen Layout getrennt). Die Daten in der Mailbox an sich sind im gleichen Format…hier hat sich nur der vordere Teil des Pfads geändert. Ich glaube, auch der Sieve-Pfad hat sich geändert. Ansonsten kannst du den Rest der Konfiguration einfach anwenden. Letztendlich geht es ja nur um die Mailbox-Daten und Passwortdaten die erhalten werden müssen.

      LG Thomas

  • Thomas, woran erkenne ich, dass das antispam-Plugin korrekt geladen ist? In den Logs ist für mich nichts ersichtlich und das Skript wird beim Verschieben nach „Spam“ auch nicht ausgeführt (hatte testweise mal ein „date >> /tmp/spampipe.log“ eingefügt).

  • Hallo Herr Leister,

    erst einmal vielen Dank für die in meinen Augen sehr gelungene Anleitung.

    Ich würde dies auch gern umsetzen, möchte aber 2 Server einrichten. Der eine soll die Mails aus dem Internet annehmen und auf Spam, etc prüfen.
    Auf dem zweiten Server sollen die Postfächer und ein Webmailer (bsp. Roundcube) liegen.
    Gibt es für diesen Fall eine Anleitung?
    Grund für die Trennung ist, dass man die eingehenden Mails auf mehrere Mailserver problemlos über DNS (per Round Robin) verteilen kann. Daher wird die Spamsuche, etc auch auf mehrere Server verteilt.
    Es sollten auch schon ein paar Tipps reichen…
    @Jürgen: Ist das nicht das, was Du auch gemacht hast?

    Vielen Dank.

    Viele Grüße Tino

    • Mailserver mit DNS Round Robin Records macht man nicht.
      Google nach: Peer Heinlein – Tipps für stressfreie Mailserver.

      • Hallo Martin,

        danke für Deine Antwort.
        Warum sollte man die annehmende Seite nicht per DNS Round Robin auf verschiedene Server verteilen?
        Die Postfächer sollen ja auf nur einem Mailserver liegen.

        Mein Vorgehen wäre so.
        Ich würde vorerst 2 MX Server einrichten wollen, die die Mails auf Spam und Viren prüfen und nach erfolgreicher Prüfung in das Postfach auf dem Mailserver mit den Postfächern einsortieren.
        Der Mailserver mit den Postfächern wird nicht aus dem Internet erreichbar sein, sodass er nicht von jedem erreicht werden kann, sondern nur von den freigegeben IP Adressen (das LAN).
        So ein Konstrukt ist aus meiner Sicht gut, wenn viel Mailverkehr erwartet wird und die Sicherheit groß geschrieben werden soll.

        Ich werde mich jetzt näher damit beschäftigen und die Anleitung von Thomas Leister als Grundlage nutzen.
        Wenn es gewünscht wird, stelle ich auch meine Anleitung zur Verfügung, falls ich nicht auf unüberwindbare Hürden stoße. :-)

        Viele Grüße
        Tino

        • Servus Tino,

          weil ich gerade dein Anliegen gesehen habe mal was für dich zum nachsehen: Die Verteilung zur Weiterverarbeitung der Mails läuft über LMTP (schau dir ganz oben noch mal das Schaubild an). Hier wird zwar zum Teil über eine lokale Socket die Mails verteilt, aber es geht auch über IP/Ports. Sprich: Der Postfix gibt die Mails weiter an Amavis, SpamAssassin oder schlussendlich auch an Dovecot und dies kann jeweils auch über IP gehen, sodass jeder dieser Dienste auf einem (oder kommt auf das Cluster-Konstrukt an auch mehrere) Server laufen kann. Hierzu musst du nur in den Man-Pages mal die Parameter nachschlagen, die für die Weitergabe der Mails zuständig sind.
          Es ist also somit möglich, dass du mehrere annehmende Postfix-Server bereitest, die dann an einen speziellen Amavis-Server und SpamAssasin-Server erst die Mails zur Prüfung übergeben, bevor diese dann an einen Dovecot-Server übertragen werden. Dieser könnte dann sogar einen separaten Postfix-Server für den Mailausgang verwenden. (In wieweit das ganze Sinn macht, sei mal dahin gestellt und kommt auf jeden Fall auch auf das zu erwartende Auskommen eingehend, wie ausgehend an.)

          Viel Spaß beim Konfigurieren … ;)
          Grüße, Mischa.

  • hi
    wollte fragen ob ihr eine info hättet wie ich da nun auch pop3 hinzufügen kann
    währe sehr nett
    vielen dank
    grüße

  • Hallo,

    dazu fügst du in der Datei „dovecot.conf“ zu den Protokollen einfach pop3 hinzu. Habe ich auch gemacht und es läuft.

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

    protocols = imap pop3 lmtp sieve

    Gruß

    Andreas

  • Hi,

    sehr gute Anleitung, allerdings möchte ich noch ungültige Absender-Adressen im LAN am Versenden von E-Mails hintern:
    Beim Erstellen einer E-Mail mit z.B. Thunderbird kann man eine „benutzerdefinierte Absenderadresse“ eintragen. Egal was hier eingetragen wird, die E-Mail wird von postfix durchgewunken. Das soll natürlich verhindert werden!

    Mit sender_*_map habe ich schon ein paar Versuche angestellt, komme aber nicht weiter, die Mails werden trotzdem akzeptiert. Der %s / %u / %d Parameter scheint immer der eingeloggte User, aber nicht der From:-User zu sein, somit kann man hier auch nicht filtern :(
    Hat jemand eine Idee?

    Danke

    • Ok,

      ich sehe schon, dass das mit Standard-Postfix so erstmal nicht funktioniert. Der angezeigte Absender im MUA (z.B. Thunderbird) ist ja aus dem From: vom Data-Block der E-Mail.
      Der eingeloggt (authentifizierte) User ist im Mail-Envelope/Header ja korrekt gesetzt. Der Empfänger schaut sich kaum den Quelltext der E-Mail an (reply-to,…), was für Otto-Normal-Verbraucher nicht geeignet ist.
      Ich hab mal zum Test einen python Milter programmiert, welcher nachschaut, ob der Envelope/Header-From „“ im Data-From (Display From) enthalten ist „Max Mustermann “ und ansonsten mit 550 Reject abweist. Das funktioniert schon, aber gibt es keine einfachere Möglichkeit?

      Ciao,
      Clemens

    • OK, wir setzen ja OpenDKIM ein, also ist es nicht zwingend notwendig einen eigenen Milter für den Envelope/Display From check zu starten, stattdessen, kann man ja ein LUA SetupPolicyScript in OpenDKIM ausführen.

      #/etc/opendkim.conf

      SetupPolicyScript /etc/opendkim/check_display_from.lua

      #/etc/opendkim/check_display_from.lua
      odkim.log(ctx, „Check Display From LUA script“)
      — mydomains anpassen!
      local mydomains = {„@testnet.local“, „@something.else“}

      local envfrom = odkim.get_envfrom(ctx)
      if envfrom == nil then
      odkim.log(ctx, „Envelope From not set, someone should handle this, exiting OK“)
      return nil
      end

      envfrom = string.lower(envfrom)
      for i=1,#mydomains do
      if string.find(envfrom, string.lower(mydomains[i])) ~= nil then
      odkim.log(ctx, „Envelope From found in mydomains: ‚“ .. envfrom .. „‚“)
      local displayFrom = odkim.get_header(ctx, „From“, 0)
      if displayFrom == nil then
      odkim.log(ctx, „*** Display From header not set, exiting REJECT“)
      odkim.set_result(ctx, SMFIS_REJECT)
      return nil
      end

      displayFrom = string.lower(displayFrom)
      if string.find(displayFrom, envfrom) == nil then
      odkim.log(ctx, „*** Envelope From ‚“ .. envfrom .. „‚ not found in Display From ‚“ .. displayFrom .. „‚, exiting REJECT“)
      odkim.set_result(ctx, SMFIS_REJECT)
      return nil
      end

      odkim.log(ctx, „Display From ‚“ .. displayFrom .. „‚ contains submitted Envelope From ‚“ .. envfrom .. „‚, exiting OK“)
      return nil
      end
      end

      odkim.log(ctx, „Mail not from mydomains, exiting OK“)
      return nil

      Einziges Manko: Wenn man im Display-From keine E-Mail Adresse einträgt, sondern nur einen Namen (Test im Firefox, z.B. „Mein Name ist Hase“), führt OpenDKIM das Script gar nicht erst aus, sondern verabschieded sich gleich und winkt durch:
      syslog: mail opendkim[3633]: E0A4BE3DD5: can’t parse From: header value ‚ Mein Name ist Hase‘
      Aber das kann man im Mail-Client als Otto-Normal noch einfacher erkennen, als erst den Mail-Quelltext anzuschauen.

  • Servus,

    weiß jetzt nicht ob es daran liegt, dass ich nicht Ubuntu, sondern Debian direkt eingesetzt habe, aber mit der SQL-Abfrage zur TLS-Policy hatte ich auch so meine Probleme. Es kam ein leeres Ergebnis zurück.
    Darauf hin habe ich mal in der Postfix-Doku nachgelesen und die Füllvariable %d anstatt %s verwendet. Seit dem geht es.

    Falls hier jemand ähnliche Probleme hat.

    Grüße, Mischa.

  • Hallo Mischa,

    kannst du bitte einen Link zu der Stelle in der relevanten Postfix Doku geben?

    Danke!

    Andreas

    • Servus Andreas,
      bin hier leider nicht so oft auf der Page und hatte auch keine Mail erhalten, drum etwas verspätet die Antwort:

      In der ManPage zu MySQL-Tabellen zu Postfix unter http://www.postfix.org/mysql_table.5.html findet man bei den MySQL Parametern unter „query“ die entsprechenden Variablen beschrieben. Unter anderem %d als einsetzbare Variable, die mit dem Domain-Anteil einer Mail-Adresse (wie in %s) gefüllt wird.

  • Hi,

    die Anleitung ist wirklich gut und funktioniert fast 1:1 auch unter Debian ‚Jessie‘. Ich musste meinen Server zu einigen Updates ‚überreden‘ , die Razor Einstellungen lassen sich nicht über sudo bewerkstelligen (habe das jetzt als root in dem user Verzeichnis gemacht).

    Der Rest ist „Plug and Play“. Also vielen Dank für die Anleitung!

  • Hallo Thomas,

    ich hatte das Problem, dass amavisd-milter (läuft im Kontext von postfix) nicht auf den amavisd-Socket zugreifen konnte. Das habe ich mittels usermod -aG postfix amavis && usermod -aG amavis postfix gefixt.

    Jetzt habe ich noch das Problem, dass Postfix nicht auf den Port 587 reagiert. Mit netstat -tanp sehe ich, dass an meiner Mailadresse auf dem Port 587 von „master“ gelauscht wird. Mittels ufw status sehe ich auch, dass der Port geöffnet ist. Wenn ich ein telnet localhost 587 mache, bekomme ich eine Antwort von Postfix. ein telnet mydomain.tld 587 hingegen führt ins Leere. Jetzt bin ich so langsam ratlos, was ich da noch tun kann…

    Liebe Grüße
    Ulf!

    • Setzt du Ubuntu 16.04 ein?
      Bei mir gings auch erst, nachdem ich aber die letzten Kernelupdates installiert und neugestartet hab, hab ich dasselbe Problem. Wollte mir das jetzt übers Wochenende mal ansehen, Dienste laufen alle.

      • FYI: Bei mir gehts wieder, hatte eigenmächtig an der /etc/postfix/master.cf rumgepfuscht. Dadurch ist postfix scheinbar nicht gestartet. War mir gestern gar nicht aufgefallen

  • Besten Dank, hat beim ersten Versuch gleich funktioniert :)

    Ich hab nur eine offene Frage zum Spamfilter, den Test wie hier vorgeschlagen habe ich gemacht und konnte das auch in den Logs nachvollziehen. Aber sollten Spams nicht eigentlich im IMAP Spam Ordner landen?
    Wegen dem Verhalten hab ich etwas Sorge, eingehende Mails zu „verpassen“, ohne dass ich es mit bekomme.

    Wieso ist das so und kann ich irgendwo Benachrichtigungen für so einen Fall konfigurieren?

    • Je nach Score, wird die Mail entweder abgelehnt oder in den Spam Ordner geschoben. Du kannst diese Werte in /etc/amavis/conf.d/50-user einstellen:
      $sa_tag_level_deflt = -999;
      $sa_tag2_level_deflt = 6.2;
      $sa_kill_level_deflt = 6.9;

      Damit wird der Benutzer informiert, sollte er eine geblockte mail bekommen:
      $warnbannedrecip = 1;

  • Moinsen Thomas,

    Geiles Tut,
    habe es auf anhieb geschafft ^^ Mailserver läuft 1A,

    Nur habe ich derzeit dass problem ich habe eingerichtet mailserver.tld, email1.tld, email2.tld & email3.tld,

    wie schaffe ich es wenn ich z.b. user1@email1.tld in thunderbird verbinde dass mir folgende imap/smtp/pop3 adressen angezeigt werden

    imap.mailserver.tld
    smtp.mailserver.tld
    pop3.mailserver.tld

    oder ggf. auch einfach nur mail.mailserver.tld für alles.

    Mit Freundlichen Grüßen
    Tojon

  • ACHTUNG bei Webmail auf gleichem Server.
    Wenn z.B. Roundcube auf dem gleichen Server läuft können dort die Nutzer zunächst frei Ihren Absender wählen. Einfacher fix wäre deswegen permit_mynetworks in der smtpd_sender_restrictions im submission Bereich der master.cf zu entfernen.
    Ich bin mir aber nicht sicher inwiefern noch andere Restriktionen ausgehebelt werden.

    Deswegen habe ich Roundcube in ein extra IP-Netz gelegt damit es wie ein externer Mail-Client behandelt wird.
    Dazu muss zunächst ein Netz in der der /etc/network/interfaces hinzugefügt bzw. lo angepasst werden.

    auto lo lo:0
    iface lo inet loopback
    # additional loopback ip to make roundcube look like external to postfix
    iface lo:0 inet static
    address 10.123.123.123
    netmask 255.255.255.255

    Ihr solltet mit ping 10.123.123.123 (nach ifup lo:0 wenn kein neustart) eine Antwort erhalten.
    Dann muss in der /etc/postfix/main.cf dem parameter inet_interfaces die Adresse 10.123.123.123 hinzugefügt werden. Nicht aber den mynetworks!

    Wenn ihr nun in Roundcube diese Adresse als smtp tls server auf port 587 konfiguriert geht es allerdings noch nicht. Dummerweise wird nun auch eine korrekte TLS aushandlung mit gültigem Zertifikat gefordert. Ich habe dafür bei meinem DNS Provider den Namen foreign-loopback.domain.tld als zusätzlichen A Record auf meinen Mailserver konfiguriert. Bei unbound ist noch eine Datei/etc/unbound/unbound.conf.d/loopback.conf von nöten:

    server:
    local-zone: „foreign-loopback.domain.tld.“ static
    local-data: „foreign-loopback.domain.tld. 10800 IN NS localhost.“
    local-data: „foreign-loopback.domain.tld. 10800 IN SOA localhost. nobody.invalid. 1 3600 1200 604800 10800“
    local-data: „foreign-loopback.domain.tld. 10800 IN A 10.123.123.123“

    ohne unbound sollte ein Eintrag in /etc/hosts/ für die domain reichen. Nun haben wir erreicht das das Internet unter der subdomain die öffentliche, unser Server aber die private Adresse sieht. Nur so können wir die Adresse zu unserem letsencrypt zertifikat hinzufügen und /etc/roundcube/config.inc.php entsprechend konfigurieren

    $config[’smtp_server‘] = „tls://foreign-loopback.domain.tld“;
    $config[’smtp_port‘] = 587;

    • Warum greifen in diesem Fall eigentlich folgende Einträge in der master.cf nicht?:
      smtpd_sender_restrictions = … reject_sender_login_mismatch und reject_unknown_sender_domain

      So wie ich das gerade sehe, ist zur Zeit beliebiges Adressspoofing durch alle eingeloggten Benutzer möglich.

      Danke für den Hinweis!

      • Okay ich denke das ist ein Problem von Roundcube, wenn ich über Thunderbird eine weitere Identität erstelle und versuche von dieser zu senden erhalte ich korrekterweise folgenden Fehler:
        NOQUEUE: reject: RCPT from unknown[$REMOTEIP]: 553 5.7.1 : Sender address rejected: not owned by user correct@domain.de; from= to= proto=ESMTP helo=

        • Fix in Roundcube config.php:
          /*spoofing protection*/
          $config[‚identities_level‘] = 1;
          /*
          0 – multiple identities with possibility to edit all parameters
          1 – multiple identities with possibility to edit all parameters except email address
          2 – one identity with possibility to edit all parameters
          3 – one identity with possibility to edit all parameters except email address
          4 – one identity with possibility to edit only signature
          */

          ACHTUNG: Bereits gespoofte Adressen können weiterhin benutzt werden, der Fix verhindert lediglich dass das E-Mail Feld durch die Benutzer geändert werden kann.

          • Du beschreibst genau das Problem was ich auch beschrieben habe.
            Roundcube-Config: Ja diese Einstellung ist mir bewusst gewesen. Ich halte es jedoch nicht für richtig die Einschränkungen dem Mail-Client, der nur ein PHP Skript ist zu überlassen. Es geht um mehr als um die Absenderadresse. Diese Einstellung ist hauptsächlich eingebaut damit der Nutzer gar nicht erst den kryptischen SMTP 553 bekommen kann.

            Das Hauptproblem ist das Roundcube die IP 127.0.0.1 hat und damit alles was permit_mynetworks gesetzt hat erlaubt wird. Es darf damit im Prinzip fast alles. Nachfolgende Einschränkungen mit reject_… werden dann nicht mehr evaluiert!
            Genau um die 127.0.0.1 zu umgehen habe ich diesen Fix geschrieben.

  • Hi,
    ich wollte fragen, ob mit jemand villeicht bei einem Problem helfen kann. Ich kann Mails senden und empfangen, außer an web.de und gmx kann ich keine mails senden. Ich kriege nur als Antwort TLS is required, but was not offered by host
    mx-ha03.web.de[212.227.15.17] ich habe in der TLS-policy Tabelle auch schon mit und ohne Einträge probiert. Wenn ich mit Einträge mache kann ich aber glaube an gar keinen Anbieter der aufgelisteten Anbieter senden.
    Weiß einer was da falsche gelaufen ist?
    Vielen Dank für eure Antworten

  • Ai ai ai ai ai das war ne super Nachtschicht zu dem Thema.
    Jetzt nach 4 Stunden endlich durch. – mit wenigen Einschränkungen.

    Also erst einmal echt Lob für das Tutorial.
    An sich bekommt man das schnell abgearbeitet.

    Allerdings folgen danach ein paar Fehler mit der Konfiguration.
    So geht unverschlüsselt gar nichts mehr, außer dass Mails ankommen können.
    Und TLS über den 25er Port für die Clients geht auch nicht mehr.
    Also Clients sind echt nur über 587 möglich per TLS und IMAP geht per SSL.
    Zwecks Problemen hab ich dann noch das SpamHaus entfernt.

    Hab zudem das Ganze noch aufgemotzt indem ich ViMbAdmin installiert hab und die Queries im Dovecot sowie Postfix dann durch deren ausgetauscht hab. So hab ich ein geniales System welches dank dir schön Spamfrei agiert.
    Dank der Admin-GUI kann ich es super einfach administrieren und dank Rainloop hab ich ein hochmodernes Webmail.

    Also top top top!

    Der Mailserver läuft auf einer kostenfreien Amazon EC2 Instanz (kostenloses Freikontingent) und dann eben mit deinem Postfix, Dovecot, Amavis, … + Rainloop + ViMbAdmin + Amazon SES als Relay.

    Wirklich hammer :-D

    • hi Admin (netz-app)
      hast du event. eine anleitung für ViMbAdmin wie du das integriert hast (tut for newbe…)
      währe super
      danke
      grüße
      andi

  • Erst einmal ein großes Lob für die detaillierte Anleitung.
    Mir ist aufgefallen das Benutzer Mails auch unter anderem Absender verschicken können. Egal ob vom gleichen Server oder einer fremden Domain. Getestet im Thunderbird und dem „Benutzerdefinierten Absender“.
    Wie kann man dies unterbinden? Der Benutzer soll ja nur mit seiner Adresse und den dazugehörigen Alias verschicken können.

  • Ich habe noch den schönen Webmailer rainloop hinzugefügt. Hat jemand ein passendes plugin für dieses Setup hier von Thomas, um dem Benutzer unter rainloop zu erlauben, sein eigenes Passwort zu ändern?

  • Hallo Thomas,

    ein wirklich tolles Tutorial. Funktioniert alles super.
    Lediglich den managedsieve bekomm ich nicht zum Laufen.

    Wenn ich den sieve Port 4190 mit gnutls-cli teste erhalte ich folgende Meldung:
    || Received record packet of unknown type 34
    *** Fatal error: An unexpected TLS packet was received.
    *** Handshake has failed
    GnuTLS error: An unexpected TLS packet was received.

  • Gibt es irgend ein Webadministration Panel für diese Konfiguration?

    Währe echt Cool

  • Hallo,
    Erstmal Danke für diesen Artikel.
    Ich habe schon erfolg auf einen virtuellen Server bei DigitalOcean gehabt. Jedoch will ich demnächst einen Mailserver bei meinen echten Server einrichten. Deshalb frage ich mich: Soll der rDNS record „IP – mail.domain.tld“ oder „IP – domain.tld“ heißen? Und könnte ich da eventuell auf irgendwelche Probleme stoßen wenn ich den Aktuellen rDNS Eintrag des Anbieters verändere?
    Ich habe außerdem einige Virtuellen Server auf meine Echten server laufen. Werden diese von dem Ändern des Hostnamens oder der rDNS beeinflusst?
    Hoffentlich können sie mir helfen.
    LG
    Colin

    • Der rDNS Eintrag ist wirklich nur für Mailanwendungen relevant, deshalb mail.domain.tld. Die virtuellen Server sollten deshalb auch nicht davon beeinflusst werden.

      LG

  • Hallo,
    das Problem mit mit dem
    ‚Dec 26 17:18:31 mail amavisd-milter[16226]: ##blabla##: could not connect to amavisd socket /var/run/amavis/amavisd.sock: Connection refused‘
    ist ganz bestimmt nicht behoben. Sitze echt schon seit Stunden an dem Problem. Habe deine Anleitung exakt befolgt.

    • Außerdem kriege ich ständig folgenden Fehler:
      Dec 26 17:17:32 mail amavis[16224]: (!!)TROUBLE in pre_loop_hook: config: no rules were found! Do you need to run ’sa-update‘?
      Dec 26 17:17:32 mail amavis[16224]: (!)_DIE: Suicide () TROUBLE in pre_loop_hook: config: no rules were found! Do you need to run ’sa-update‘?
      sa-update habe ich selbstverständlich schon ausgeführt.

  • Moin,
    ich habe die Anleitung Schritt für Schritt auf einem frisch installierten System nachvollzogen, bei mir klappt leider überhaupt nichts. Den Fehler mit dem amavisd-milter kann ich bestätigen, außerdem kann ich weder E-Mails senden noch empfangen (Als Antwort, wenn ich mit Outlook senden möchte, kommt z.B.:

    „Serverfehler: „450 4.7.25 Client host rejected: cannot find your hostname, [IP von mir daheim]“‚“.

    Empfangen kann ich auch nichts, die Logs sagen dazu folgendes:

    NOQUEUE: reject: RCPT from unknown[209.85.217.177]: 450 4.7.25 Client host rejected: cannot find your hostname

    Habe jetzt nach einiger Sucherei keine brauchbare Lösung gefunden, einzig das Milter-Problem konnte ich mit dem 2-Sekunden-Script von weiter oben lösen…

    Schade, da ich die Anleitung sehr gut geschrieben und erklärt finde. Habe vor einem Jahr die Anleitung mit dem 14.04er befolgt, da hat es nahezu reibungslos geklappt…

  • Vielen Dank für die Anleitung. Hat alles prima geklappt. Den Teil mit den DKIM-DNS-Einträgen mußte ich mehrfach durcharbeiten, bis ich ihn verstanden habe und bei meinem Provider alles richtig eingetragen habe.
    Für Spamassassin mußte ich Port 2703 für ausgehende Verbindungen freischalten. Wäre vielleicht noch gut, alle benutzen Ports aufzulisten.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.