Zwölf Builds

Ein selbst gehosteter Mailserver, der wirklich im Posteingang ankommt

Postfix, Dovecot und rspamd auf einer Instanz, mit korrekt konfiguriertem SPF, DKIM und DMARC sowie einem Verifizierungsschritt, der die Header der empfangenden Seite selbst liest.

Was das hier aufbaut

Ein vollständiger Mailserver für eine Domain: Postfix für den Transport, Dovecot für IMAP und lokale Zustellung, rspamd für Filterung und DKIM-Signierung sowie die drei DNS-Einträge, die darüber entscheiden, ob große Empfänger deine Mail in den Posteingang legen oder in einen Ordner, den niemand öffnet. Er sendet, er empfängt, er authentifiziert, und er ist kein offenes Relay.

Einen eigenen Mailserver zu betreiben ist unmoderner Rat und das meist aus gutem Grund. Die Zustellbarkeit ist der schwierige Teil, nicht die Software. Wenn das DNS falsch ist, schickt der sorgfältigste konfigurierte Postfix der Welt Nachrichten direkt ins Leere.

Bevor du beginnst

  • Eine R-8 oder größer. Filterung ist CPU-gebunden, und rspamd wird während einer Spam-Welle jeden Kern, den du ihm gibst, gerne nutzen.
  • Eine Domain, deren DNS du kontrollierst, und Geduld für die Ausbreitung.
  • Reverse DNS auf der Instanz-Adresse auf deinen Mail-Hostnamen gesetzt. Das ist im Panel bearbeitbar und ist Pflicht: Empfänger weisen nicht auflösbare Absender ab.
  • Ein Ticket an den Support, in dem du fragst, ob ausgehender Port 25 auf deiner Instanz offen ist. Frage, bevor du baust, nicht danach.
  • mail.example.com überall. Ersetze durch deine eigenen Werte.

1. Hostname und DNS

hostnamectl set-hostname mail.example.com
apt update && apt full-upgrade -y

Veröffentliche diese Einträge jetzt, denn der Zertifikatsschritt braucht den A-Eintrag und der Signierschritt braucht einen Ort für einen Schlüssel. Die Werte in der Tabelle beschreiben, was jeder Eintrag tut, nicht, was du einfügen sollst.

EintragNameInhalt
A / AAAAmailDie Instanz-Adressen aus dem Panel
MX@10 mail.example.com.
TXT@v=spf1 mx -all
TXT_dmarcv=DMARC1; p=none; rua=mailto:[email protected]; adkim=s; aspf=s
PTRInstanz-Adressemail.example.com — im Panel gesetzt

Der SPF-Eintrag besagt: Meine MX-Hosts senden meine Mail, alles andere ist gefälscht. Harte Ablehnung statt weicher Ablehnung, denn ~all lädt Empfänger ein, eine eigene Entscheidung zu treffen, und ihre Entscheidung wird nicht die großzügige sein. DMARC beginnt mit p=none, damit du eine Woche lang Berichte sammelst, bevor etwas in deinem Namen abgelehnt wird.

2. Zertifikate

apt install -y certbot
certbot certonly --standalone -d mail.example.com

Es lauscht noch nichts auf Port 80, daher ist der Standalone-Modus der einfachste Weg. Erneuerungs-Hooks kommen am Ende, sobald es Dienste gibt, die neu geladen werden müssen.

3. Postfix

DEBIAN_FRONTEND=noninteractive apt install -y postfix postfix-pcre dovecot-imapd dovecot-lmtpd rspamd redis-server

Jetzt die Transport-Konfiguration setzen. Jede Zeile unten ist bewusst gewählt; postconf schreibt sie an Ort und Stelle, damit es keinen Editor gibt, in dem man etwas falsch machen kann:

