Uncategorized
0

Dovecot und Postfix mit virtuellen Mailboxen einrichten – Teil 2: MariaDB, vmail, LMTP und virtuelle Benutzer

Im ersten Teil dieser Serie haben wir Dovecot mit lokalen Linux-Benutzern eingerichtet. Dabei entsprach jede Mailbox einem echten Benutzer auf dem Linux-System. Für den Einstieg ist das sehr hilfreich, weil man SMTP, IMAP, Maildir und die Authentifizierung gut nachvollziehen kann.

Für einen produktiven Mailserver ist dieses Konzept jedoch nur bedingt geeignet. In der Praxis möchte man nicht für jede E-Mail-Adresse einen eigenen Linux-Benutzer anlegen. Stattdessen werden sogenannte virtuelle Mailboxen verwendet.

In diesem Teil stellen wir den Mailserver daher auf folgende Architektur um:

Postfix


Dovecot LMTP


/var/vmail

Thunderbird


Dovecot IMAP


MariaDB

Am Ende dieses Artikels können virtuelle E-Mail-Konten wie info@example.de verwendet werden, ohne dass dafür ein Linux-Benutzer info existiert.

Ziel des zweiten Teils

Nach diesem Artikel haben wir:

  • virtuelle Mailboxen unter /var/vmail
  • einen eigenen Systembenutzer vmail
  • MariaDB als Benutzerverwaltung
  • Dovecot SQL-Authentifizierung
  • Postfix Virtual Mailbox Domains
  • Zustellung über Dovecot LMTP
  • Anmeldung per Thunderbird mit vollständiger E-Mail-Adresse
  • Unterstützung für virtuelle Aliase

Ausgangssituation

Dieser Artikel baut auf dem ersten Teil auf. Folgende Komponenten sollten bereits vorhanden sein:

  • Debian 13
  • Postfix
  • Dovecot
  • TLS-Zertifikat von Let’s Encrypt
  • funktionierender IMAP-Zugriff
  • funktionierender SMTP-Versand über Submission
  • Dovecot SASL für Postfix

Bisher sieht die Mailzustellung vereinfacht so aus:

Postfix


/home/tobias/Maildir

Dovecot authentifiziert Benutzer über PAM gegen die lokalen Linux-Benutzer:

Dovecot
   │
   ▼
  PAM
   │
   ▼
/etc/shadow

Das ändern wir nun.

Warum virtuelle Mailboxen?

Bei lokalen Linux-Benutzern müsste für jede Mailbox ein eigener Systembenutzer angelegt werden:

tobias
info
support
rechnung

Dazu gehören dann Home-Verzeichnisse, Benutzer-IDs und theoretisch auch Systemzugänge. Für einen Mailserver ist das unpraktisch und unnötig. Mit virtuellen Mailboxen existiert auf dem Linux-System nur noch ein einziger technischer Benutzer. In meinem Fall der Benutzer vmail. Alle Mailboxen liegen dann beispielsweise unter:

/var/vmail/
└── example.de
├── info
│ └── Maildir
├── support
│ └── Maildir
└── rechnung
└── Maildir

Die Benutzer selbst werden nicht mehr in /etc/passwd, sondern in einer Datenbank verwaltet.

MariaDB für virtuelle Benutzer vorbereiten

Zuerst wird eine Datenbank für den Mailserver angelegt. Dazu muss als erstes in die MariaDB-Shell gewechselt werden:

mysql

Dann:

CREATE DATABASE mailserver;

CREATE USER 'mailuser'@'localhost'
IDENTIFIED BY 'EinSehrLangesPasswort';

GRANT ALL PRIVILEGES
ON mailserver.*
TO 'mailuser'@'localhost';

FLUSH PRIVILEGES;
EXIT;

Der Benutzer mailuser wird später von Postfix und Dovecot verwendet, um Domains, Mailboxen und Aliase abzufragen.

Tabellen für Domains, Benutzer und Aliase anlegen

Nun werden die Tabellen erstellt.

mysql mailserver

Tabelle für virtuelle Domains

CREATE TABLE virtual_domains (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY name (name)
);

Diese Tabelle enthält alle Domains, für die der Server E-Mails annehmen soll.

Beispiel:

