Postfix unter Ubuntu-Server

Postfix ist ein beliebter SMTP-Server unter Linux. Eine eigene Postfix-Installation erlaubt es, E-Mails ohne Nutzung komplexer Infrastrukturen (wie z.B. MS Exchange oder E-Mail-Provider in der Cloud) zu versenden. Dieser Blog-Artikel zeigt Euch, wie man Postfix unter Ubuntu Server 20.04 LTS installiert und konfiguriert.

Einführung

Postfix ist ein freier Mail Transfer Agent (MTA) und Open Source. Die Lizenzierung ist dual: Eclipse Public license (EPL 2.0) und IBM Public License (IPL 1.0). Postfix läuft unter Linux, macOS sowie weiteren Unix-Derivaten.

Die Postfix-Homepage

Die Postfix-Homepage

Bevor wir uns weiter mit Postfix beschäftigen, ein kurzer Überblick über die Art und Weise wie der E-Mail-Zustellungsprozess vonstattengeht. Das ist wichtig, um die Rolle von Postfix innerhalb des E-Mail-Workflows zu verstehen.

Eine E-Mail durchläuft in der Regel mehrere Stationen, bis sie beim Empfänger ankommt.

E-Mail-Zustellungsprozess

E-Mail-Zustellungsprozess

Die verschiedenen Agents haben folgende Bedeutung:

  • Message User Agent (MUA)

    Repräsentiert den Nutzer (Sender oder Empfänger) des E-Mail-Systems. In der Regel ist damit ein E-Mail-Client (z.B. MS Outlook) gemeint, es kann aber auch die E-Mail-Benachrichtigung einer Serveranwendung sein.

  • Mail Submission Agent (MSA)

    Nimmt die E-Mail des Senders (also eines MUA) entgegen. Das Kommunikationsprotokoll zwischen MUA und MSA ist in der Regel SMTP oder ESMTP. Die E-Mail wird anschließend an den Message Transfer Agent (MTA) weitergeleitet. MSA und MTA sind meistens Teil der gleichen Serveranwendung.

  • Message Transfer Agent (MTA)

    Ist dafür verantwortlich, die E-Mail näher an den Empfänger zu bringen. Entweder, in dem er die E-Mail an einen weiteren MTA weiterleitet (in diesem Fall agiert der MTA als Relay) oder aber, in dem er sie einem Mail Delivery Agent (MDA) übergibt. Das Kommunikationsprotokoll zwischen MTAs ist SMTP. Das Routing erfolgt per DNS MX Record.

  • Mail Delivery Agent (MDA)

    Liefert die E-Mail aus, in dem er sie an einem Ort verfügbar macht, von dem aus der MUA mittels IMAP4 oder POP3 seine E-Mails abrufen kann. MDA und MTA sind meistens Teil der gleichen Serveranwendung.

MSA, MTA und MDA werden unter dem Begriff Message Handling System (MHS) zusammengefasst. Eine ausführliche Beschreibung der allgemeinen E-Mail-Architektur liefert RFC5598.

Microsoft Exchange implementiert zum Beispiel alle drei Komponenten des MHS, Postfix dagegen nur die Komponenten MSA und MTA. Zum Empfangen und Abrufen von E-Mails benötigt man einen separaten Dienst (z.B. Dovecot).

Los geht’s

Wir werden jetzt folgendes tun:

  1. Postfix unter Ubuntu Server 20.04 LTS installieren und so konfigurieren, dass er als SMTP-Server unter smtp.beispiel.de erreichbar ist, um E-Mails entgegenzunehmen (Submission) und sie weiterzuleiten.

  2. Wir werden die Konfiguration im Anschluss weiter verfeinern:

    • Das SPAM-Problem lösen
    • Eine Authentifizierung erzwingen
    • Die Kommunikation mit Postfix per TLS absichern
    • Gültige Absenderadressen definieren
    • Die Firewall konfigurieren

Postfix installieren

Postfix ist Bestandteil der Standard-Repositories von Ubuntu. Die Installation beginnt unspektakulär:

$ sudo apt-get update && sudo apt-get install postfix

Während des Installationsvorgangs wirst Du interaktiv nach einigen grundlegenden Konfigurationsdaten gefragt. Zunächst erscheint eine Anzeige mit einer einführenden Erklärung. Bestätige mit OK.

