Warum ein eigener Mailserver?

E-Mail ist die älteste und verlässlichste digitale Kommunikationsform – und gleichzeitig die am stärksten zentralisierte. Google, Microsoft und ein Handvoll weiterer Anbieter verarbeiten den Großteil des globalen E-Mail-Verkehrs. Wer seine eigene Domain betreibt, gibt die Kontrolle über das Herzstück seiner digitalen Identität meist trotzdem ab.

Mailcow ändert das. Ein vollständiger Mailserver mit Webmail, Kalender, Kontakten, Spamfilter, Virenschutz und Zwei-Faktor-Authentifizierung – containerisiert, wartbar, erweiterbar.

⚠️ Niveau: Fortgeschritten. Grundkenntnisse in Docker, DNS und Linux werden vorausgesetzt. Ein Mailserver ist kein Lernprojekt für den Einstieg – Fehlkonfigurationen haben direkte Auswirkungen auf Zustellbarkeit und Sicherheit.


Was ist Mailcow?

Mailcow: dockerized ist eine Open-Source-Mailserver-Suite, die ausschließlich auf etablierten Linux-Projekten aufbaut:

Komponente Aufgabe
Postfix SMTP – Versand und Empfang von E-Mails
Dovecot IMAP/POP3 – Zugriff durch Mailclients
SOGo Webmail, Kalender (CalDAV), Kontakte (CardDAV), ActiveSync
Rspamd Spamfilter, DKIM-Signierung
ClamAV Virenschutz für eingehende E-Mails
Unbound Interner DNS-Resolver
Nginx Web-Frontend, SSL-Terminierung
MariaDB Datenbank für Konfiguration und Mailboxen
Redis Session-Cache, Job-Queue
Olefy Analyse von Office-Dokumenten auf Makros
Netfilter Automatisches IP-Banning (Fail2Ban-äquivalent)
Watchdog Health-Monitoring, automatischer Neustart
ACME Let’s Encrypt Zertifikatsverwaltung

Mailcow ist kein einzelner Dienst – es ist ein orchestriertes System aus über einem Dutzend Containern, die zusammen einen vollständigen Mailserver ergeben.


Architektur

                    Internet
                       │
              Port 25/465/587 (SMTP)
              Port 143/993  (IMAP)
              Port 110/995  (POP3)
              Port 8030/9443 (Web-UI)
                       │
        ┌──────────────┴──────────────┐
        │        nginx-mailcow        │
        │   Web-Frontend / SSL-Term   │
        └──────┬───────────┬──────────┘
               │           │
    ┌──────────▼──┐   ┌────▼────────────┐
    │   postfix   │   │      sogo       │
    │    SMTP     │   │  Webmail/DAV    │
    └──────┬──────┘   └────────────────┘
           │
    ┌──────▼──────┐
    │   dovecot   │◄──── IMAP/POP3-Clients
    │  IMAP/POP3  │
    └──────┬──────┘
           │
    ┌──────▼──────────────────────────────────┐
    │              rspamd                     │
    │  Spamfilter · DKIM-Signierung · Greylisting │
    └──────┬──────────────────┬───────────────┘
           │                  │
    ┌──────▼──────┐    ┌──────▼──────┐
    │   clamd     │    │    olefy    │
    │  Virenscan  │    │  Makro-Scan │
    └─────────────┘    └─────────────┘

    ┌─────────────────────────────────────────┐
    │           Infrastruktur                 │
    │  MariaDB · Redis · Unbound · Netfilter  │
    │  Watchdog · ACME · DockerAPI · Ofelia   │
    └─────────────────────────────────────────┘

    Alle Container im mailcow-network (172.22.1.0/24)

Das interne Netzwerk mailcow-network ist ein dediziertes Bridge-Netzwerk mit festen IP-Adressen für kritische Dienste (z.B. Unbound auf .254, Redis auf .249). Alle Container kommunizieren über DNS-Aliases innerhalb dieses Netzwerks – mysql, redis, rspamd, postfix etc. sind intern direkt auflösbar.


Vorbereitung

Systemanforderungen

Ressource Minimum
CPU 1 GHz
RAM 6 GiB + 1 GiB Swap
Disk 20 GiB (ohne E-Mails)
Architektur x86_64, ARM64