INSERT INTO virtual_domains
(name)
VALUES
('example.de');

Prüfen:

SELECT * FROM virtual_domains;

Tabelle für virtuelle Benutzer

CREATE TABLE virtual_users (
id INT NOT NULL AUTO_INCREMENT,
domain_id INT NOT NULL,
email VARCHAR(255) NOT NULL,
password VARCHAR(255) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY email (email)
);

Diese Tabelle enthält die eigentlichen Mailboxen.

Beispiele:

info@example.de
support@example.de
rechnung@example.de

Tabelle für virtuelle Aliase

CREATE TABLE virtual_aliases (
id INT NOT NULL AUTO_INCREMENT,
domain_id INT NOT NULL,
source VARCHAR(255) NOT NULL,
destination VARCHAR(255) NOT NULL,
PRIMARY KEY (id)
);

Aliase besitzen kein eigenes Postfach. Sie leiten E-Mails nur an eine andere Adresse weiter.

Beispiel:

support@example.de → info@example.de

Passwort-Hash für Dovecot erzeugen

Dovecot speichert Passwörter nicht im Klartext. Wir erzeugen daher einen Hash:

doveadm pw -s BLF-CRYPT

Dovecot fragt nun nach einem Passwort und gibt anschließend einen Hash aus:

{BLF-CRYPT}$2y$05$....

Diesen Hash kopieren wir.

Erste virtuelle Mailbox anlegen

Angenommen, die Domain hat die ID 1.

INSERT INTO virtual_users
(domain_id,email,password)
VALUES
(
1,
'info@example.de',
'{BLF-CRYPT}$2y$05$....'
);

Prüfen:

SELECT id,email FROM virtual_users;

Damit existiert die Mailbox bereits in der Datenbank. Auf dem Linux-System wurde dafür aber kein Benutzer info angelegt.

vmail-Systembenutzer anlegen

Alle virtuellen Mailboxen sollen einem einzigen technischen Benutzer gehören.

groupadd -g 5000 vmail
useradd \
-u 5000 \
-g vmail \
-d /var/vmail \
-m \
-s /usr/sbin/nologin \
vmail

Prüfen:

id vmail

Die Ausgabe sollte ungefähr so aussehen:

uid=5000(vmail) gid=5000(vmail) Gruppen=5000(vmail)

Das Login-Shell ist bewusst auf nologin gesetzt. Der Benutzer vmail soll sich nicht am System anmelden können.

Mailverzeichnis vorbereiten

mkdir -p /var/vmail
chown -R vmail:vmail /var/vmail

Für unsere erste Mailbox legen wir die Struktur an:

mkdir -p /var/vmail/example.de/info/Maildir/{cur,new,tmp}
chown -R vmail:vmail /var/vmail/example.de

Prüfen:

tree /var/vmail

Die Struktur sollte so aussehen:

/var/vmail
└── example.de
└── info
└── Maildir
├── cur
├── new
└── tmp

Dovecot SQL-Modul installieren

Damit Dovecot MariaDB verwenden kann, wird das SQL-Modul benötigt:

apt install dovecot-mysql

Dovecot SQL-Authentifizierung einrichten

In Dovecot 2.4 wird die SQL-Konfiguration direkt in der Auth-Datei definiert.

Datei öffnen:

nano /etc/dovecot/conf.d/auth-sql.conf.ext

Inhalt:

sql_driver = mysql

mysql 127.0.0.1 {
user = mailuser
password = EinSehrLangesPasswort
dbname = mailserver
}

passdb sql {
query = SELECT email AS user, password FROM virtual_users WHERE email = '%{user}'
default_password_scheme = BLF-CRYPT
}

userdb static {
fields {
uid = vmail
gid = vmail
home = /var/vmail/%{user | domain}/%{user | username}
}
}

Was passiert hier?

sql_driver

sql_driver = mysql

Dovecot verwendet MariaDB/MySQL als Datenquelle.

passdb sql

passdb sql {
query = SELECT email AS user, password FROM virtual_users WHERE email = '%{user}'
}

Dovecot sucht bei der Anmeldung nach der vollständigen E-Mail-Adresse. Wenn sich also info@example.de anmeldet, wird folgender Benutzer gesucht:

info@example.de

userdb static

userdb static {
fields {
uid = vmail
gid = vmail
home = /var/vmail/%{user | domain}/%{user | username}
}
}

Alle virtuellen Benutzer verwenden denselben Linux-Benutzer vmail. Für info@example.de ergibt sich daraus:

/var/vmail/example.de/info

SQL-Authentifizierung zusätzlich aktivieren

Jetzt wird SQL in Dovecot eingebunden.

Datei öffnen:

nano /etc/dovecot/conf.d/10-auth.conf

Dort befindet sich aktuell meist:

!include auth-system.conf.ext

Für den Übergang kann SQL zunächst zusätzlich aktiviert werden:

!include auth-system.conf.ext
!include auth-sql.conf.ext

Dadurch funktionieren sowohl lokale Linux-Benutzer als auch virtuelle Benutzer. Später kann auth-system.conf.ext entfernt werden, wenn ausschließlich virtuelle Mailboxen verwendet werden sollen.

Dovecot-Konfiguration prüfen

Vor dem Neustart sollte die Konfiguration geprüft werden:

dovecot -n

Wenn keine Fehler angezeigt werden:

systemctl restart dovecot

SQL-Login testen

Jetzt testen wir die Authentifizierung:

doveadm auth test info@example.de PASSWORT

Bei Erfolg erscheint:

passdb: info@example.de auth succeeded
extra fields:
user=info@example.de

Zusätzlich prüfen wir, wie Dovecot den Benutzer auflöst:

doveadm user info@example.de

Erwartet wird ungefähr:

field     value
uid 5000
gid 5000
home /var/vmail/example.de/info
mail_path /var/vmail/example.de/info/Maildir

Damit weiß Dovecot:

  • Benutzer existiert
  • Passwort ist korrekt
  • Mailbox liegt unter /var/vmail
  • Besitzer ist vmail

LMTP verstehen

Bisher konnte Postfix Mails selbst direkt in ein Maildir schreiben. Bei virtuellen Mailboxen soll aber Dovecot die Zustellung übernehmen. Dafür verwenden wir LMTP.

Der neue Weg lautet:

Internet


Postfix


Dovecot LMTP


/var/vmail/example.de/info/Maildir

Der Vorteil:

  • Dovecot kennt die Benutzer
  • Dovecot kennt den Mailbox-Pfad
  • Dovecot kann später Quotas anwenden
  • Dovecot kann später Sieve-Filter ausführen
  • Postfix muss nicht wissen, wie die Mailbox intern gespeichert wird

Dovecot LMTP-Socket für Postfix einrichten

Datei öffnen:

nano /etc/dovecot/conf.d/10-master.conf

Im Abschnitt service lmtp folgenden Socket einrichten:

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

Danach prüfen:

dovecot -n

und Dovecot neu starten:

systemctl restart dovecot

Wichtiger Hinweis zu auth_username_format

Falls in der LMTP-Konfiguration eine Zeile wie diese vorhanden ist:

auth_username_format = %{user | username | lower}

sollte sie für virtuelle Mailboxen mit vollständiger E-Mail-Adresse entfernt oder auskommentiert werden.

Warum?

Aus:

info@example.de

würde sonst nur:

info

Dovecot würde dann in der SQL-Tabelle nach info suchen, obwohl dort info@example.de gespeichert ist.

Das führt zu Fehlern wie:

User doesn't exist: info@example.de

Für virtuelle Mailboxen sollte Dovecot die vollständige Adresse verwenden.

Postfix MySQL-Unterstützung installieren

Postfix benötigt ein eigenes Modul, um MySQL-Tabellen abfragen zu können:

apt install postfix-mysql

SQL-Abfragen für Postfix erstellen

Wir legen die SQL-Dateien unter /etc/postfix/sql ab.

mkdir -p /etc/postfix/sql

Virtuelle Domains

nano /etc/postfix/sql/virtual_domains.cf

Inhalt:

user = mailuser
password = EinSehrLangesPasswort
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM virtual_domains WHERE name='%s'

Test:

postmap -q example.de mysql:/etc/postfix/sql/virtual_domains.cf

Erwartet:

1

Virtuelle Mailboxen

nano /etc/postfix/sql/virtual_mailboxes.cf