Postfix: Einführende Erklärung

Postfix: Einführende Erklärung

Es erscheint folgende Auswahl. Wir wählen Internet, da wir eine zentrale Postfix-Instanz aufsetzen wollen. Bestätige mit OK.

Postfix: Konfigurationstyp

Postfix: Konfigurationstyp

Jetzt müssen wir noch die Standarddomäne für unsere E-Mails definieren. Bestätige erneut mit OK.

Postfix: Standarddomäne für E-Mails

Postfix: Standarddomäne für E-Mails

Noch etwas Geduld. Aber am Ende sollte der Postfix-Dienst erfolgreich gestartet sein.

Wir können dies wie folgt überprüfen:

$ service postfix status

Die Antwort sollte in etwa so aussehen:

● postfix.service - Postfix Mail Transport Agent
     Loaded: loaded (/lib/systemd/system/postfix.service; enabled; vendor preset: enabled)
     Active: active (exited) since Fri 2021-11-12 17:44:38 CET; 2min 31s ago
   Main PID: 2337 (code=exited, status=0/SUCCESS)
      Tasks: 0 (limit: 60)
     Memory: 0B
     CGroup: /system.slice/postfix.service

Möchtest Du die exakte Version Deines Postfix-Servers ermitteln, dann tippe folgendes ein:

$ postconf -d mail_version

Die Antwort sollte in etwa so aussehen:

mail_version = 3.4.13

Ein erster Überblick

Schauen wir uns die Installation von Postfix genauer an:

  • Alle Konfigurationsdateien liegen standardmäßig unter /etc/postfix/.

  • Die Hauptkonfigurationsdatei lautet /etc/postfix/main.cf.

  • Eine weitere wichtige Datei ist die Master Process Configuration unter /etc/postfix/master.cf. Sie legt fest, welche Postfix-Prozesse mit welcher Konfiguration gestartet werden.

  • Die Log-Datei liegt unter /var/log/mail.log.

  • Standardmäßig nimmt Postfix nur lokal versendete E-Mails oder per SASL authentifizierte E-Mails entgegen (zum Thema SASL kommen wir später).

Zum Testen verschicken wir eine E-Mail an uns selber (ersetze dabei <Meine E-Mail-Adresse> durch Deine eigene E-Mail-Adresse):

$ echo "Hallo! Hier kommt eine Testnachricht via Postfix" | mail -r postfix@beispiel.de -s "Testnachricht" <Meine E-Mail-Adresse>

So, die E-Mail ist jetzt verschickt. Überprüfe bitte, ob sie bei Dir auch angekommen ist. Sehr wahrscheinlich ist sie in Deinem Spam-Ordner gelandet.

Die Sache mit dem SPAM

Schauen wir uns die E-Mail etwas genauer an. Warum ist sie im SPAM-Ordner gelandet?

SPAM ist nicht gleich SPAM. Je nach E-Mailserver und SPAM-Filterkonfiguration kann ein und dieselbe E-Mail unterschiedlich klassifiziert werden. Es gibt jedoch eine Reihe von Merkmalen, die fast immer zu Rate gezogen werden. Dabei kann uns ein E-Mail-Checker wie zum Beispiel MailGenius helfen.

  1. Öffne die Webseite von MailGenius in Deinem Web-Browser.

  2. Dir wird eine generierte E-Mail-Adresse angezeigt, an die wir unsere Testmail von eben erneut schicken.

  3. Drücke nach kurzer Wartezeit auf die Schaltfläche SEE YOUR SCORE.

Das Ergebnis für unsere E-Mail sieht wie folgt aus:

Analyseergebnis für Postfix-Standardkonfiguration

Analyseergebnis für Postfix-Standardkonfiguration

Wir fassen zusammen:

  • Wir haben keinen DMARC-Eintrag veröffentlicht.
  • Es existiert kein SPF-Record.
  • Die DKIM Signatur der E-Mail-Nachricht fehlt.
  • Es wird mit einer Warnung darauf hingewiesen, dass ein Link zur Abmeldung (List-Unsubscribe-Header) fehlt.

Ein paralleler Test unter mailtester bringt zusätzlich folgendes Problem zu Tage:

  • Kein E-Mailserver (MX-Eintrag) für die Domäne beispiel.de auffindbar.

Um diese fünf Punkte wollen wir uns jetzt kümmern.

