← Übersicht  ·  Skripte & Dateien  ·  cloud-host · E-Mail

Mailserver auf Hetzner

Einen eigenen Mailserver (Mailcow) für seb4u.com auf einem Hetzner-Cloud-Server betreiben. Der Aufbau ist an einem Nachmittag erledigt – die Arbeit steckt in Port 25, IP-Reputation und Deliverability. Ehrliche Einschätzung zuerst.

Stand: 30. August 2026 Mailcow (Docker) · eigener Server ~8–16 €/Mon + Pflege

Platzhalter einsetzen – werden unten ersetzt, nur im Browser

Lohnt sich das für dich?

Ehrlich

Für eine Person mit ein paar Postfächern ist ein gehosteter Anbieter (Zoho, Proton, mailbox.org, Fastmail) fast immer die bessere Wahl: kein Blocklisten-Stress, keine Deliverability-Sorgen, kein 03:00-Uhr-Notfall. Diese Anleitung macht nur Sinn, wenn du bewusst volle Kontrolle willst (viele Adressen/Aliase, Datenhoheit, Lernen) und bereit bist, den Server dauerhaft zu pflegen.

  • Aufwand einmalig: ~1 Nachmittag Setup + 1–3 Wochen Warmup.
  • Aufwand laufend: Updates (monatlich), Backups prüfen, DMARC-Reports lesen, Blocklisten-Monitoring, gelegentlich mit Groß-Providern kämpfen.
  • Eigener Server, nicht mitbenutzt. Mailcow will die Box für sich (RAM, IP-Reputation, eigener Reboot-Zyklus). Nicht neben WordPress & Co.
  • Nicht umkehrbar unter Zeitdruck: wenn die IP auf einer Blockliste landet oder Gmail dich ablehnt, dauert die Erholung Tage.

1 Port 25 freischalten

Hetzner blockt ausgehenden Port 25 (Server-zu-Server-Zustellung). Ohne Freischaltung kannst du empfangen, aber nicht senden.

  1. Hetzner-Konto → Support → neues Ticket. Sinngemäß: „Ich möchte auf Server <Name/IP> einen eigenen Mailserver (Mailcow) für meine Domain seb4u.com betreiben und bitte um Freischaltung des ausgehenden SMTP-Ports 25. rDNS wird auf mail.seb4u.com gesetzt, SPF (Sender Policy Framework)/DKIM/DMARC werden konfiguriert.“
  2. Bei etablierten Konten kommt die Freischaltung oft in 1–2 Tagen. Bei ganz frischen Konten kann sie verzögert oder abgelehnt werden – dann Konto erst etwas „altern“ lassen oder die Relay-Variante.
  3. Erst wenn Port 25 raus offen ist, lohnt der Rest. Test nach Freischaltung: nc -zv gmail-smtp-in.l.google.com 25 vom Server.

2 IP & Standort prüfen

Bevor du irgendetwas installierst: ist die IP sauber?

  1. Server erstellen (Schritt 4) → IP notieren → prüfen gegen Blocklisten: multirbl.valli.org, mxtoolbox Blacklist.
  2. Steht die IP auf Spamhaus PBL (typisch für „dynamische/Cloud“-Bereiche), reicht meist die Port-25-Freischaltung + korrektes rDNS, damit Hetzner den PBL-Eintrag entfernen lässt. Steht sie auf SBL/CSS/XBL (echte Spam-Historie): neue IP anfordern (Primary IP löschen + neu, oder Server neu erstellen), evtl. andere Location.
  3. Notfalls: eine reservierte Primary IP nehmen – dann bleibt die geprüfte IP stabil, auch wenn du den Server neu baust.
Location

Deutsche/EU-Endkunden: nbg1/fsn1/hel1 ist gut. Einzelne Cloud-Bereiche haben schlechteren Ruf als andere – wenn die erste IP schlecht aussieht, ist eine zweite oft besser.

3 Server + Firewall

