Email-Server für KI-Systeme: SMTP, IMAP & Datenbank

Anforderungen lokaler KI-Systeme

Lokal betriebene, interne KI-Systeme haben spezifische Anforderungen an Email-Infrastruktur, die proprietäre Cloud-Dienste oft nicht erfüllen können:

Zielgruppe und Scope

Diese Anleitung richtet sich an kleine und mittelständische Unternehmen mit bis zu 20 Personen. Das beschriebene Setup ist:

Voraussetzungen

Für den Betrieb wird benötigt:

Die drei Schichten eines Email-Systems

Ein Email-Server besteht aus klar getrennten Schichten:

Terminal
┌─────────────────────────────────────────────────────────────┐
│  ANWENDUNG                                                   │
│  Webmail, Thunderbird, KI-Agents, PHPMailer                 │
└──────────────────────┬──────────────────────────────────────┘
                       │ nutzt
┌──────────────────────▼──────────────────────────────────────┐
│  PROTOKOLLE                                                  │
│  SMTP (senden)  │  IMAP (abrufen)  │  POP3 (veraltet)       │
└──────────────────────┬──────────────────────────────────────┘
                       │ implementiert durch
┌──────────────────────▼──────────────────────────────────────┐
│  SERVER-SOFTWARE                                             │
│  Postfix (SMTP)  │  Dovecot (IMAP)  │  MariaDB (User-DB)    │
└─────────────────────────────────────────────────────────────┘

Komponenten im Detail

SMTP und Postfix

SMTP (Simple Mail Transfer Protocol) ist das Standardprotokoll zum Versenden und Empfangen von Emails zwischen Servern. Postfix ist der bewährte Mail Transfer Agent (MTA), der SMTP implementiert.

Postfix übernimmt:

IMAP und Dovecot

IMAP (Internet Message Access Protocol) ermöglicht den Zugriff auf Mailboxen. Dovecot ist der performante IMAP-Server mit SQL-Authentifizierung.

Dovecot übernimmt:

Datenbank statt Systemuser

Im Virtual-Mailbox-Setup existieren Email-Accounts nur in der Datenbank, nicht als Linux-User. Vorteile:

Die drei Tabellen

Das Virtual-Mailbox-Setup benötigt drei Tabellen:

Terminal
┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│ virtual_domains │     │  virtual_users  │     │ virtual_aliases │
├─────────────────┤     ├─────────────────┤     ├─────────────────┤
│ id              │◄────│ domain_id       │     │ id              │
│ name            │     │ email           │     │ domain_id       │◄──┐
└─────────────────┘     │ password        │     │ source          │   │
                        │ quota           │     │ destination     │   │
                        └─────────────────┘     └─────────────────┘   │
                                                         │            │
                                                         └────────────┘

virtual_domains

Enthält alle Domains, für die der Server Mails annimmt:

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

-- Beispiel
INSERT INTO virtual_domains (name) VALUES 
    ('firma.de'),
    ('projekt.com');

virtual_users

Enthält alle Mailboxen mit SHA512-verschlüsselten Passwörtern:

Terminal
CREATE TABLE virtual_users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    domain_id INT NOT NULL,
    email VARCHAR(255) NOT NULL UNIQUE,
    password VARCHAR(255) NOT NULL,
    quota BIGINT DEFAULT 0,
    FOREIGN KEY (domain_id) REFERENCES virtual_domains(id)
);

-- Passwort generieren (auf dem Server):
-- doveadm pw -s SHA512-CRYPT

INSERT INTO virtual_users (domain_id, email, password, quota) VALUES 
    (1, 'max@firma.de', '{SHA512-CRYPT}$6$abc...', 1073741824);

virtual_aliases

Weiterleitungen und Catch-All-Adressen:

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

-- Beispiele
INSERT INTO virtual_aliases (domain_id, source, destination) VALUES 
    (1, 'info@firma.de', 'max@firma.de'),           -- Weiterleitung
    (1, 'postmaster@firma.de', 'max@firma.de'),     -- Pflicht-Alias
    (1, '@firma.de', 'catchall@firma.de');          -- Catch-All