Sender Policy Framework (SPF)

Das Sender Policy Framework (SPF) ist ein Verfahren, mit dem das Versenden von E-Mails über nicht legitimierte Mail Transfer Agents (MTAs) unterbunden werden soll. SPF ermöglicht dem empfangenden E-Mailserver zu überprüfen, ob eine E-Mail, die behauptet, von einer bestimmten Domäne zu stammen, vom Administrator der Domäne auch autorisiert wurde. Dazu trägt dieser die IP-Adresse des MTA als TXT-Record für seine Domäne ein.

Genau das machen wir jetzt auch. Dazu musst Du bei Deinem DNS-Provider für die Domäne beispiel.de einen zusätzlichen DNS-Eintrag vom Typ TXT hinzufügen. Dieser hat folgenden Wert (die IP-Adresse ist natürlich wieder nur ein Beispiel, Du musst die IP-Adresse Deines Postfix-Servers eintragen):

v=spf1 ip4:159.69.60.4/32 ~all

Existiert bereits ein DNS-Eintrag für SPF, musst Du Deine IP-Adresse diesem anfügen, es darf nicht mehr als ein Eintrag pro Domäne geben. Eine gute Hilfe beim Generieren von SPF-Einträgen bietet Dir der folgende SPF Generator.

Hast Du die Änderung bei Deinem DNS-Provider erfolgreich durchgeführt, kannst Du mittels SPF Check prüfen, ob alles ok ist. Bitte beachte, dass es einige Stunden dauern kann, bis der neue TXT-Eintrag im Internet allgemein verfügbar ist.

DomainKeys Identified Mail (DKIM)

DomainKeys Identified Mail (DKIM) ist ein Verfahren zur Sicherstellung der Authentizität von E-Mail-Absendern. Dabei wird die versendete E-Mail mit einer digitalen Signatur versehen, deren öffentlicher Schlüssel ebenfalls als DNS-Eintrag für die Mail-Domäne hinterlegt wird. Der empfangende MTA oder MUA kann dann mit Hilfe des öffentlichen Schlüssels die E-Mail verifizieren. DKMI versucht wie SPF auch, das Fälschen von E-Mail-Absenderadressen zu unterbinden, ist aber komplexer in der Konfiguration.

OpenDKIM ist eine Open-Source-Implementation des DKIM-Verfahrens. Der folgende externe Blog-Artikel beschreibt ausführlich das Einrichten von OpenDKIM unter Postfix: DKIM-Konfiguration für Postfix. Wir beschränken uns auf eine absolute Kurzfassung.

Zunächst installieren wir OpenDKIM:

$ sudo apt-get install opendkim opendkim-tools 

Öffne die folgende Datei:

$ sudo nano /etc/opendkim.conf

Kopiere den folgenden Inhalt hinein und speichere die Datei:

Syslog                yes
SyslogSuccess         yes
LogWhy                yes
UMask                 002
UserID                opendkim:opendkim

InternalHosts         refile:/etc/opendkim/trusted
ExternalIgnoreList    refile:/etc/opendkim/trusted

SigningTable          refile:/etc/opendkim/signing.table
KeyTable              /etc/opendkim/key.table

Socket                inet:8892@localhost
PidFile               /var/run/opendkim/opendkim.pid

AutoRestart           yes
AutoRestartRate       10/1h
Canonicalization      relaxed/simple
Mode                  sv
OversignHeaders       From
SignatureAlgorithm    rsa-sha256
SubDomains            no

Jetzt geht es mit folgenden Befehlen weiter:

sudo mkdir /etc/opendkim
sudo mkdir /etc/opendkim/keys
sudo chown -R opendkim:opendkim /etc/opendkim
sudo chmod go-rw /etc/opendkim/keys

Erstelle die folgende Datei:

$ sudo nano /etc/opendkim/trusted

Kopiere die Liste der Hosts hinein, denen Du vertraust, die also keine DKMI-Signatur benötigen:

127.0.0.1
::1
localhost

Erstelle die folgende Datei:

$ sudo nano /etc/opendkim/signing.table

Hier werden die E-Mail-Absenderadressen (FROM) auf ihre Schlüssel abgebildet:

*@beispiel.de beispiel.de

Erstelle die folgende Datei:

$ sudo nano /etc/opendkim/key.table