postconf -e "myhostname = mail.example.com"
postconf -e "mydestination = localhost"
postconf -e "smtpd_banner = \$myhostname ESMTP"
postconf -e "inet_interfaces = all"
postconf -e "smtpd_tls_cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pem"
postconf -e "smtpd_tls_key_file = /etc/letsencrypt/live/mail.example.com/privkey.pem"
postconf -e "smtpd_tls_security_level = may"
postconf -e "smtp_tls_security_level = dane"
postconf -e "smtpd_tls_mandatory_protocols = >=TLSv1.2"
postconf -e "smtpd_sasl_type = dovecot"
postconf -e "smtpd_sasl_path = private/auth"
postconf -e "smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated reject_unauth_destination"
postconf -e "smtpd_recipient_restrictions = permit_mynetworks permit_sasl_authenticated reject_unknown_recipient_domain reject_unauth_destination"
postconf -e "virtual_transport = lmtp:unix:private/dovecot-lmtp"
postconf -e "virtual_mailbox_domains = example.com"
postconf -e "smtpd_milters = inet:127.0.0.1:11332"
postconf -e "non_smtpd_milters = inet:127.0.0.1:11332"
postconf -e "milter_default_action = accept"

Die wichtigste Zeile ist smtpd_relay_restrictions. Sie endet mit reject_unauth_destination, und genau das verhindert, dass das gesamte Internet deine Maschine nutzt, um seine Mail zu senden. Ein offenes Relay führt innerhalb von Stunden zu einer Delistung und stellt außerdem einen Verstoß gegen die Richtlinien zur akzeptablen Nutzung dar.

Aktiviere den Submission-Port, damit deine eigenen Clients senden können, mit erforderlicher Authentifizierung und ohne anonymen Zugriff:

postconf -M submission/inet="submission inet n - y - - smtpd"
postconf -P "submission/inet/syslog_name=postfix/submission"
postconf -P "submission/inet/smtpd_tls_security_level=encrypt"
postconf -P "submission/inet/smtpd_sasl_auth_enable=yes"
postconf -P "submission/inet/smtpd_client_restrictions=permit_sasl_authenticated,reject"

4. Dovecot

Mailboxen im Maildir-Format unter einem einzigen Systembenutzer hält diesen Aufbau klein. Erstelle den Benutzer und den Speicher:

groupadd -g 5000 vmail
useradd -g vmail -u 5000 -d /var/vmail -m vmail
install -d -o vmail -g vmail -m 700 /var/vmail/example.com

Schreibe /etc/dovecot/conf.d/99-local.conf:

mail_location = maildir:/var/vmail/%d/%n
mail_uid = vmail
mail_gid = vmail
ssl = required
ssl_cert = </etc/letsencrypt/live/mail.example.com/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.example.com/privkey.pem
ssl_min_protocol = TLSv1.2
auth_mechanisms = plain login
disable_plaintext_auth = yes

passdb {
  driver = passwd-file
  args = scheme=ARGON2ID username_format=%u /etc/dovecot/users
}
userdb {
  driver = static
  args = uid=vmail gid=vmail home=/var/vmail/%d/%n
}

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

service auth {
  unix_listener /var/spool/postfix/private/auth {
    mode = 0660
    user = postfix
    group = postfix
  }
}

Erstelle eine Mailbox. Der Befehl fragt zweimal nach und schreibt einen Hash, nie das Passwort selbst:

echo -n "[email protected]:" >> /etc/dovecot/users
doveadm pw -s ARGON2ID >> /etc/dovecot/users
chmod 640 /etc/dovecot/users
chgrp dovecot /etc/dovecot/users

5. rspamd und DKIM

Generiere den Signierschlüssel, dann veröffentliche den öffentlichen Teil:

install -d -o _rspamd -g _rspamd -m 750 /var/lib/rspamd/dkim
rspamadm dkim_keygen -s mail -b 2048 -d example.com -k /var/lib/rspamd/dkim/example.com.mail.key
chown _rspamd:_rspamd /var/lib/rspamd/dkim/example.com.mail.key
chmod 400 /var/lib/rspamd/dkim/example.com.mail.key