Dovecot SQL-Konfiguration

Die Datei /etc/dovecot/dovecot-sql.conf.ext verbindet Dovecot mit der Datenbank:

Terminal
driver = mysql
connect = host=localhost dbname=vmail user=vmail password=GEHEIM

default_pass_scheme = SHA512-CRYPT

password_query = SELECT email as user, password 
    FROM virtual_users WHERE email='%u'

user_query = SELECT 5000 AS uid, 5000 AS gid, 
    '/var/vmail/%d/%n' AS home, 
    'maildir:~/Maildir' AS mail 
    FROM virtual_users WHERE email='%u'

Postfix Virtual-Mailbox-Konfiguration

In /etc/postfix/main.cf:

Terminal
virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailboxes.cf
virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-aliases.cf
virtual_transport = lmtp:unix:private/dovecot-lmtp

Warum MX-Fallback?

Wenn der primäre Mailserver ausfällt (Wartung, Hardware-Problem, DDoS), gehen ohne Fallback alle eingehenden Emails verloren. Ein Backup-MX speichert Mails temporär und liefert sie aus, sobald der Hauptserver wieder erreichbar ist.

DNS-Konfiguration

MX-Records mit unterschiedlichen Prioritäten:

Terminal
firma.de.    IN MX 10 mail.firma.de.        ; Primär (niedrigste Zahl = höchste Priorität)
firma.de.    IN MX 20 backup.firma.de.      ; Backup auf eigenem VPS
firma.de.    IN MX 30 mx-backup.hoster.de.  ; Externer Fallback

Absendende Server versuchen zuerst Priorität 10. Erst bei Timeout oder Fehler wird Priorität 20 kontaktiert, dann 30.

Option 1: Kleiner VPS als Backup-MX

Ein minimaler VPS (1 GB RAM, 5 €/Monat) reicht als Backup-MX:

Terminal
# /etc/postfix/main.cf auf backup.firma.de

# Nur als Relay für firma.de agieren
relay_domains = firma.de
transport_maps = hash:/etc/postfix/transport

# Mails maximal 5 Tage queuen
maximal_queue_lifetime = 5d

# Kein lokaler Empfang
mydestination = 

Die Transport-Map leitet an den Hauptserver weiter:

Terminal
# /etc/postfix/transport
firma.de    smtp:[mail.firma.de]

Option 2: Externer Hoster als Fallback

Viele Hoster bieten Backup-MX als Zusatzservice:

Bei dieser Variante wird eine Mailbox beim Hoster als Catch-All konfiguriert. Ein Cronjob auf dem Hauptserver holt regelmäßig Mails per IMAP ab und sortiert sie in die richtigen lokalen Mailboxen.

Fallback-Mailbox mit automatischem Import

Script zum Abrufen der Fallback-Mails:

Terminal
#!/bin/bash
# /usr/local/bin/fetch-fallback-mail.sh

FALLBACK_HOST="imap.hoster.de"
FALLBACK_USER="fallback@firma.de"
FALLBACK_PASS="geheim"

# Alle Mails abrufen und lokal zustellen
fetchmail --protocol IMAP 
    --server $FALLBACK_HOST 
    --username $FALLBACK_USER 
    --password $FALLBACK_PASS 
    --ssl 
    --mda "/usr/lib/dovecot/deliver -d %T"

Monitoring

Überwache den Hauptserver, um bei Ausfall benachrichtigt zu werden:

Terminal
# Einfacher Check per Cron (alle 5 Minuten)
*/5 * * * * nc -z mail.firma.de 25 || 
    echo "Mailserver down" | mail -s "ALERT" admin@extern.de

Was muss gesichert werden?

Ein vollständiges Email-Backup umfasst:

Maildir-Backup mit rsync

Das Maildir-Format speichert jede Email als einzelne Datei. Das ermöglicht inkrementelle Backups:

Terminal
#!/bin/bash
# /usr/local/bin/backup-mail.sh

