Postfix TLS Perfect Forward Secrecy

Abstract

Dank #prism ist Forward Secrecy für E-Mail gerade in aller Munde. Ich habe mal die relevanten Informationen für Postfix zusammengetragen, damit man nicht lange suchen muss.

Dank #prism ist Forward Secrecy für E-Mail gerade in aller Munde. Ich habe mal die relevanten Informationen für Postfix zusammengetragen, damit man nicht lange suchen muss. Aber erst mal ein wenig Schlau machen…

Was ist Forward Secrecy?

Wikipedia beschreibt Forward Secrecy wie folgt: Folgenlosigkeit (englisch Perfect Forward Secrecy, PFS; auf deutsch etwa perfekt fortgesetzte Geheimhaltung) bedeutet in der Kryptographie die Eigenschaft von Verschlüsselungsverfahren, dass aus einem aufgedeckten Schlüssel nicht auf vorhergehende oder nachfolgende Schlüssel eines Kommunikationskanals geschlossen werden kann.

In anderen Worten: Sollte jemand den verschlüsselten Datenverkehr mitgeschnitten haben, kann dieser – selbst wenn der Key kompromittiert wurde (!) – nachträglich nicht mehr entschlüsselt werden.

Wie muss man Postfix dazu konfigurieren?

Technische Voraussetzung für Forward Secrecy sind zusätzliche, temporäre Einmalschlüssel, die für ephemeral Diffie-Hellman (EDH) Verschlüsselung geeignet sind. Wer OpenSSL >= 1.0.0 und Postfix >= 2.6.0 einsetzt, kann sie einfach generieren. Auf der Kommandozeile wird dazu ein Satz DH-Parameterdateien generiert – 1024-Bit für non-export und 512-Bit für export ciphers:

% openssl gendh -out /etc/postfix/dh_512.pem -2 512
% openssl gendh -out /etc/postfix/dh_2048.pem -2 2048

Diese Schlüssel werden dann, ergänzend zu einer bereits bestehenden TLS-Konfiguration für den Postfix smtpd SMTP-Server, so eingebunden:

smtpd_tls_dh1024_param_file = ${config_directory}/dh_2048.pem
smtpd_tls_dh512_param_file = ${config_directory}/dh_512.pem

# Postfix ≥ 2.6 für elliptic curve cryptography:
smtpd_tls_eecdh_grade = strong

Important

Debian hat in der Vergangenheit GnuTLS gepatcht und die minimal akzeptable Anzahl an Bits von 1024 auf 2048 hochgesetzt. Das führt zu Problemen in der Kommunikation mit anderen Servern. Der Workaround besteht darin, Postfix von vornherein ein Diffie-Hellman Cert mit 2048 Bit an die Hand zu geben.

Note

Viktor Dukhovni schreibt zusätzlich in Exim, DH, GnuTLS & interop: If your openssl(1) version is 1.0.0 or higher, your server may perform faster if you generate DSA-style parameters:

% openssl dhparam -dsaparam -out dh_2048.pem 2048

Alte Software wie z.B. Netscape 7 kommt mit 2048-Bit EDH nicht klar. In so einem Fall muss man auf den Ports 465 und 587 (mit denen solche Clients reden) mit 1024-Bit EDH betreiben:

% openssl dhparam -out dh1024.pem 1024
% postconf -e 'submission_tls_dh1024_param_file = ${config_directory}/dh1024.pem'

Und in der master.cf:

465 inet n ... smtpd
  -o smtpd_tls_wrappermode=yes
  -o smtpd_tls_dh1024_param_file=$submission_tls_dh1024_param_file
  ...
587 inet n ... smtpd
  -o smtpd_tls_dh1024_param_file=$submission_tls_dh1024_param_file
  ...

Damit der Server die neue EDH-Verschlüsselungsmethode wählt und der Client nicht selbst und frei (das Falsche) wählen darf, kommt noch der tls_preempt_cipherlist-Parameter (ab Postfix >= 2.8.0) hinzu:

tls_preempt_cipherlist = yes

Important

Das kann bei broken clients zu Verbindungsproblemen führen. Wenn diese eine statische IP besitzen, kann man diese mit smtpd_discard_ehlo_keyword_address_maps davon abhalten, wieder und wieder gegen eine Wand zu rennen...

Damit wird der Liste des Servers Vorrang gegeben. Voraussetzung dafür ist (mindestens) eine SSLv3-Verbindung. Ältere Standards wie z.B. SSLv2 lassen dem Client die Wahl der Verschlüsselungsmethode. SSLv2 will ohnehin niemand haben, weil es nicht brauchbar sicher ist. In der main.cf weist man den Server deshalb an, sie gar nicht in die Liste würdiger Standards aufzunehmen:

smtpd_tls_protocols = !SSLv2

SMTP Forward Secrecy testen

Mit dem openssl-Kommando und dessen s_client lässt sich dann abschließend einfach testen, ob jetzt ECDHE-Chiffren zum Einsatz kommen:

$ openssl s_client -CAfile /etc/ssl/certs/ca-certificates.crt -starttls \
        smtp -connect mail.sys4.de:25
...
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : ECDHE-RSA-AES256-SHA
    Session-ID: 37751B6CA3687E6477827A3D29AEC162B470990429FFF0245F0B57FC3B66DCB2
    Session-ID-ctx:
    Master-Key: 8C1882D9F7C4916AEA6EFCE45CA950EC260D34FAC40C4717CCFAF5150A87A693
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 3600 (seconds)
    TLS session ticket:
    0000 - 69 0e 9c e5 42 97 33 71-e2 31 26 35 95 b5 42 fd   i...B.3q.1&5..B.
    0010 - 05 b5 d7 d0 53 f6 23 13-2e d6 e9 be 46 62 45 c7   ....S.#.....FbE.
    0020 - 90 a2 d5 b4 c0 e3 cc 3c-4b 94 6a af 07 25 be 1b   .......<K.j..%..
    0030 - 44 ce a0 0a d8 df e4 73-34 bc 8e 88 c2 e8 28 84   D......s4.....(.
    0040 - 89 8a 99 cc a4 15 f6 4e-58 92 53 7f 92 77 20 b3   .......NX.S..w .
    0050 - 78 ec 9b 03 74 be d7 8f-ae 46 6d 5f e6 8a 6d cb   x...t....Fm_..m.
    0060 - 60 03 b9 a4 95 78 7e fd-e4 94 40 ea 77 10 95 21   `....x~...@.w..!
    0070 - 32 6c b1 7d 1e 5a 29 ec-ae d7 a3 a3 05 84 de dc   2l.}.Z).........
    0080 - e0 6b e4 c1 84 43 4e 62-9f b5 bc ff a8 f9 99 6d   .k...CNb.......m
    0090 - a8 b2 40 8c ef 2b 44 28-ea fb 37 b6 4b 48 0d 8d   ..@..+D(..7.KH..

    Start Time: 1376481129
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---
250 DSN
QUIT

Nach einer Weile lassen sich dann auch entsprechende Verbindungen im LOG nachweisen:

$ zegrep "TLS connection established from.*with cipher.*ECDHE" /var/log/mail.log | \
        awk '{printf("%s %s %s %s\n", $12, $13, $14, $15)}' | sort | uniq -c | sort -n
      5 TLSv1 with cipher ECDHE-RSA-AES128-SHA
     17 TLSv1 with cipher ECDHE-RSA-AES256-SHA
    155 TLSv1 with cipher ECDHE-RSA-RC4-SHA
Ralf Hildebrandt, 14. August 2013

   postfix    tls    prism    pfs