Hier werden die Schlüssel auf Ihren Speicherorte abgebildet:

beispiel.de beispiel.de:202111:/etc/opendkim/keys/beispiel.de.private

Jetzt geht es mit folgender Befehlsfolge weiter. Wir erzeugen jetzt einen privaten und öffentlichen DKMI-Schlüssel:

$ cd /etc/opendkim
$ sudo opendkim-genkey -d beispiel.de -b 2048 -r -s 202111
$ sudo mv 202111.private keys/beispiel.de.private
$ sudo mv 202111.txt keys/beispiel.de.txt

Dann sorgen wir dafür, dass nur der Benutzer opendkim Zugriff auf die Schlüssel hat:

$ sudo chown -R opendkim:opendkim /etc/opendkim
$ sudo chmod -R go-rwx /etc/opendkim/keys

Jetzt musst Du bei Deinem DNS-Provider eine neue Sub-Domäne 202111._domainkey.beispiel.de anlegen und dort den TXT-Inhalt aus der Datei /etc/opendkim/keys/beispiel.de.txt als zusätzlichen DNS-Eintrag vom Typ TXT hinterlegen. Es folgt ein beispielhafter Inhalt:

202111._domainkey       IN      TXT     ( "v=DKIM1; h=sha256; k=rsa; s=email; "
          "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzVw/YHBQiT00WNEkNAT5kbmkRkpCdHIJBoCtTlNJJyNUXQw3+zhetdah3XD28THzZhW3yfFWiy1HUOFt9oEbIL17uLM4n8cFhossgckaVIupByYp1582oOze4fBDM3zyxunyw4EVY8ove7PvtDtMyBm+4alBhfQyKrKy3aabWK32X6C6sDC1DMnQ/05xT5FOK7isef+BUWXGXS"
          "s1mVf+g4OtxN9retO+jrDlAH3K43h1Sey8HpA8g2vD6cQBc091b5rUqFL1zSdcDkJ104kUqQ4Bn5kQpct9Zxtkh/3zat47vEC9IYtITdQ4pQUHoknkBhw+4LBxtSLiEqoe63x5TQIDAQAB" )  ; ----- DKIM key 202111 for beispiel.de		  

Achtung: Du darfst nur den Inhalt zwischen den Klammern kopieren!

Hast Du die Änderung bei Deinem DNS-Provider erfolgreich durchgeführt, kannst Du mittels DKIM Record Checker prüfen, ob alles ok ist. Bitte beachte, dass es einige Stunden dauern kann, bis die Sub-Domäne im Internet allgemein verfügbar ist.

Die Konfiguration für OpenDKIM ist damit abgeschlossen. Wir starten jetzt OpenDKIM neu:

$ sudo service opendkim restart

Ein erster Test:

$ opendkim-testkey -d beispiel.de -s 202111 -vvv

Wenn alles glatt läuft, bekommen wir folgendes Ergebnis:

$ opendkim-testkey: using default configfile /etc/opendkim.conf
$ opendkim-testkey: checking key '202111._domainkey.beispiel.de'
$ opendkim-testkey: key not secure
$ opendkim-testkey: key OK

Prima, jetzt müssen wir nur noch Postfix Bescheid geben, dass ausgehende E-Mails mittels OpenDKIM signiert werden sollen.

$ sudo nano /etc/postfix/main.cf

Füge folgenden Inhalt hinzu und speichere die Datei:

# DKMI filter
milter_default_action = accept
milter_protocol = 6
smtpd_milters = inet:localhost:8892
non_smtpd_milters = inet:localhost:8892

Zum Abschluss starten wir Postfix neu:

$ sudo service postfix restart

DMARC

Domain-based Message Authentication, Reporting & Conformance (DMARC) ist eine Spezifikation, die den Einsatz von SPF und DKMI fordert und darüber hinaus Richtlinien definiert, wie genau beide Verfahren zur Authentifizierung einer einkommenden E-Mail eingesetzt werden sollen und was im Fehlerfall passieren soll.

Die Implementation von DMARC ist recht einfach:

  • Konfiguriere SPF und DKMI (das haben wir ja schon gemacht)
  • Lege bei Deinem DNS-Provider eine neue Sub-Domäne _dmarc.beispiel.de.
  • Füge dieser neuen Sub-Domäne einen zusätzlichen DNS-Eintrag vom Typ TXT mit dem Wert v=DMARC1\; p=quarantine\; rua=mailto:postmaster@beispiel.de hinzu.