Dieser Befehl gibt einen DNS-Eintrag auf der Standardausgabe aus. Veröffentliche ihn als TXT-Eintrag unter mail._domainkey.example.com, genau wie ausgegeben, wobei die in Anführungszeichen gesetzten Segmente so verbunden werden, wie dein DNS-Anbieter es erwartet. Dann sage rspamd, wo der Schlüssel liegt, in /etc/rspamd/local.d/dkim_signing.conf:

path = "/var/lib/rspamd/dkim/$domain.$selector.key";
selector = "mail";
allow_username_mismatch = true;
use_domain = "header";
sign_authenticated = true;
sign_local = true;

Binde den Milter ein und setze ein Passwort für die Weboberfläche:

echo "bind_socket = \"127.0.0.1:11332\";" > /etc/rspamd/local.d/worker-proxy.inc
rspamadm pw

Füge den resultierenden Hash in /etc/rspamd/local.d/worker-controller.inc als password = "..." ein. Erreiche die Oberfläche über einen SSH-Tunnel, anstatt Port 11334 für die Welt zu öffnen.

6. Alles starten

systemctl enable --now redis-server rspamd dovecot postfix
postfix check
systemctl --no-pager --failed

Füge einen Erneuerungs-Hook hinzu, damit ein neues Zertifikat beide Dienste erreicht:

echo "systemctl reload postfix dovecot" > /etc/letsencrypt/renewal-hooks/deploy/reload-mail.sh
chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-mail.sh

Verifizieren

Drei Tests. Der erste ist lokal, der zweite ist der, der zählt, der dritte ist der, der dich nicht auf Blocklisten bringt.

echo | openssl s_client -starttls smtp -connect mail.example.com:25 -servername mail.example.com 2>/dev/null | grep -E "subject=|Verify return"

Sende dann eine Nachricht von deinem neuen Server an eine Mailbox, die du bei einem großen Webmail-Anbieter hast, öffne die empfangene Nachricht und lies ihre rohen Header. Du suchst nach einer Zeile:

Authentication-Results: mx.receiver.example;
  dkim=pass [email protected];
  spf=pass smtp.mailfrom=example.com;
  dmarc=pass (p=NONE) header.from=example.com

Drei Erfolge und du bist fertig. Ein dkim=none bedeutet, dass rspamd nicht signiert, also prüfe rspamadm configdump dkim_signing. Ein spf=fail bedeutet fast immer, dass die Nachricht über IPv6 abging, während dein SPF-Eintrag nur die v4-MX-Adresse abdeckt.

Zuletzt beweise, dass du kein Relay bist. Von einer anderen Maschine verbinde dich und versuche, Mail zwischen zwei Domains zu senden, die dir nicht gehören:

apt install -y swaks
swaks --to [email protected] --from [email protected] --server mail.example.com

Das korrekte Ergebnis ist eine Ablehnung beim Empfänger: 554 5.7.1 Relay access denied. Alles andere bedeutet, dass du eine Maschine konfiguriert hast, die noch am selben Tag missbraucht wird, und du solltest aufhören und Schritt drei erneut lesen.

Danach

Lasse DMARC eine Woche lang auf p=none und lies die Aggregatberichte. Wenn sie nur noch deinen eigenen Server zeigen, der deine eigene Mail signiert, wechsle zu p=quarantine und zwei Wochen später zu p=reject. Füge nebenbei ein Off-Node-Backup für /var/vmail hinzu, denn Mail ist das Eine, von dem Benutzer nie eine zweite Kopie haben, und unser Backup-Add-on schreibt an einen anderen Standort als die Instanz.

Bereit, wenn Sie es sind

Wählen Sie eine Stadt. Wählen Sie eine Größe. Bezahlen Sie in Coins.

Keine Formulare darüber, wer Sie sind, kein Warten auf einen Menschen, der Sie genehmigt, kein Anruf zur Verifizierung. Die Rechnung wird beglichen, und die Zugangsdaten landen in Ihrem Posteingang.