Postfix-TLS-Optionen

Die Einstellung der TLS-Optionen der E-Mail-Servers Postfix ist nicht gerade trivial. Dieser Beitrag versucht, die Hintergründe der wichtigsten Verschlüsselungsoptionen von Postfix ein wenig zu erhellen. Dabei beziehe ich mich auf Ubuntu 14.04 und 16.04. Sinngemäß sollten die meisten Informationen aber auch für Postfix-Installationen auf anderen Distributionen gelten.

Vorbemerkungen

Vorweg eine kurze Einordnung: Postfix ist ein Mail Transfer Agent (MTA), also umgangssprachlich ein Mail-Server. Es gibt natürlich auch andere MTAs (z.B. sendmail), aber bei vielen aktuellen Linux-Distributionen ist Postfix heute das Default-Programm. (Werfen Sie eventuell auch einen Blick auf diese Statistik. Leider verrät die Seite nicht, wann die Daten erfasst wurden und wie groß die Datenbasis war.)

Die wichtigste Konfigurationsdatei von Postfix ist /etc/postfix/main.cf. Eine umfassende Dokumentation zu den vielen zulässigen Parametern gibt man 5 postconf.

An dieser Stelle konzentriere ich mich auf einige wenige Optionen. Sie steuern, wie Postfix den Datenverkehr beim Versenden (outgoing) und Empfangen (incoming) von Mails verschlüsselt. Dabei gilt folgende Regel:

  • smtp_xxx-Optionen gelten für den Versand (also outgoing aus der Sicht der MTAs)
  • smtpd_xxx-Optionen betreffen den Empfang (also incoming aus der Sicht des MTAs; smtpd ist der SMTP-Dämon, der im Hintergrund darauf wartet, Nachrichten entgegenzunehmen)

Beachten Sie, dass sich bei der Verschlüsselung der Mail-Daten immer zwei Server einig werden müssen: Ein Server, der die Nachricht sendet, und ein zweiter Server, der die Nachricht erhält. Was nützt es, wenn der eine Server bereit ist, die Mail verschlüsselt zu übertragen, der andere Server dazu aber nicht in der Lage ist? Oder wenn die beiden Server sich nicht auch ein gemeinsames Verschlüsselungsprotokoll einigen können?

Im Prinzip erfolgt die Verschlüsselung beim Mail-Versand zwischen Server so ähnlich wie zwischen einem Webserver und einem Webbrowser, wenn HTTPS zum Einsatz kommt. Es gibt aber einen Unterschied: Im Web achten gängige Webbrowser peinlich genau darauf, dass das Zertifikat der Webservers korrekt ist: Es darf nicht abgelaufen sein, der Hostname des Servers muss exakt mit dem des Zertifikats übereinstimmen, und das Zertifikat muss von einer anerkannten Zertifizierungsstelle (CA = Certification Authority) ausgestellt sein.

Mail-Server agieren in dieser Hinsicht wesentlich lockerer: Höchste Priorität hat es, dass der Datenfluss überhaupt verschlüsselt wird. Deswegen akzeptieren die meisten Mail-Server beim Empfang einer Mail die Verschlüsselung auch dann, wenn der sendende Server ein selbst signiertes Zertifikat zum Einsatz kommt, wenn dieses schon abgelaufen ist etc.

Hinweis: Nicht Thema dieses Beitrags ist die Verschlüsselung beim Abruf von E-Mails durch den Mail-Client. Dabei sind andere Programme und Protokolle im Spiel, z.B. Dovecot und IMAP (immer seltener auch POP3). Ebenfalls nicht Thema dieses Beitrags ist die Verschlüsselung der Mail an sich durch PGP oder S/MIME. Es geht hier nur darum, dass zwei Mail-Server verschlüsselt miteinander kommunizieren.

Verschlüsselung beim Versenden (outgoing, smtp-Optionen)

Das folgende Listing zeigt die für die outgoing-Verschlüsselung notwendigen Einstellungen. (Vorsicht: Bei einer Defaultkonfiguration unter Debian/Ubuntu fehlt normalerweise die erste Zeile. Postfix sendet deswegen unverschlüsselt!)

# Datei /etc/postfix/main.cf
smtp_tls_security_level = may
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
# optional zur Fehlersuche
smtp_tls_loglevel = 1

smtp_tls_security_level = may bedeutet, dass Postfix Mails nach Möglichkeit verschlüsselt versendet, sofern der Empfänger (also der Mail-Server auf der anderen Seite) dazu in der Lage ist. Zur Not wird die Nachricht aber auch im Klartext übertragen. Sicherer wäre smtp_tls_security_level = encrypt — aber dann kann Ihr Mail-Server keine Nachrichten mehr an Mail-Server senden, die keine Verschlüsselung unterstützen.

Der smtp_tls_loglevel gibt an, wie ausführlich die Kommunikationsdetails protokolliert werden sollen. Ein Log-Level größer 0 hilft bei der Fehlersuche. Der zulässige Wertebereich reicht von 0 (kein Logging) bis 4 (Hex- und ASCII-Dumps der gesamten Kommunikation; Vorsicht: führt zu riesigen, weitgehend unlesbaren Logging-Dateien).