Eine gute Hilfe beim Generieren von DMARC-Einträgen bietet Dir der folgende DMARC Record Generator.

List-Unsubscribe-Header

Der List-Unsubscribe Header ist in RFC 2369 spezifiziert. Mit diesem optionalen Header wird dem E-Mail-Empfänger ein Link zum Abmelden präsentiert, ähnlich dem obligatorischen Abmeldelink bei Newsletter-E-Mails. Damit kann der E-Mail-Empfänger bestimmen, dass er zukünftig keine E-Mails von dieser Absenderadresse erhalten möchte. Der List-Unsubscribe Header macht Sinn, wenn die E-Mail beispielsweise Teil einer Mailingliste ist.

In unserem Fall benötigen wir keinen List-Unsubscribe Header und lassen die Implementation deshalb weg.

MX-Record

Ein Mail Exchange Resource Record (MX-Record) definiert, unter welchem Fully Qualified Domain Name (FQDN) der E-Mailserver für eine bestimmte Domäne erreichbar ist. Dazu musst Du bei Deinem DNS-Provider für die Domäne beispiel.de einen zusätzlichen DNS-Eintrag vom Typ MX hinzufügen. Dieser sollte in unserem Fall folgenden Wert haben:

MX 10 smtp.beispiel.de

Ein erneuter Test

Ein erneuter Test mit MailGenius ergibt nun folgendes Bild:

Analyseergebnis für Postfix-Standardkonfiguration

Analyseergebnis für Postfix-Standardkonfiguration

Das sieht gut aus. Die verbliebene Warnung haben wir selbst provoziert.

Authentifizierung: SASL

Bisher haben wir E-Mails lokal von unserem Postfix-Server verschickt. Jetzt wollen wir E-Mails von einem Remote-SMTP-Client aus über smtp.beispiel.de verschicken. Dazu installieren wir Cyrus SASL, eine Open-Source-Implementation des Simple Authentication and Security Layer (SASL).

$ sudo apt install libsasl2-modules sasl2-bin

Als nächstes legen wir folgende Datei an:

$ sudo nano /etc/postfix/sasl/smtpd.conf

Kopiere folgenden Inhalt hinein und speichere diese Datei:

pwcheck_method: auxprop
auxprop_plugin: sasldb
mech_list: plain login

Als nächstes öffnen wir folgende Datei:

$ sudo nano /etc/default/saslauthd

Ändere den Parameter MECHANISMS wie folgt ab und speichere diese Datei:

MECHANISMS="sasldb"

Starte den SASL-Dienst neu:

$ sudo service saslauthd restart

Jetzt legen wir ein neues SASL-Konto mit Namen postfix an:

$ sudo saslpasswd2 -c -u smtp.beispiel.de postfix

Jetzt müssen wir Postfix Bescheid geben, dass SMTP-Clients sich per SASL authentifizieren können.

$ sudo nano /etc/postfix/main.cf

Füge folgenden Inhalt hinzu und speichere die Datei:

# SMTP server SASL configuration
smtpd_sasl_auth_enable = yes
smtpd_sasl_path = smtpd
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $mydomain
broken_sasl_auth_clients = yes

SASL-Konten werden in einer Datenbankdatei unter /etc/sasldb2 abgelegt. Postfix benötigt /etc/sasldb2 in seiner chroot-Umgebung. Dazu kopieren wir diese Datei in das Startup-Skript von Postfix. Öffne folgende Datei:

$ sudo nano /usr/lib/postfix/configure-instance.sh

Erweitere die Zeile

FILES="etc/localtime etc/services etc/resolv.conf etc/hosts \
  etc/host.conf etc/nsswitch.conf etc/nss_mdns.config"

wie folgt:

FILES="etc/localtime etc/services etc/resolv.conf etc/hosts \
  etc/host.conf etc/nsswitch.conf etc/nss_mdns.config etc/sasldb2"

Speichere die Datei und starte Postfix neu:

$ sudo service postfix restart