Inhalt:

user = mailuser
password = EinSehrLangesPasswort
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM virtual_users WHERE email='%s'

Test:

postmap -q info@example.de mysql:/etc/postfix/sql/virtual_mailboxes.cf

Erwartet:

1

Virtuelle Aliase

nano /etc/postfix/sql/virtual_aliases.cf

Inhalt:

user = mailuser
password = EinSehrLangesPasswort
hosts = 127.0.0.1
dbname = mailserver
query = SELECT destination FROM virtual_aliases WHERE source='%s'

Postfix auf virtuelle Domains umstellen

Jetzt konfigurieren wir Postfix so, dass die Domain nicht mehr als lokale Linux-Domain behandelt wird, sondern als virtuelle Maildomain.

postconf -e 'virtual_mailbox_domains = mysql:/etc/postfix/sql/virtual_domains.cf'
postconf -e 'virtual_mailbox_maps = mysql:/etc/postfix/sql/virtual_mailboxes.cf'
postconf -e 'virtual_alias_maps = mysql:/etc/postfix/sql/virtual_aliases.cf'
postconf -e 'virtual_transport = lmtp:unix:private/dovecot-lmtp'

Wichtig ist außerdem mydestination.

Bisher steht dort häufig:

mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain

Wenn example.de weiterhin in mydestination enthalten ist, behandelt Postfix die Domain als lokale Linux-Domain. Das wollen wir nicht mehr.

Daher setzen wir:

postconf -e 'mydestination = $myhostname, localhost.$mydomain, localhost'

Danach prüfen:

postfix check

und Postfix neu laden:

systemctl reload postfix

Erste Testmail an virtuelle Mailbox

Jetzt senden wir lokal eine Testmail:

echo "Test virtuelle Mailbox" | mail -s "Test LMTP" info@example.de

Log prüfen:

journalctl -u postfix -n 50 --no-pager

Bei Erfolg sollte dort etwas wie folgt stehen:

relay=mail.example.de[private/dovecot-lmtp]status=sent
Saved

Das zeigt:

Postfix → Dovecot LMTP → Maildir

Die Datei sollte nun unterhalb von /var/vmail liegen:

find /var/vmail/example.de/info/Maildir/new -type f -ls

Thunderbird einrichten

Jetzt kann die virtuelle Mailbox in Thunderbird eingerichtet werden.

Posteingang

Protokoll: IMAP
Server: mail.example.de
Port: 143
Verschlüsselung: STARTTLS
Benutzername: info@example.de

Alternativ:

Port: 993
Verschlüsselung: SSL/TLS

Postausgang

SMTP-Server: mail.example.de
Port: 587
Verschlüsselung: STARTTLS
Authentifizierung: Passwort normal
Benutzername: info@example.de

Wichtig ist, dass der Benutzername jetzt die vollständige E-Mail-Adresse ist:

info@example.de

nicht nur:

info

Virtuelle Aliase einrichten

Ein Alias leitet E-Mails an eine andere Adresse weiter.

Beispiel:

support@example.de → info@example.de

SQL:

INSERT INTO virtual_aliases
(domain_id,source,destination)
VALUES
(
1,
'support@example.de',
'info@example.de'
);

Test:

postmap -q support@example.de mysql:/etc/postfix/sql/virtual_aliases.cf

Erwartet:

info@example.de

Eine Mail an support@example.de wird nun an info@example.de zugestellt.

Lokale Linux-Authentifizierung optional deaktivieren

Während der Umstellung haben wir Dovecot so konfiguriert, dass sowohl lokale Linux-Benutzer als auch virtuelle SQL-Benutzer funktionieren:

!include auth-system.conf.ext
!include auth-sql.conf.ext

Wenn der Mailserver vollständig auf virtuelle Mailboxen umgestellt werden soll, kann die Systemauthentifizierung deaktiviert werden.

Datei öffnen:

nano /etc/dovecot/conf.d/10-auth.conf

Diese Zeile entfernen oder auskommentieren:

!include auth-system.conf.ext

Danach sollte nur noch SQL aktiv sein:

!include auth-sql.conf.ext

Dovecot neu starten:

systemctl restart dovecot

Test:

doveadm auth test info@example.de PASSWORT