smtp_tls_session_cache_database gibt an, wo TLS-Session-Informationen zwischengespeichert werden sollen. Die Datenbank wird von mehreren Postfix-Instanzen gemeinsam genutzt. Sie beschleunigt die TLS-Kommunikation erheblich. Unter Debian und Ubuntu befindet sich das Postfix Data Directory in /var/lib/postfix. Die Session-Datenbank landet daher in der Datei /var/lib/postfix/smtp_scache.db.

smtp_tls_CAfile gibt schließlich den Ort einer Datei an, in der sich eine Referenz aller CAs befindet, denen der Mail Server vertrauen soll. Unter Debian und Ubuntu wird eine derartige Datei durch das Kommando update-ca-certificates aggregiert und dann in /etc/ssl/certs/ca-certificates.crt gespeichert. (Die zugrundeliegenden Einzeldateien befinden sich ebenfalls im Verzeichnis /etc/ssl/certs.)

Postfix läuft allerdings in einer chroot-Umgebung und hat gar keinen Zugriff auf /etc/ssl/certs. Deswegen wird ca-certificates.crt beim Start von Postfix durch das Init-System in das chroot-Verzeichnis /var/spool/postfix/etc/ssl/certs kopiert. Der Dateiname in smtp_tls_CAfile ist relativ zum chroot-Verzeichnis.

Wenn smtp_tls_CAfile nicht eingestellt wird, dann werden beim Senden von Mails die Nachricht Untrusted TLS connection protokolliert. Das bedeutet, dass die Nachricht zwar verschlüsselt übertragen wurde, dass Postfix aber das Zertifikat des anderen Mail-Servers nicht verifizieren konnte:

Nov 11 17:36:20 host1 postfix/smtp[12047]: Untrusted TLS connection established to gmail-smtp-in.l.google.com[2607:f8b0:4002:c03::1b]:25: TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)

Mit der korrekten Einstellung von smtp_tls_CAfile und vorausgesetzt, dass das Zertifikat des Empfänger-Servers durch eine CA ausgestellt wurde, der in ca-certificates.crt enthalten ist, ändert sich der Logging-Eintrag zu Trusted TLS connection:

Nov 11 17:39:04 host1 postfix/smtp[12222]: Trusted TLS connection established to gmail-smtp-in.l.google.com[209.85.144.26]:25: TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)

Hilfe bei der Interpretation von Untrusted, Trusted etc. gibt die FORWARD-SECRECY-README-Seite der Postfix-Dokumentation.

Verschlüsselung beim Empfang (incoming, smtpd-Optionen)

Die folgenden Zeilen zeigen Grundeinstellung zum verschlüsselten Versand von Mails:

# Datei /etc/postfix/main.cf
smtpd_tls_security_level = may
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
# optional zur Fehlersuche
smtpd_tls_loglevel = 1

smtpd_tls_security_level = may aktiviert die Verschlüsselung, sofern der Sender-Mail-Server die Nachricht verschlüsselt senden kann. Ist das nicht der Fall, wird die Mail unverschlüsselt übertragen. Sicherer wäre smtpd_tls_security_level = encrypt — aber dann ist das Versenden von Mails an schlecht konfigurierte Mail-Server eben unmöglich.

smtpd_tls_cert_file und smtpd_tls_key_file geben die Dateinamen des Zertifikats und des Schlüssels an. Standardmäßig verwendet Postfix unter Debian und Ubuntu ein selbst signiertes, für 10 Jahre gültiges Snakeoil-Zertifikat. Wenn Sie über ein »richtiges« Zertifikat verfügen, müssen Sie die beiden Optionen entsprechend ändern. Wie Sie an dieser Stelle Let’s-Encrypt-Zertifikate verwenden können, habe ich in diesem Blog-Beitrag schon vor einiger Zeit beschrieben. Analog können Sie natürlich auch von einer kommerziellen CA erworbene Schlüssel verwenden.

smtpd_tls_session_cache_database gibt wie der entsprechende smtp_xxx-Parameter den Ort einer Caching-Datenbank an. Das steigert die Effizienz/Geschwindigkeit.

Wenn Ihr Mail-Server jetzt eine Mail empfängt, sollte in /var/log/mail.log ein Eintrag nach dem folgenden Muster erscheinen:

Nov 11 19:51:47 ub postfix/smtpd[10999]: Anonymous TLS connection established from mail-wm0-f53.google.com[74.125.82.53]: TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)

Auch wenn Anonymous TLS vielleicht eine nicht optimale Sicherheit vermuten lässt, ist die Meldung kein Indikator dafür, dass die Verschlüsselung nicht OK wäre. Vielmehr verzichtet Postfix standardmäßig darauf, das Zertifikat des Clients (des Mail-Senders) zu überprüfen. Hilfe bei der Interpretation von Anonymous TLS
gibt die FORWARD-SECRECY-README-Seite der Postfix-Dokumentation.