Die RAM-Angabe ist das absolute Minimum für eine Standardkonfiguration. In der Praxis gilt:

  • 6 GiB + 1 GiB Swap sind für private Installationen ausreichend
  • 8 GiB sind empfohlen für 5–10 Nutzer
  • 16 GiB sollten bei ~15 ActiveSync-Verbindungen und 50 gleichzeitigen IMAP-Sessions eingeplant werden

ClamAV und der FTS-Indexer (Flatcurve) sind die größten RAM-Verbraucher. Ein einzelner SOGo-Worker kann bis zu ~350 MiB belegen – die Standardkonfiguration startet 20 Worker. Auf ressourcenbeschränkten Systemen können beide über SKIP_CLAMD=y und SKIP_FTS=y deaktiviert werden.

Nicht unterstützt: OpenVZ, Virtuozzo, LXC, Synology/QNAP NAS. Mailcow erfordert vollständige Virtualisierung (KVM, ESX, Hyper-V) oder Bare Metal.

Unterstützte Betriebssysteme

Betriebssystem Status
Debian 11–13
Ubuntu 22.04+
Alma Linux 8, 9
Rocky Linux 9
Alpine seit 3.19 ⚠️ manuelle Anpassungen nötig

Abhängigkeiten

Vor der Installation müssen folgende Pakete vorhanden sein:

# Debian/Ubuntu
apt install -y git openssl curl gawk coreutils grep jq

# RHEL-basiert (Rocky, Alma)
dnf install -y git openssl curl gawk coreutils grep jq

Docker muss mindestens in Version 24.0.0, Docker Compose mindestens 2.0 vorliegen. Die Distribution-eigenen Pakete sind häufig veraltet – das offizielle Installationsskript ist die zuverlässigere Quelle:

curl -sSL https://get.docker.com/ | CHANNEL=stable sh
systemctl enable --now docker

Firewall & Ports

Vor dem Start muss sichergestellt werden, dass keine andere Anwendung die benötigten Ports belegt:

ss -tlpn | grep -E -w '25|80|110|143|443|465|587|993|995|4190'

Eingehende Ports, die nach außen erreichbar sein müssen:

Dienst Port Protokoll
Postfix SMTP 25 TCP
Postfix SMTPS 465 TCP
Postfix Submission 587 TCP
Dovecot IMAP 143 TCP
Dovecot IMAPS 993 TCP
Dovecot POP3 110 TCP
Dovecot POP3S 995 TCP
Dovecot ManageSieve 4190 TCP
Web-UI (HTTP/HTTPS) 80/443 TCP

⚠️ Firewalld/UFW: Mailcow läuft containerisiert – INPUT-Regeln haben keine Wirkung. Regeln müssen in die DOCKER-USER-Chain eingetragen werden, da diese bei Docker-Neustarts erhalten bleibt.

ℹ️ Hetzner-Firewall: Unbound nutzt für ausgehende DNS-Anfragen den Port-Bereich 1024–65535. In der Hetzner Robot Firewall müssen eingehende TCP-Pakete mit ACK-Flag sowie UDP-Pakete auf diesem Port-Bereich explizit erlaubt werden.

Systemzeit & NTP

Ein korrekt synchronisiertes System ist Pflicht – TOTP-basierte Zwei-Faktor-Authentifizierung schlägt bei abweichender Systemzeit fehl.

timedatectl status

NTP aktivieren falls nicht aktiv:

timedatectl set-ntp true

/etc/systemd/timesyncd.conf sollte explizite NTP-Server enthalten:

[Time]
NTP=0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.org

DNS-Voraussetzungen

Vor der Installation müssen folgende DNS-Einträge gesetzt sein:

mail.example.com.   A      <SERVER-IPv4>
mail.example.com.   AAAA   <SERVER-IPv6>    # optional
mail.example.com.   MX     10 mail.example.com.

Der Hostname in mailcow.conf muss exakt mit dem A-Record übereinstimmen – andernfalls schlägt die TLS-Zertifikatsgenerierung fehl.

Repository klonen

cd /opt
git clone https://github.com/mailcow/mailcow-dockerized
cd mailcow-dockerized

Konfiguration generieren

./generate_config.sh

Das Skript fragt nach dem FQDN (z.B. mail.example.com) und der Zeitzone und erzeugt daraus eine vollständige mailcow.conf.