Der virtuelle Benutzer muss weiterhin funktionieren. Ein lokaler Linux-Benutzer sollte sich dann nicht mehr per IMAP anmelden können.

Was ist mit home_mailbox?

In der alten Konfiguration wurde Postfix für lokale Benutzer häufig so eingestellt:

home_mailbox = Maildir/

Diese Einstellung wird für virtuelle Mailboxen nicht mehr benötigt, solange die Zustellung über virtual_transport und Dovecot LMTP erfolgt. Sie schadet für lokale Systemmails nicht zwingend, ist aber für die virtuellen Mailboxen nicht mehr der relevante Zustellweg. Der entscheidende Weg ist jetzt:

virtual_transport = lmtp:unix:private/dovecot-lmtp

Typische Fehler und Lösungen

Fehler: unsupported dictionary type: mysql

Meldung:

postmap: warning: unsupported dictionary type: mysql
postmap: fatal: unsupported dictionary type: mysql

Lösung:

apt install postfix-mysql

Fehler: User doesn’t exist

Meldung im Postfix-Log:

User doesn't exist: info@example.de

Mögliche Ursachen:

  • Benutzer fehlt in virtual_users
  • SQL-Abfrage findet den Benutzer nicht
  • Dovecot verändert den Benutzernamen durch auth_username_format
  • Dovecot sucht nur nach info statt nach info@example.de

Prüfen:

doveadm auth test info@example.de PASSWORT
doveadm user info@example.de

Fehler in Postfix SQL-Dateien

Die Queries sollten einzeilig geschrieben werden.

Richtig:

query = SELECT 1 FROM virtual_users WHERE email='%s'

Problematisch sind mehrzeilige Queries mit Backslash, wenn sie nicht korrekt verarbeitet werden.

Mail landet noch lokal

Wenn eine Mail an info@example.de nicht über LMTP, sondern lokal zugestellt wird, ist meist mydestination falsch.

Prüfen:

postconf mydestination

Die virtuelle Domain darf dort nicht mehr enthalten sein.

Richtig:

mydestination = $myhostname, localhost.$mydomain, localhost

Aktuelle Architektur

Nach der Umstellung sieht unser Mailserver so aus:

Eingehende Mail


Postfix


SQL-Prüfung:
virtual_domains
virtual_mailboxes
virtual_aliases


Dovecot LMTP


/var/vmail/example.de/info/Maildir

Der Abruf durch den Client erfolgt so:

Thunderbird


Dovecot IMAP


SQL-Login:
virtual_users


/var/vmail/example.de/info/Maildir

Der Versand durch den Client erfolgt so:

Thunderbird


Postfix Submission


Dovecot SASL


SQL-Login:
virtual_users

Damit verwenden IMAP und SMTP dieselbe Benutzerverwaltung.

Fazit

Mit der Umstellung auf virtuelle Mailboxen haben wir den Mailserver deutlich professioneller aufgebaut. Statt für jede E-Mail-Adresse einen Linux-Benutzer anzulegen, verwalten wir die Mailboxen nun in MariaDB. Dovecot übernimmt die Authentifizierung, stellt die Postfächer per IMAP bereit und nimmt eingehende Nachrichten über LMTP von Postfix entgegen.

Damit haben wir jetzt eine moderne Grundlage für einen eigenen Mailserver:

  • Postfix für SMTP
  • Dovecot für IMAP, Authentifizierung und LMTP
  • MariaDB für Benutzer, Domains und Aliase
  • /var/vmail als zentraler Speicherort
  • vollständige E-Mail-Adressen als Login
  • virtuelle Mailboxen ohne Linux-Benutzer

Im nächsten Teil können wir den Server weiter absichern und internet-tauglicher machen. Dazu gehören insbesondere:

  • SPF
  • DKIM
  • DMARC
  • Rspamd
  • Fail2Ban
  • Rate-Limits
  • Backups der Mailboxen und Datenbank

Inhalt

Ähnliche Beiträge

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Bitte füllen Sie dieses Feld aus.
Bitte füllen Sie dieses Feld aus.
Bitte gib eine gültige E-Mail-Adresse ein.
Sie müssen den Bedingungen zustimmen, um fortzufahren.