Noch ein paar Tipps:

  • Ein SASL-Konto testen:

    $ sudo testsaslauthd -u postfix -p qwertz -r smtp.beispiel.de
    
  • Alle SASL-Konten auflisten:

    $ sudo sasldblistusers2 
    
  • Einen SASL-Konto löschen:

    $ sudo saslpasswd2 -d -u smtp.beispiel.de postfix
    
  • Einen SASL-Konto aktualisieren (also das Kennwort ändern):

    $ sudo saslpasswd2 -u smtp.beispiel.de postfix
    

Authentifizierung: Trusted networks

Eine Alternative zur Authentifizierung via SASL ist, externen E-Mail-Clients, die unter der eigenen Kontrolle sind, explizit zu vertrauen. Grundlage ist die IP-Adresse des Clients. Dazu öffnen wir erneut die Postfix-Konfiguration:

$ sudo nano /etc/postfix/main.cf

Dort erweitern wir den Parameter mynetworks wie folgt und speichern die Datei:

mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 ${config_directory}/trusted-network

Anschließend legen wir eine neue Datei an:

$ sudo nano /etc/postfix/trusted-networks

Dort kopieren wir alle IP-Adressen rein, von denen aus ohne SASL-Authentifizierung E-Mails an unseren Postfix-Server verschickt werden darf (die IP-Adresse ist natürlich wieder nur ein Beispiel):

159.69.60.4/32

Anschließend starten wir Postfix neu:

$ sudo service postfix restart

TLS-Verschlüsselung

Transport Layer Security (kurz TLS) ist ein Verschlüsselungsverfahren zum sicheren Übertragen von Daten über öffentliche Netzwerke. Bekannter ist es immer noch unter dem alten Namen SSL (Secure Sockets Layer). TLS ist die Grundlage für das Übertragungsprotokoll HTTPS, einer Erweiterung des HTTP-Protokolls, das die Übertragung von Daten verschlüsselt.

TLS kann aber auch zur Verschlüsselung der Datenübertragung via SMTP verwendet werden. In diesem Fall spricht man auch von SMTPS (Simple Mail Transfer Protocol Secure).

Wir wollen jetzt die Kommunikation mit smtp.beispiel.de mittels TLS verschlüsseln. Dazu benötigen wir ein weiteres Werkzeug namens Certbot. Certbot ist ein Open Source Werkzeug zum automatisierten Erzeugen von TLS-Zertifikaten durch Let’s Encrypt.

Eine Installation unter Ubuntu geht wie folgt:

$ sudo apt install certbot

Und dann kann es auch schon losgehen. Mit dem folgenden Befehl erstellen wir ein Zertifikat für smtp.beispiel.de

$ sudo certbot certonly --standalone -d smtp.beispiel.de

Beim aller ersten Einsatz von Certbot musst Du zunächst ein paar Fragen beantworten. Certbot fragt Dich nach Deiner E-Mail-Adresse zur Registrierung bei Let’s Encrypt. Bei Problemen (z.B. bei nicht durchgeführter Erneuerung eines Zertifikats) oder Missbrauch wirst Du automatisch von Let’s Encrypt per E-Mail benachrichtigt.

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel):

Anschließend möchte Certbot, dass Du Dir die Nutzungsbedingungen (Terms of Service) von Let’s Encrypt durchliest und diesen zustimmst.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel:

Die nächste Frage kann man getrost mit No beantworten.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o:

Und jetzt kommt der interessante Teil. Certbot beginnt damit, ein neues TLS-Zertifikat von Let’s Encrypt zu erfragen. Das sieht dann in etwa so aus.

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for smtp.beispiel.de
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/smtp.beispiel.de/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/smtp.beispiel.de/privkey.pem
   Your cert will expire on 2022-02-06. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - If you like Certbot, please consider supporting our work by: 

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

Jetzt müssen wir Postfix das neue Zertifikat bekannt geben. Dazu öffnen wir wieder die Postfix-Konfiguration:

$ sudo nano /etc/postfix/main.cf

Ersetze folgende Standardwerte:

# TLS parameters
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_tls_security_level=may

smtp_tls_CApath=/etc/ssl/certs
smtp_tls_security_level=may
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

mit folgenden Werten:

# SMTP server TLS configuration
smtpd_tls_security_level = encrypt
smtpd_tls_auth_only = yes
smtpd_tls_cert_file=/etc/letsencrypt/live/smtp.beispiel.de/fullchain.pem
smtpd_tls_key_file=/etc/letsencrypt/live/smtp.beispiel.de/privkey.pem
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_mandatory_ciphers = medium
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtpd_tls_dh1024_param_file = ${config_directory}/dh2048.pem