mailcow.conf – die wichtigsten Parameter

Mailcow wird vollständig über mailcow.conf gesteuert. Die docker-compose.yml liest alle Werte per ${VARIABLE} daraus – sie wird nicht manuell bearbeitet.

Hostname & Authentifizierung
MAILCOW_HOSTNAME=mail.example.com
MAILCOW_PASS_SCHEME=BLF-CRYPT

MAILCOW_HOSTNAME ist der FQDN des Mailservers – identisch mit dem DNS-A-Record und dem späteren MX-Eintrag. BLF-CRYPT (bcrypt) ist das empfohlene Passwort-Hashing-Schema für Mailbox-Passwörter.

Datenbank & Redis
DBNAME=mailcow
DBUSER=mailcow
DBPASS=<langer_zufälliger_string>
DBROOT=<langer_zufälliger_string>
REDISPASS=<langer_zufälliger_string>

Alle Passwörter sollten lange, zufällige alphanumerische Strings sein (A-Za-z0-9). Sonderzeichen können in bestimmten Kontexten zu Parsing-Problemen führen. Nach dem ersten Start sind Passwortänderungen aufwendig.

Port-Konfiguration
HTTP_PORT=8030
HTTPS_PORT=9443

SMTP_PORT=25
SMTPS_PORT=465
SUBMISSION_PORT=587
IMAP_PORT=143
IMAPS_PORT=993
POP_PORT=110
POPS_PORT=995
SIEVE_PORT=4190

DOVEADM_PORT=127.0.0.1:19991
SQL_PORT=127.0.0.1:13306
REDIS_PORT=127.0.0.1:7654

HTTP/HTTPS sind auf nicht-standardisierte Ports verschoben – sinnvoll wenn ein Reverse Proxy (z.B. Traefik) Port 80/443 bereits belegt. Die Mail-Ports (25, 465, 587, 143, 993) müssen direkt erreichbar sein und dürfen nicht hinter einem Proxy liegen. Doveadm, SQL und Redis sind auf 127.0.0.1 gebunden – kein externer Zugriff.

Zertifikate & ACME
SKIP_LETS_ENCRYPT=y
AUTODISCOVER_SAN=y
ADDITIONAL_SAN=

Mit SKIP_LETS_ENCRYPT=y übernimmt ein vorgelagerter Reverse Proxy die SSL-Terminierung und stellt Zertifikate bereit. Ohne Reverse Proxy sollte dieser Wert auf n stehen – Mailcow bezieht dann selbst Let’s Encrypt-Zertifikate über den integrierten ACME-Container.

AUTODISCOVER_SAN fügt autodiscover.* und autoconfig.* dem Zertifikat hinzu – relevant für automatische Mailclient-Konfiguration (Outlook, Thunderbird).

Dienste aktivieren/deaktivieren
SKIP_CLAMD=n        # ClamAV Virenschutz
SKIP_SOGO=n         # Webmail, Kalender, Kontakte
SKIP_FTS=n          # Volltextsuche (Dovecot Flatcurve)
FTS_HEAP=128        # Max. Heap in MB für FTS-Indexer
FTS_PROCS=1         # Max. gleichzeitige Indexer-Prozesse

Auf ressourcenbeschränkten Systemen können SKIP_CLAMD=y und SKIP_FTS=y erheblich Arbeitsspeicher sparen. ClamAV verbraucht allein ~1 GB, der FTS-Indexer je nach Datenmenge weitere Ressourcen.

Watchdog
USE_WATCHDOG=y
WATCHDOG_NOTIFY_START=y
WATCHDOG_NOTIFY_BAN=n
WATCHDOG_EXTERNAL_CHECKS=n

Der Watchdog überwacht alle Mailcow-Container und startet fehlerhafte Dienste automatisch neu. Benachrichtigungen können per E-Mail oder Webhook (Discord, Slack) konfiguriert werden:

WATCHDOG_NOTIFY_EMAIL=admin@example.com
WATCHDOG_NOTIFY_WEBHOOK=https://discord.com/api/webhooks/...

Die Container im Detail

Postfix – SMTP-Kern