Entscheidend ist vielmehr, dass in den Logging-Dateien überhaupt ein TLS-Eintrag erscheint. Andernfalls wurde die Nachricht nämlich unverschlüsselt übertragen. Genau das ist der Fall, wenn der Eintrag smtpd_tls_security_level = may fehlt.

Forward Secrecy

Forward Secrecy bzw. Perfect Forward Secrecy bezeichnet ein kryptographisches Protokoll zum Schlüsselaustausch, das sicherstellt, dass eine früher aufgezeichnete Kommunikation später nicht rekonstruiert werden kann, selbst dann, wenn der damals verwendete Schlüssel mittlerweile kompromittiert oder geknackt ist. Dazu wird jede Kommunikation mit einen zeitlich nur kurzzeitig gültigen Schlüssel verschlüsselt.

Postfix unterstützt Forward Secrecy schon seit einigen Jahren. Bei aktuellen Versionen ist dazu nicht einmal eine besondere Konfiguration erforderlich — Forward Secrecy wird automatisch verwendet, sofern die Gegenseite mitspielt. In den Logging-Dateien lässt sich das anhand der eingesetzten Verschlüsselungsverfahren (Cipher) erkennen. Eine Liste von Forward-Secrecy-tauglichen Verschlüsselungsverfahren liefert openssl:

openssl ciphers -v \
  'aNULL:-aNULL:kEECDH:kEDH:+RC4:!eNULL:!EXPORT:!LOW:@STRENGTH' | 
  awk '{printf "%-32s %s\n", $1, $3}'

AECDH-AES256-SHA                 Kx=ECDH
ECDHE-RSA-AES256-GCM-SHA384      Kx=ECDH
ECDHE-ECDSA-AES256-GCM-SHA384    Kx=ECDH
ECDHE-RSA-AES256-SHA384          Kx=ECDH
ECDHE-ECDSA-AES256-SHA384        Kx=ECDH
ECDHE-RSA-AES256-SHA             Kx=ECDH
ECDHE-ECDSA-AES256-SHA           Kx=ECDH
ADH-AES256-GCM-SHA384            Kx=DH
ADH-AES256-SHA256                Kx=DH
ADH-AES256-SHA                   Kx=DH
ADH-CAMELLIA256-SHA              Kx=DH
DHE-DSS-AES256-GCM-SHA384        Kx=DH
DHE-RSA-AES256-GCM-SHA384        Kx=DH
DHE-RSA-AES256-SHA256            Kx=DH
...

Bei OpenSSL 1.0.2g unter Ubuntu 16.04 ergibt das obige Kommando eine Liste mit 51 Einträgen. Bei einer Mail, die ich von kofler.info an ubuntu-buch.info gesendet habe, wurde auf ubuntu-buch.info die folgende Nachricht in mail.log protokolliert:

Nov 13 14:58:26 ub postfix/smtpd[11753]: Anonymous TLS connection established from host1.kofler.info[138.201.20.187]: TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)

Es wurde also das Verschlüsselungsverfahren AECDH-AES256-SHA verwendet, das erste aus der obigen Liste der Forward-Secrecy-tauglichen Cipher. (AECDH = Anonymous Elliptic Curve Diffie Hellman, AES = Advanced Encryption Standard, SHA = Secure Hash Algorithm)

Um es nochmals zu betonen: Postfix nutzt Forward Secrecy ohne weitere Konfiguration. Für den für Forward Secrecy erforderlichen Schlüsselaustausch werden allerdings standardmäßig beim Kompilieren von Postfix vorgegebene Schlüssel verwendet. Sicherheitstechnisch noch besser ist es, stattdessen eigene Schlüssel zu generieren und main.cf um einige Zeilen zu erweitern, damit diese Schlüssel auch verwendet werden (Quellen: Postfix-Dokumentation, Blog auf heinlein-support.de).

Zur Erzeugung eigener Schlüssel führen Sie diese Kommandos aus:

cd /etc/postfix
umask 022
openssl dhparam -out dh512.tmp 512 && mv dh512.tmp dh512.pem
openssl dhparam -out dh1024.tmp 1024 && mv dh1024.tmp dh1024.pem
openssl dhparam -out dh2048.tmp 2048 && mv dh2048.tmp dh2048.pem
chmod 644 dh512.pem dh1024.pem dh2048.pem

Anschließend fügen Sie die folgenden zwei Zeilen in /etc/postfix/main.cf ein:

# Anpassung in /etc/postfix/main.cf für noch
# bessere Forward Secrecy
smtpd_tls_dh1024_param_file = ${config_directory}/dh2048.pem
smtpd_tls_dh512_param_file = ${config_directory}/dh512.pem

Quellen

Wikipedia

Postfix-Dokumentation

Blogs, Anleitungen & Co.

PS: Ich bin kein Kryptografie-Experte. Ich habe mich bemüht, die kryptografischen Details korrekt darzustellen. Sollte mir dabei ein Fehler unterlaufen sein, freue ich mich natürlich über Feedback!