BACKUP_SERVER="backup.firma.de"
BACKUP_PATH="/backups/mail"

# Inkrementelles Backup der Maildirs
rsync -avz --delete 
    /var/vmail/ 
    $BACKUP_SERVER:$BACKUP_PATH/vmail/

# Datenbank-Dump
mysqldump -u backup -p'geheim' vmail | 
    ssh $BACKUP_SERVER "cat > $BACKUP_PATH/vmail.sql"

# Konfiguration
rsync -avz /etc/postfix/ $BACKUP_SERVER:$BACKUP_PATH/postfix/
rsync -avz /etc/dovecot/ $BACKUP_SERVER:$BACKUP_PATH/dovecot/

Backup-Rotation

Für Point-in-Time-Recovery mit täglichen Snapshots:

Terminal
# Auf dem Backup-Server
# /etc/cron.daily/rotate-mail-backup

BACKUP_BASE="/backups/mail"
DAYS_TO_KEEP=14

# Täglicher Snapshot mit Hardlinks (platzsparend)
rsync -avz --delete --link-dest=$BACKUP_BASE/latest 
    $BACKUP_BASE/incoming/ 
    $BACKUP_BASE/daily/$(date +%Y-%m-%d)/

# Alte Backups löschen
find $BACKUP_BASE/daily -maxdepth 1 -type d -mtime +$DAYS_TO_KEEP -exec rm -rf {} ;

Restore-Prozedur

Bei totalem Datenverlust:

Terminal
# 1. Datenbank wiederherstellen
mysql -u root -p vmail < /backups/mail/vmail.sql

# 2. Maildirs wiederherstellen
rsync -avz backup:/backups/mail/vmail/ /var/vmail/

# 3. Berechtigungen setzen
chown -R vmail:vmail /var/vmail
chmod -R 700 /var/vmail

# 4. Dovecot Index neu aufbauen
doveadm force-resync -A '*'

Empfohlener Backup-Plan

IntervallWasAufbewahrung
StündlichDatenbank-Dump24 Stunden
TäglichMaildir + DB + Config14 Tage
WöchentlichVollbackup8 Wochen
MonatlichArchiv-Backup12 Monate

TLS-Verschlüsselung

Alle Verbindungen müssen verschlüsselt sein:

Terminal
# /etc/postfix/main.cf
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.firma.de/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.firma.de/privkey.pem
smtpd_tls_security_level = may
smtp_tls_security_level = may

# /etc/dovecot/conf.d/10-ssl.conf
ssl = required
ssl_cert = 

SPF (Sender Policy Framework)

SPF definiert, welche Server Mails für eine Domain senden dürfen:

Terminal
# DNS TXT-Record
firma.de.  IN TXT "v=spf1 mx a:mail.firma.de -all"

Bedeutung:

DKIM (DomainKeys Identified Mail)

DKIM signiert ausgehende Mails kryptografisch:

Terminal
# Schlüssel generieren
opendkim-genkey -s mail -d firma.de

# DNS TXT-Record (aus mail.txt)
mail._domainkey.firma.de. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkq..."

Postfix-Integration mit OpenDKIM:

Terminal
# /etc/postfix/main.cf
milter_default_action = accept
milter_protocol = 6
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891

DMARC (Domain-based Message Authentication)

DMARC kombiniert SPF und DKIM und definiert, was bei Fehlschlägen passieren soll:

Terminal
# DNS TXT-Record
_dmarc.firma.de. IN TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@firma.de; pct=100"

Parameter:

Fail2ban gegen Brute-Force

Schutz vor Passwort-Angriffen:

Terminal
# /etc/fail2ban/jail.local
[dovecot]
enabled = true
port = imap,imaps
filter = dovecot
logpath = /var/log/mail.log
maxretry = 5
bantime = 3600

[postfix-sasl]
enabled = true
port = smtp,submission
filter = postfix-sasl
logpath = /var/log/mail.log
maxretry = 3
bantime = 3600

Checkliste Email-Sicherheit