Postfix übernimmt den gesamten E-Mail-Transport: eingehende Mails von fremden Servern (Port 25), ausgehende Mails von Clients (Port 587/465) und die interne Weiterleitung an Dovecot. Die Konfiguration wird vollständig von Mailcow verwaltet – direkte Eingriffe in main.cf sind über Override-Dateien in ./data/conf/postfix/ möglich.

Dovecot – IMAP/POP3

Dovecot verwaltet die Mailboxen, stellt IMAP und POP3 bereit und liefert die Authentifizierung für alle Mailcow-Komponenten. E-Mails werden im Maildir-Format in einem dedizierten Volume (vmail-vol-1) gespeichert. Die Volltextsuche (FTS) läuft über das Flatcurve/Xapian-Backend direkt in Dovecot.

Rspamd – Spamfilter & DKIM

Rspamd ist das Herzstück der E-Mail-Sicherheit. Jede eingehende Mail durchläuft eine Vielzahl von Checks: Bayes-Filter, DNS-Blacklists (DNSBL), Greylisting, SPF/DKIM/DMARC-Prüfung. Ausgehende Mails werden von Rspamd automatisch mit dem DKIM-Schlüssel signiert. Die Rspamd-Weboberfläche ist direkt im Mailcow-Admin-Panel integriert.

Unbound – Interner DNS-Resolver

Anstatt die DNS-Auflösung an den Host oder externe Resolver zu delegieren, betreibt Mailcow einen eigenen rekursiven Resolver. Das verhindert DNS-Leaks, ermöglicht DNSSEC-Validierung und stellt sicher, dass Spam-Blacklist-Abfragen (DNSBL) korrekt funktionieren – viele Public-DNS-Resolver wie 8.8.8.8 haben Rate-Limits für DNSBL-Abfragen. Unbound erhält eine feste IP im internen Netzwerk (.254) und alle anderen Container nutzen ihn als primären DNS.

Netfilter – Automatisches IP-Banning

Netfilter läuft im host-Netzwerkmodus mit privileged: true und hat direkten Zugriff auf die Kernel-Netzwerkschicht. Es überwacht fehlgeschlagene Authentifizierungsversuche und sperrt angreifende IPs automatisch via iptables/nftables – funktional vergleichbar mit Fail2Ban, aber tief in den Mailcow-Stack integriert.

Olefy – Office-Makro-Analyse

Olefy analysiert eingehende Office-Dokumente (.doc, .xls, .ppt etc.) auf eingebettete Makros – ein häufiger Angriffsvektor in gezielten Phishing-Kampagnen. Die Analyse läuft über olevba und wird von Rspamd automatisch angefordert.

Watchdog – Health-Monitoring

Der Watchdog überwacht kontinuierlich alle Mailcow-Container und reagiert auf Ausfälle. Jeder Dienst hat konfigurierbare Schwellenwerte – überschreitet z.B. die Postfix-Fehlerrate POSTFIX_THRESHOLD=8, wird ein Neustart eingeleitet und optional eine Benachrichtigung verschickt.


Start

docker compose pull
docker compose up -d

Der erste Start dauert mehrere Minuten: ClamAV lädt seine Signaturdatenbank (~300 MB), Datenbankmigrationen laufen durch, Zertifikate werden beantragt. Der Fortschritt lässt sich beobachten mit:

docker compose logs -f
# oder gezielt:
docker compose logs -f postfix-mailcow
docker compose logs -f acme-mailcow

Die Admin-Oberfläche ist nach erfolgreichem Start unter https://mail.example.com:9443 erreichbar. Standardzugangsdaten: admin / moohoosofort ändern.


DNS-Konfiguration

Ein Mailserver steht und fällt mit seinen DNS-Einträgen. Fehlende oder falsche Einträge führen dazu, dass ausgehende Mails als Spam eingestuft oder direkt abgelehnt werden.

MX-Record

example.com.   MX   10   mail.example.com.

Definiert, welcher Server E-Mails für die Domain empfängt.

PTR-Record (Reverse DNS)

<SERVER-IP>   PTR   mail.example.com.

Der PTR-Record wird beim Hosting-Provider gesetzt, nicht im eigenen DNS. Er muss mit MAILCOW_HOSTNAME übereinstimmen. Viele Mailserver lehnen eingehende Verbindungen ohne gültigen PTR-Record ab.

SPF – Sender Policy Framework