# SMTP client TLS configuration
smtp_tls_security_level = may
smtp_tls_loglevel = 1
smtp_tls_note_starttls_offer = yes
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

# OpenSSL cipherlist for "medium" or higher grade ciphers
tls_medium_cipherlist = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
tls_preempt_cipherlist = no

Bei der TLS-Konfiguration von Postfix haben wir den Mozilla SSL Configuration Generator zu Rate gezogen.

Zusätzlich erzeugen wir eine starke Diffie-Hellman-Gruppe (DH-Gruppe), um Perfect Forward Secrecy implementieren zu können:

$ sudo openssl dhparam -out /etc/postfix/dh2048.pem 2048

Das dauert etwas, aber wenn der Prozess fertig ist, hast Du eine starke DH-Gruppe unter /etc/nginx/dhparam.pem gespeichert. Diese Datei ist als Verweis in unserer Postfix-Konfiguration eingetragen.

Wenn wir zukünftig per TLS mit unserem Postfix-Server kommunizieren wollen, dann sollten wir nicht mehr den Standard-Port 25 verwenden, sondern stattdessen den Submission-Port 587. Öffne dazu folgende Datei:

$ sudo nano /etc/postfix/master.cf

Ersetze folgenden Standardinhalt

smtp       inet  n       -       y       -       -       smtpd
#smtp      inet  n       -       y       -       1       postscreen
#smtpd     pass  -       -       y       -       -       smtpd
#dnsblog   unix  -       -       y       -       0       dnsblog
#tlsproxy  unix  -       -       y       -       0       tlsproxy
#submission inet  n       -       y       -       -       smtpd

mit:

#smtp      inet  n       -       y       -       -       smtpd
#smtp      inet  n       -       y       -       1       postscreen
#smtpd     pass  -       -       y       -       -       smtpd
#dnsblog   unix  -       -       y       -       0       dnsblog
#tlsproxy  unix  -       -       y       -       0       tlsproxy
submission inet  n       -       y       -       -       smtpd

Anschließend starten wir Postfix neu:

sudo service postfix restart

Eine Sache ist noch offen. Die TLS-Zertifikate von Let’s Encrypt sind nur drei Monate gültig und sollten durch Automation regelmäßig erneuert werden. Dazu richten wir uns einen CronJob ein.

Erzeuge oder öffne folgende Datei:

$ sudo nano crontab

Füge folgenden Befehl ein und speichere die Datei:

14 6 * * * root certbot renew --post-hook "service postfix reload"

Wir haben jetzt einen CronJob eingerichtet, der unser TLS-Zertifikat alle 14 Tage automatisch überprüft und bei Bedarf erneuert.

Absenderadressen kontrollieren

Standardmäßig kann ein SMTP-Client eine beliebige Absenderadresse angeben. Das liegt daran, dass der Postfix-SMTP-Server nur den Hostnamen und die IP-Adresse des Remote-SMTP-Clients kennt, nicht jedoch den Benutzer, der den Remote-SMTP-Client steuert.

Dies ändert sich in dem Moment, in dem ein SMTP-Client die SASL-Authentifizierung verwendet. Nun weiß der Postfix SMTP-Server, wer der Absender ist. Anhand einer Tabelle mit Absenderadressen und SASL-Konten kann der Postfix-SMTP-Server entscheiden, ob der SASL-authentifizierte Client eine bestimmte Absenderadresse verwenden darf oder nicht.

Dazu erstellen wir die folgende Datei:

$ sudo nano /etc/postfix/controlled_envelope_senders

Dort tragen wir alle gültigen Absenderadressen und deren Abbildung auf einen SASL-Benutzer ein. Im folgenden Beispiel werden die Absenderadressen helpdesk@beispiel.com, contact@beispiel.com und contact@beispiel.de auf den SASL-Benutzer postfix@beispiel.de abgebildet. Auch das Nutzen von regulären Ausdrücken ist erlaubt:

helpdesk@beispiel.com                         postfix@beispiel.de
/^contact@(beispiel[.]de|beispiel[.]com)$/    postfix@beispiel.de

Dann öffnen wir die Postfix-Konfiguration:

$ sudo nano /etc/postfix/main.cf

Dort fügen wir folgenden Parameter hinzu und speichern die Datei.