Konto, hcloud CLI (Command-Line Interface) und SSH-Key setzt die Server-Basis-Anleitung voraus. Hier die mailspezifische Firewall (viele Ports) und der Server.

Laptop · PowerShell
# Mailcow: min. 6 GB RAM empfohlen -> cpx32 (8 GB) oder cax31
hcloud firewall create --name mail-fw
foreach ($p in 22,25,80,110,143,443,465,587,993,995,4190) {
  hcloud firewall add-rule mail-fw --direction in --protocol tcp --port $p --source-ips 0.0.0.0/0
}
hcloud server create --name mailhost --type cpx32 --image debian-12 `
  --ssh-key laptop --firewall mail-fw
PortWofür
25SMTP (Server-zu-Server, empfangen + senden)
465 / 587Submission (deine Clients senden)
143 / 993IMAP (Internet Message Access Protocol) / IMAPS
110 / 995POP3 (Post Office Protocol Version 3) / POP3S (optional)
4190ManageSieve (Filterregeln)
80 / 443Webmail (SOGo) + Admin-UI + Let’s Encrypt

Grundhärtung wie Grundausstattung (non-root, unattended-upgrades, ggf. SSH übers Tailnet). Docker installiert das Mailcow-Skript selbst nicht – curl -fsSL https://get.docker.com | sh vorab.

4 rDNS (PTR) setzen

Der wichtigste Einzeleintrag. PTR (Pointer-Record) und A-Record müssen sich exakt entsprechen, sonst lehnen viele Empfänger ab.

  1. Hetzner Console: Servers mailhost Networking die IPv4 (Internet Protocol Version 4) Edit Reverse DNS (Domain Name System)mail.seb4u.com.
  2. Dasselbe für die IPv6 (falls du IPv6 für Mail nutzt – sonst IPv6 in Mailcow deaktivieren, dann brauchst du keinen v6-PTR).
  3. In Cloudflare gleich den A-Record setzen: mail.seb4u.com<ip>, DNS only (graue Wolke – Mail wird nie geproxied).
Laptop · Kontrolle (nach Propagation)
nslookup <ip>            # -> mail.seb4u.com
nslookup mail.seb4u.com   # -> dieselbe IP

5 DNS-Records bei Cloudflare

Erst alle bis auf DKIM (das kommt nach der Installation). Alles „DNS only“ / grau – Mail wird nicht geproxied.

NameTypWert
mailA<ip>
@MX (Mail-Exchange-Record)mail.seb4u.com  Prio 10
@TXT (Text-Record)v=spf1 mx -all
_dmarcTXTv=DMARC1; p=none; rua=mailto:dmarc@seb4u.com; adkim=s; aspf=s  (erst p=none, siehe Schritt 12)
autoconfigCNAME (Canonical Name)mail.seb4u.com
autodiscoverCNAMEmail.seb4u.com
_autodiscover._tcpSRV (Service-Record)0 1 443 mail.seb4u.com
_submission._tcpSRV0 1 587 mail.seb4u.com
_imaps._tcpSRV0 1 993 mail.seb4u.com
dkim._domainkeyTXTkommt aus Mailcow, Schritt 8

Optional für Fortgeschrittene: MTA-STS (_mta-sts TXT + mta-sts-Host mit Policy) und TLS-RPT (_smtp._tls TXT) – erzwingt verschlüsselte Zustellung und Reports. Mailcow bringt den MTA-STS-Webserver mit.

6 Mailcow installieren

Server · als root
apt update && apt install -y git curl
curl -fsSL https://get.docker.com | sh

git clone https://github.com/mailcow/mailcow-dockerized /opt/mailcow-dockerized
cd /opt/mailcow-dockerized
./generate_config.sh
# Mail server hostname (FQDN):  mail.seb4u.com
# Timezone:                     Europe/Berlin

docker compose pull
docker compose up -d
# ~3-5 Min. Danach: https://mail.seb4u.com  (Login admin / moohoo -> sofort aendern)
Vor up -d

Der A-Record für mail.seb4u.com muss schon stehen und Port 80 erreichbar sein – Mailcow holt beim Start das Let’s-Encrypt-Zertifikat. In mailcow.conf: SKIP_IP_CHECK=y nicht nötig. ADDITIONAL_SAN=autodiscover.seb4u.com,autoconfig.seb4u.com eintragen, damit das Zertifikat auch die abdeckt.

7 DKIM erzeugen + eintragen

  1. Mailcow-UI: Configuration Options ARC/DKIM keys → Domain seb4u.com, Selector dkim, Länge 2048Add.
  2. Mailcow zeigt den fertigen DNS-Wert. In Cloudflare als TXT anlegen: dkim._domainkeyv=DKIM1;k=rsa;p=MIIBIjANBgkq… (der ganze lange String, ggf. in Anführungszeichen).
  3. Nach Propagation in Mailcow auf Recheck – Haken bei DKIM.

8 Domain + Postfach anlegen

  1. Configuration Mail setup Domains Add domainseb4u.com, Postfach-Quota + Anzahl nach Bedarf. Danach Validate DNS – MX/SPF/DKIM/DMARC sollten grün sein.
  2. Reiter MailboxesAdd mailbox: du@seb4u.com, Passwort, Quota.
  3. Aliase (info@, kontakt@ → dein Postfach) unter Aliases. Eine dmarc@-Adresse für die Reports anlegen.

9 Clients / Autodiscover

ServerPortVerschlüsselung
IMAPmail.seb4u.com993SSL (Secure Sockets Layer)/TLS (Transport Layer Security)
SMTPmail.seb4u.com587STARTTLS (opportunistische TLS-Verschlüsselung)

Benutzername = volle Adresse. Thunderbird/Outlook/iOS finden das per autoconfig/autodiscover meist von selbst. Webmail: https://mail.seb4u.com/SOGo.

10 Deliverability testen

  1. mail-tester.com: an die angezeigte Adresse eine Mail senden → Score. Ziel 10/10 (SPF, DKIM, DMARC, rDNS, kein Blocklisten-Treffer, kein Spam-Score).
  2. An eine Gmail- und eine Outlook.com-Adresse senden → Original anzeigenSPF: PASS, DKIM: PASS, DMARC: PASS. Landet sie im Posteingang oder im Spam?
  3. mxtoolbox: mx:seb4u.com, spf:, dmarc:, blacklist:<ip>.
  4. Google Postmaster Tools: seb4u.com hinzufügen, per TXT verifizieren – zeigt dir später Reputation, Spam-Rate, Auth-Fehler bei Gmail-Zustellung.
Wenn es im Spam landet

Frische IP + neue Domain = anfängliches Misstrauen. Erst SPF/DKIM/DMARC/rDNS wirklich alle PASS. Dann hilft nur Warmup und Zeit. Bei Outlook.com gibt es das Sender Support-Formular (SNDS/JMRP), falls es dauerhaft klemmt.

11 Warmup + DMARC hochziehen

  • Woche 1–2: wenig senden, echte Konversationen (Antworten von Gmail-Kontakten zählen positiv). Keine Massenmails.
  • DMARC stufenweise in Cloudflare:
    • Start: p=none – nur Reports sammeln, rua lesen.
    • Nach ~1 Woche ohne Fehler: p=quarantine; pct=25, dann pct=100.
    • Wenn stabil: p=reject.
  • DMARC-Reports (XML an dmarc@) mit einem Viewer ansehen (dmarcian / postmarkapp DMARC / selbst gehostet) – zeigt, wer in deinem Namen sendet und ob Auth passt.
  • Google Postmaster nach ~1 Woche checken: Domain-/IP-Reputation sollte „High“/„Medium“ werden, Spam-Rate < 0,1 %.

12 Migration von Zoho

Bestehende Mails aus dem Zoho-Postfach in das neue holen – ohne Unterbrechung.

  1. Neues Postfach in Mailcow anlegen (Schritt 8), aber die MX noch auf Zoho lassen.
  2. Mailcow: Email Configuration Sync jobs Create → Quelle: imap.zoho.eu, Port 993, SSL, dein Zoho-Login. Ziel: das neue Postfach. Läuft periodisch und zieht alles rüber (nutzt imapsync intern).
  3. Wenn alles synchron ist: MX in Cloudflare auf mail.seb4u.com umstellen, SPF/DKIM/DMARC anpassen (Zoho-include raus). Ab jetzt kommt neue Mail bei Mailcow an.
  4. Ein paar Tage beide beobachten, dann Zoho-Postfach kündigen.
Ohne Mailcow-Job

Einmalig vom Laptop: imapsync --host1 imap.zoho.eu --user1 … --host2 mail.seb4u.com --user2 …. Gleiches Prinzip.

13 Betrieb: Update, Backup, Monitoring

Server · /opt/mailcow-dockerized
# Update (~monatlich; liest Changelog, macht Backup der configs)
./update.sh

# Backup: Mailboxes + Configs + DB -> Verzeichnis, dann off-site
MAILCOW_BACKUP_LOCATION=/opt/backups ./helper-scripts/backup_and_restore.sh backup all --delete-days 7
rsync -a /opt/backups/ user@u123.your-storagebox.de:mail/
  • Backup als cron (nachts). Restore einmal testen – backup_and_restore.sh restore.
  • Fail2ban / Watchdog sind in Mailcow eingebaut (UI → Fail2ban, Configuration → Options).
  • Platz: der Maildata-Ordner wächst. docker system df, Quotas setzen, Server-Volume groß genug (oder ein eigenes Volume für vmail).
  • Monitoring: Uptime Kuma auf Port 993 + 25 + die Web-UI. Alarm bei Blocklisten-Treffer (z. B. per Skript gegen die RBL-APIs).
  • IPv6: wenn du keinen sauberen v6-PTR + AAAA (IPv6-Adress-Record) pflegen willst, IPv6 in Mailcow abschalten (mailcow.confIPV6_NETWORK anpassen bzw. SMTP_INBOUND_ADDITIONAL_ADDRESSES) – verhindert v6-Zustellprobleme.

+ Falls Port 25 nicht kommt: Outbound-Relay

Empfangen geht ohne Port-25-Freischaltung nicht (eingehend brauchst du 25 sowieso – eingehend ist bei Hetzner offen, nur ausgehend gesperrt). Fürs Senden dann ein Relay: einen SMTP-Smarthost (transaktionaler Anbieter oder ein zweiter Server mit offenem 25) als relayhost.

Datei · data/conf/postfix/extra.cf
relayhost = [smtp.dein-relay.tld]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = static:USER:PASS
smtp_sasl_security_options = noanonymous
smtp_tls_security_level = encrypt

Danach docker compose restart postfix-mailcow. SPF muss dann den Relay erlauben (include: des Anbieters). DKIM signiert weiterhin Mailcow.

+ Kosten

Preise sind Richtwerte. Hetzner hat 2026 zweimal erhöht (zuletzt 15. Juni: CX/CAX +30–40 %, CPX/CCX über 100 %). Aktuelle Server-Preise, alle Nebenposten, ein Rechner und Beispielrechnungen stehen zentral in Kosten & Budget.

Posten~€/Tag~€/Mon
Server CPX32 (8 GB) – eigener, nur Mail. CAX21 ARM (Advanced RISC Machines) ~10,5~1,17~35,5
Primary IP (stabile, geprüfte IP)~0,02~0,5
Backup: Storage Box BX11 – optional~0,13~3,8
Port-25-Freischaltung, DNS, Zertifikate00
Summe~0,30–0,40~8–12 + deine Zeit
Vergleich: Zoho Mail Lite / mailbox.org / Fastmail~1–5
⌂ Cockpit