SPF-Eintrag
Name:  @
Typ:   TXT
Wert:  v=spf1 mx a -all

Mit expliziter Server-IP:

Name:  @
Typ:   TXT
Wert:  v=spf1 ip4:<IPv4> ip6:<IPv6> mx a -all

SPF definiert, welche Server berechtigt sind, E-Mails im Namen einer Domain zu versenden. Der empfangende Mailserver prüft beim Eingang, ob die IP des Absenders im SPF-Record der Absender-Domain autorisiert ist.

-all am Ende bedeutet “Hard Fail” – alle nicht autorisierten Server werden abgelehnt. ~all (Soft Fail) markiert sie lediglich als verdächtig. Für produktive Umgebungen ist -all die korrekte Wahl.

DKIM – DomainKeys Identified Mail

DKIM-Schlüssel aus Mailcow exportieren
# DKIM-Schlüssel in der Mailcow-Admin-UI:
# E-Mail → Konfiguration → Domains → Domain auswählen → DKIM

Der öffentliche Schlüssel wird als DNS-TXT-Eintrag gesetzt:

Name:  dkim._domainkey.example.com.
Typ:   TXT
Wert:  v=DKIM1; k=rsa; p=<PUBLIC_KEY>

DKIM fügt jeder ausgehenden E-Mail eine kryptografische Signatur im Mail-Header hinzu. Der empfangende Server kann diese Signatur mit dem öffentlichen Schlüssel im DNS verifizieren. Damit wird sichergestellt, dass der Inhalt der Mail seit dem Versand nicht verändert wurde – und dass der versendende Server tatsächlich Zugriff auf den privaten Schlüssel der Domain hat.

Anders als SPF funktioniert DKIM auch über Weiterleitungshosts hinweg, da die Signatur an der Mail selbst hängt und nicht an der sendenden IP.

Mailcow generiert den DKIM-Schlüssel automatisch beim Anlegen einer Domain. Der zu exportierende Public Key ist in der Admin-Oberfläche unter E-Mail → Konfiguration → Domains verfügbar.

DMARC – Domain-based Message Authentication

DMARC-Eintrag
Name:  _dmarc.example.com.
Typ:   TXT
Wert:  v=DMARC1; p=reject; rua=mailto:dmarc@example.com; ruf=mailto:dmarc@example.com; fo=1

DMARC baut auf SPF und DKIM auf und definiert, was mit E-Mails passieren soll, die beide Prüfungen nicht bestehen:

Policy Verhalten
p=none Nur Monitoring, keine Aktion
p=quarantine Mail in Spam-Ordner verschieben
p=reject Mail vollständig ablehnen

rua definiert eine E-Mail-Adresse für aggregierte Berichte (täglich, maschinenlesbar). ruf für forensische Einzelberichte. fo=1 sendet einen Bericht bei jedem SPF- oder DKIM-Fehler.

Empfohlene Einführungsstrategie: mit p=none beginnen, Berichte auswerten, schrittweise zu quarantine und schließlich reject wechseln.

SRV-Records – Automatische Client-Konfiguration

SRV-Records ermöglichen die automatische Konfiguration von Mailclients (Outlook, Thunderbird, iOS, Android) ohne manuelle Eingabe von Server und Ports. Für Mailcow empfehlen sich folgende Einträge:

SRV-Records
# Name                  Typ  Prio  Gew.  Port   Ziel
_autodiscover._tcp      SRV  0     1     443    mail.example.com.
_caldavs._tcp           SRV  0     1     443    mail.example.com.
_caldavs._tcp           TXT                     "path=/SOGo/dav/"
_carddavs._tcp          SRV  0     1     443    mail.example.com.
_carddavs._tcp          TXT                     "path=/SOGo/dav/"
_imap._tcp              SRV  0     1     143    mail.example.com.
_imaps._tcp             SRV  0     1     993    mail.example.com.
_pop3._tcp              SRV  0     1     110    mail.example.com.
_pop3s._tcp             SRV  0     1     995    mail.example.com.
_sieve._tcp             SRV  0     1     4190   mail.example.com.
_submission._tcp        SRV  0     1     587    mail.example.com.
_submissions._tcp       SRV  0     1     465    mail.example.com.

Vollständige DNS-Übersicht