smtpd_recipient_restrictions = reject_unknown_recipient_domain

Dann aktualisieren wir die Lookup-Tabellen von Postfix mit folgendem Befehl:

$ sudo postmap /etc/postfix/controlled_envelope_senders

Anschließend starten wir Postfix neu:

$ sudo service postfix restart

Firewall

Als letzte Maßnahme wollen wir die Ubuntu-Firewall konfigurieren.

Die Installation erfolgt wie folgt:

$ sudo apt-get install ufw

Standardmäßig ist die Firewall deaktiviert. Wir konfigurieren sie (beispielhaft) wie folgt und aktivieren sie anschließend.

$ sudo ufw default deny incoming
$ sudo ufw allow ssh
$ sudo ufw allow 587/tcp
$ sudo ufw enable

Was haben wir gemacht?

Wir haben zunächst alle einkommenden Anfragen geblockt. Anschließend haben wir die Protokolle ssh (Port 22) und Mail submission (Port 587) wieder geöffnet. Zu guter Letzt haben wir die Firewall aktiviert.

Damit Certbot seine TLS-Zertifikate erneuern kann, benötigen wir zusätzlich einen temporären Zugriff auf HTTP (Port 80). Wir nutzen dafür die Hook-Unterstützung von Certbot.

Öffne folgende Datei:

$ sudo nano /etc/letsencrypt/cli.ini

Füge folgenden Inhalt hinzu und speichere die Datei.

# Manage Firewall
pre-hook = ufw allow http
post-hook = ufw deny http

# Reload Postfix
renew-hook = service reload postfix

Was haben wir gemacht?

Wir haben uns in den Workflow von Certbot eingeklingt. Bei jedem Renewal-Start wird zunächst Port 80 freigegeben, dann wird der Renewal-Prozess durchgeführt. Anschließend wird Port 80 wieder blockiert und Postfix gezwungen, seine Konfiguration neu einzulesen.

Noch ein paar Tipps:

  • Status der Firewall abfragen:

    $ sudo ufw status
    
  • Die Firewall wieder deaktivieren:

    $ sudo ufw disable
    

Die komplette main.cf

Wir haben die Konfigurationsdatei /etc/postfix/main.cf jetzt so häufig geändert, dass man schnell durcheinander kommt. Hier eine sauber redigierte Version für unseren Postfix-Server:

smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
biff = no
append_dot_mydomain = no
readme_directory = no
compatibility_level = 2
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myhostname = smtp.beispiel.de
myorigin = /etc/mailname
mydestination = $myhostname, beispiel.de, localhost
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 ${config_directory}/trusted-networks
relayhost =
mailbox_command = procmail -a "$EXTENSION"
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all

# Only trusted networks and SASL authenticated clients allowed
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination

# Only known recipients allowed
smtpd_recipient_restrictions = reject_unknown_recipient_domain

# SMTP server SASL configuration
smtpd_sasl_auth_enable = yes
smtpd_sasl_path = smtpd
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $mydomain
broken_sasl_auth_clients = yes

# SMTP server TLS configuration
smtpd_tls_security_level = encrypt
smtpd_tls_auth_only = yes
smtpd_tls_cert_file=/etc/letsencrypt/live/smtp.beispiel.de/fullchain.pem
smtpd_tls_key_file=/etc/letsencrypt/live/smtp.beispiel.de/privkey.pem
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_mandatory_ciphers = medium
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtpd_tls_dh1024_param_file = ${config_directory}/dh2048.pem

# SMTP client TLS configuration
smtp_tls_security_level = may
smtp_tls_loglevel = 1
smtp_tls_note_starttls_offer = yes
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

# OpenSSL cipherlist for "medium" or higher grade ciphers
tls_medium_cipherlist = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
tls_preempt_cipherlist = no

# DKMI filter
milter_default_action = accept
milter_protocol = 6
smtpd_milters = inet:localhost:8892
non_smtpd_milters = inet:localhost:8892
Das könnte dich auch interessieren:
  1. PostgreSQL 14 unter Ubuntu-Server
  2. UniFi Network Controller unter Ubuntu
  3. HTTPS unter nginx/Ubuntu
  4. Ubuntu Server 20.04 installieren
  5. HTTPS unter Apache/Ubuntu
Teile diesen Artikel
comments powered by Disqus