mail.example.com.              A      <IPv4>
mail.example.com.              AAAA   <IPv6>
autodiscover.example.com.      CNAME  mail.example.com.
autoconfig.example.com.        CNAME  mail.example.com.
example.com.                   MX  10 mail.example.com.
example.com.                   TXT    "v=spf1 mx a -all"
dkim._domainkey.example.com    TXT    "v=DKIM1; k=rsa; p=<KEY>"
_dmarc.example.com.            TXT    "v=DMARC1; p=reject; rua=mailto:dmarc@example.com"
<IP>.in-addr.arpa.             PTR    mail.example.com.

Konfiguration testen

Nach dem Setzen der DNS-Einträge empfiehlt sich eine Überprüfung mit spezialisierten Tools:

Tool Prüft
MX Toolbox DNS, SMTP, Blacklists
mail-tester.com DKIM, DMARC, SPF gesamt
port25.com Verifier DKIM, SPF
MultiRBL.valli.org DNSBL/RBL-Blacklist-Check

Ein schneller End-to-End-Test ist das Versenden einer Mail an check-auth@verifier.port25.com – die Antwort enthält einen vollständigen SPF/DKIM/DMARC-Report.


Sicherheit & Zertifikate

TLS-Zertifikate

Mailcow verwaltet TLS-Zertifikate über den acme-mailcow-Container. Dieser beantragt automatisch Let’s Encrypt-Zertifikate für MAILCOW_HOSTNAME sowie alle in ADDITIONAL_SAN definierten Namen.

Mit SKIP_LETS_ENCRYPT=y (wie in dieser Konfiguration) übernimmt ein vorgelagerter Reverse Proxy die TLS-Terminierung. In diesem Fall müssen die Zertifikate unter ./data/assets/ssl/ bereitgestellt werden:

./data/assets/ssl/cert.pem
./data/assets/ssl/key.pem

Mailcow erkennt Zertifikatswechsel automatisch und lädt sie ohne Neustart.

Passwort-Hashing

BLF-CRYPT (bcrypt) ist das standardmäßig konfigurierte Hashing-Schema für Mailbox-Passwörter – ein bewusst langsamer Algorithmus, der Brute-Force-Angriffe auf die Datenbank erheblich erschwert.

Automatisches IP-Banning

Netfilter sperrt IPs nach konfigurierbaren Fehlversuchen automatisch. Die aktuelle Sperrliste ist in der Admin-Oberfläche unter System → Sperrliste einsehbar und verwaltbar.

Watchdog-Benachrichtigungen

Der Watchdog kann Benachrichtigungen über Webhooks versenden. Für produktive Umgebungen empfiehlt sich eine Integration in ein Monitoring-System oder zumindest eine Benachrichtigung per Webhook:

WATCHDOG_NOTIFY_WEBHOOK=https://discord.com/api/webhooks/...
WATCHDOG_NOTIFY_WEBHOOK_BODY='{"username": "Mailcow", "content": "⚠️ **\n"}'

Updates & Wartung

Mailcow bringt ein eigenes Update-Skript mit:

cd /opt/mailcow-dockerized
./update.sh

Das Skript zieht neue Images, führt Datenbankmigrationen aus und startet betroffene Container neu. Ein manuelles docker compose pull && docker compose up -d ist nicht empfohlen – Migrationen würden übersprungen.

# Logs eines bestimmten Dienstes
docker compose logs -f rspamd-mailcow

# Alle Container-Status
docker compose ps

# Datenbank-Backup
docker compose exec mysql-mailcow mysqldump -u root -p${DBROOT} mailcow > mailcow_$(date +%Y%m%d).sql

Fazit

Mailcow ist einer der ausgereiftesten selbstgehosteten Mailserver. Die Containerisierung macht Installation und Updates reproduzierbar, das Admin-Panel deckt nahezu alle Anforderungen ab und die Kombination aus Postfix, Dovecot, Rspamd und ClamAV entspricht dem Stand der Technik in der Mailserver-Absicherung.

Der Betrieb erfordert Sorgfalt – insbesondere bei DNS-Konfiguration, Zertifikatsverwaltung und regelmäßigen Updates. Ein Mailserver ist kein “Deploy and forget”-Projekt. Mit der richtigen Grundkonfiguration ist er jedoch ein stabiles, wartbares und vollständig selbstkontrolliertes Kommunikationssystem.