IT security, FreeBSD, Linux, mail server hardening, post-quantum crypto, DNS, retro computing & hands-on hardware hacks. Privater Tech-Blog seit 2003.

Schlagwort: Encryption (Seite 2 von 8)

FreeBSD: Unverschlüsseltes ZFS-Dataset nachträglich verschlüsseln

Bild der Bücher FreeBSD Mastery ZFS und FreeBSD Mastery Advanced ZFS

ZFS Encryption lässt sich nicht nachträglich auf ein bestehendes Dataset aktivieren. Die Daten müssen per zfs send | zfs receive in ein neues, verschlüsseltes Dataset geschrieben werden. Typischer Anwendungsfall: Jails, die in eigenen Datasets liegen und nach einem FreeBSD-Upgrade auf 13+ verschlüsselt werden sollen.

Wer die Grundlagen zu ZFS Encryption noch braucht (Dataset anlegen, Passphrase, Mount nach Reboot), findet sie im Beitrag Native ZFS Encryption einrichten.

Ausgangslage

Ein Pool zroot mit dem unverschlüsselten Dataset varta:

zfs list zroot/varta
NAME          USED  AVAIL     REFER  MOUNTPOINT
zroot/varta   100M  12.0G      100M  /zroot/varta

zfs get encryption zroot/varta
NAME         PROPERTY    VALUE   SOURCE
zroot/varta  encryption  off     default

Migration

Bei zfs send | zfs receive kann man kein Passphrase interaktiv eingeben, weil stdin durch die Pipe belegt ist. Deshalb legt man den Schlüssel temporär in einer Datei ab:

echo 'MeinGeheimesPassphrase' > /tmp/keyfile.txt
chmod 600 /tmp/keyfile.txt

Snapshot erstellen und in ein neues verschlüsseltes Dataset senden:

zfs snapshot zroot/varta@migration

zfs send zroot/varta@migration | \
  zfs receive -F \
  -o encryption=on \
  -o keyformat=passphrase \
  -o keylocation=file:///tmp/keyfile.txt \
  zroot/en-varta

Das neue Dataset zroot/en-varta enthält jetzt dieselben Daten, verschlüsselt mit AES-256-GCM:

zfs list zroot/varta zroot/en-varta
NAME             USED  AVAIL     REFER  MOUNTPOINT
zroot/en-varta   100M  11.8G      100M  /zroot/en-varta
zroot/varta      100M  11.8G      100M  /zroot/varta

Aufräumen

Die Keyfile-Referenz auf Passphrase-Abfrage umstellen und die temporäre Datei löschen:

zfs set keylocation=prompt zroot/en-varta

zfs get keylocation zroot/en-varta
NAME            PROPERTY     VALUE   SOURCE
zroot/en-varta  keylocation  prompt  local

rm /tmp/keyfile.txt

Dann das alte Dataset entfernen und das neue umbenennen:

zfs destroy -r zroot/varta
zfs rename zroot/en-varta zroot/varta

Fertig. Das Dataset liegt jetzt verschlüsselt am selben Mountpoint wie vorher:

zfs get encryption,keylocation,keyformat zroot/varta
NAME         PROPERTY     VALUE        SOURCE
zroot/varta  encryption   aes-256-gcm  -
zroot/varta  keylocation  prompt       local
zroot/varta  keyformat    passphrase   -

Stolperfallen

Keyfile in /tmp ist ein Kompromiss. Auf FreeBSD-Default ist /tmp zwar ein tmpfs im RAM, aber bei Speicherdruck kann das System swappen. chmod 600 schützt gegen andere Benutzer, nicht gegen root, Backup-Prozesse oder einen Crash-Dump. Sauberer ist eine keylocation auf einem schon verschlüsselten Dataset oder ein FIFO statt einer regulären Datei. In beiden Fällen existiert die Passphrase nie persistent auf der Platte.

Properties gehen beim Send verloren. Ohne -R (Replication Stream) oder explizite -o-Optionen werden compression, recordsize, quota, reservation, atime und eigene Properties nicht mitübertragen. Wer compression=zstd oder recordsize=1M gesetzt hatte, muss die beim receive wieder setzen oder direkt einen Replication Stream nutzen.

Mountpoint nach dem Rename prüfen. Lag das alte Dataset auf /var/jails/varta, muss der Mountpoint nach dem Rename wieder explizit gesetzt werden, sonst landet das Dataset am Default-Pfad des Pools:

zfs set mountpoint=/var/jails/varta zroot/varta

Jail vorher stoppen. service jail stop <name> bzw. iocage stop oder bastille stop. Sonst sind Dateien offen, zfs destroy -r schlägt fehl und der Rename macht keinen Spaß.

Inkrementelle Migration für große Datasets

Bei Jails mit Datenbank, Mailspool oder einfach mehreren hundert GB ist Downtime gleich Send-Laufzeit nicht akzeptabel. Besser: initial senden während der Dienst läuft, dann nur kurz stoppen und den inkrementellen Rest nachziehen.

# Phase 1: initialer Send im laufenden Betrieb
zfs snapshot zroot/varta@migration-1
zfs send zroot/varta@migration-1 | \
  zfs receive -F \
  -o encryption=on \
  -o keyformat=passphrase \
  -o keylocation=file:///tmp/keyfile.txt \
  zroot/en-varta

# Phase 2: Dienst stoppen, inkrementelles Delta senden
service jail stop varta
zfs snapshot zroot/varta@migration-2
zfs send -i @migration-1 zroot/varta@migration-2 | \
  zfs receive zroot/en-varta

# Phase 3: Rename und Neustart
zfs destroy -r zroot/varta
zfs rename zroot/en-varta zroot/varta
zfs set mountpoint=/var/jails/varta zroot/varta
service jail start varta

Die Downtime reduziert sich so auf den inkrementellen Send plus Rename, bei einer typischen Mailbox sind das Sekunden statt Minuten. Bei sehr aktiven Datasets kann man mehrere inkrementelle Snapshots nacheinander schieben, bis das Delta klein genug für die gewünschte Zielzeit ist.

Update 2026: was heute dazugekommen ist

OpenZFS 2.x ist auf FreeBSD 14 und 15 stabil. Der eigentliche Migrationspfad hat sich nicht geändert, drumherum ist einiges dazugekommen:

Raw encrypted send/receive. Mit zfs send -w wird ein verschlüsseltes Dataset ohne Entschlüsselung übertragen. Der Remote-Host lagert den Stream, kennt den Schlüssel nicht und sieht keinen Klartext. Für Offsite-Backups der saubere Weg, sobald die Migration durch ist:

zfs snapshot zroot/varta@backup
zfs send -w -R zroot/varta@backup | \
  ssh backup@remote zfs receive backuppool/varta

Andere Keyformate. Statt keyformat=passphrase gehen auch keyformat=raw (32-Byte-Keyfile, z.B. aus HSM oder TPM) oder keyformat=hex (64 Zeichen Hex). keylocation=https://... holt den Schlüssel beim Pool-Import von einer URL, praktisch für headless Systeme, bei denen die Passphrase-Abfrage beim Boot stört.

Kompression vor Verschlüsselung. ZFS komprimiert zuerst, verschlüsselt danach. compression=zstd zusammen mit encryption=on wirkt also wie erwartet, und der komprimierte Zustand bleibt auch im Raw Stream erhalten.

Nur für Datenpools und Non-Root-Datasets. Diese Anleitung deckt Jails, Home-Verzeichnisse, Mailspools und ähnliches ab. Verschlüsseltes Root-on-ZFS ist ein eigenes Thema und braucht zusätzlich Boot-Environment-Handling (bectl) sowie ein geli-verschlüsseltes Swap.

Siehe auch

Native ZFS Encryption einrichten und nutzen für die Grundlagen zu Dataset, Passphrase und Mount nach Reboot. Verschlüsseltes ZFS-Backup auf USB-Platte mit geli für die Offline-Sicherung. Linux Mint mit verschlüsseltem ZFS-Root-Pool installieren für das Linux-Pendant mit Root-Pool.

Eine Übersicht über alle ZFS-Funktionen gibt es im ZFS-Überblick. Fragen? Einfach melden.

Linux Mint mit verschlüsseltem ZFS-Root-Pool installieren

ZFS als Root-Dateisystem unter Linux — will man haben. Verschlüsselung auf der Festplatte — will man auch haben. Die Kombination aus beidem war unter Linux lange ein manueller Kraftakt. Seit Linux Mint 20 bringt der Installer aber fast alles mit. Man muss ihm nur an zwei Stellen unter die Arme greifen.

Linux Mint Boot-Bildschirm: ZFS-Pool-Passwortabfrage nach erfolgreicher Verschluesselung.

Hinweis: Diese Anleitung wurde mit Linux Mint 20.1 geschrieben, funktioniert aber genauso mit Mint 21.x und 22.x — der Installer nutzt das gleiche zsys-setup-Skript.

Pakete im Live-System nachinstallieren

Die gewünschte Linux Mint ISO herunterladen und davon booten. Im Live-System ein Terminal öffnen und die ZFS-Pakete installieren:

sudo aptitude -y install libzfs2linux zfs-initramfs zfsutils-linux zfs-zed

Wer nur ZFS ohne Verschlüsselung will, ist damit schon fertig. Einfach den Installer starten, bei der Festplattenauswahl auf Advanced features… klicken und EXPERIMENTAL: Erase disk and use ZFS wählen. Für Verschlüsselung weiter lesen.

Installer-Skript für Verschlüsselung anpassen

Der Installer fragt kein Passwort für die ZFS-Verschlüsselung ab — das muss man ihm vorher ins Skript schreiben. Im Terminal:

sudo vi /usr/share/ubiquity/zsys-setup

Nach zpool create suchen — es taucht zweimal auf. Beim rpool (nicht beim bpool) zwei Änderungen vornehmen:

1. Vor die zpool create-Zeile des rpool ein echo mit dem gewünschten Passwort setzen:

echo 'EUER-PASSWORT' | zpool create -f \

2. Vor die Zeile -O mountpoint=/ -R "${target}" rpool "${partrpool}" die Encryption-Optionen einfügen:

-O encryption=aes-256-gcm \
-O keylocation=prompt \
-O keyformat=passphrase \

Das fertige Ergebnis sieht dann so aus:

echo 'Kennwort!' | zpool create -f \
        -o ashift=12 \
        -O compression=lz4 \
        -O acltype=posixacl \
        -O xattr=sa \
        -O relatime=on \
        -O normalization=formD \
        -O mountpoint=/ \
        -O canmount=off \
        -O dnodesize=auto \
        -O sync=disabled \
        -O encryption=aes-256-gcm \
        -O keylocation=prompt \
        -O keyformat=passphrase \
        -O mountpoint=/ -R "${target}" rpool "${partrpool}"

Sicherheitshinweis: Das Passwort steht kurzzeitig im Klartext in der Datei und in der Bash-History. Im Live-System ist das unkritisch — nach dem Reboot ins installierte System ist das Live-System weg. Trotzdem nicht das Produktivpasswort in Screenshots posten.

Jetzt den Installer starten, ZFS als Dateisystem wählen — fertig. Funktioniert mit EFI und Legacy-Boot.

Verschlüsselung prüfen

Nach dem ersten Boot ins neue System — Terminal öffnen und prüfen, ob die ZFS-Verschlüsselung aktiv ist und sich durch den Pool bis zu den Benutzerdaten vererbt hat:

$ zpool get feature@encryption bpool rpool
NAME   PROPERTY            VALUE     SOURCE
bpool  feature@encryption  disabled  local
rpool  feature@encryption  active    local

$ zfs get encryption rpool/USERDATA/test_9d9i92
NAME                        PROPERTY    VALUE        SOURCE
rpool/USERDATA/test_9d9i92  encryption  aes-256-gcm  -

feature@encryption: active beim rpool und aes-256-gcm auf den Benutzerdaten — alles korrekt. Der bpool (Boot-Pool) bleibt unverschlüsselt — GRUB muss den Kernel lesen können, bevor das Passwort eingegeben wird.

Wer seine SSDs im ZFS-Pool auch gleich mit TRIM versorgen will — das ist in einem separaten Beitrag beschrieben.


Bilder von der Installation zum Durchklicken:

Siehe auch: ZFS Encryption

Fragen? Einfach melden.

Windows Server RRAS: L2TP/IPsec-VPN mit sicheren Cipher Suites

Windows Server RRAS mit L2TP/IPsec-VPN-Tunnel, Firewall-Konfiguration, AES-256, DH Group 20, UDP 500/4500 und Registry-Hardening.

Wenn ich schon bei Microsoft-Themen bin: Warum nicht gleich noch RRAS (Routing und RAS) mit einem L2TP/IPsec-VPN absichern? Im Standard verbinden sich die Clients nämlich mit SHA-1, 3DES und DH Group 2 (modp1024, also 1024 Bit). SHA-1 ist grenzwertig, 3DES muss nicht sein und modp1024 will man definitiv nicht mehr.

Hinweis: Ursprünglich für Windows Server 2012 R2 geschrieben (inzwischen End of Life). Die Konfiguration über die Windows-Firewall funktioniert auf neueren Versionen identisch.

Wo man die Einstellung findet (Spoiler: nicht bei RRAS)

Ich habe einige Zeit gesucht. Man würde erwarten, dass die IPsec-Cipher irgendwo in der Nähe von Routing und RAS konfiguriert werden. Falsch gedacht. Die Einstellung steckt in der Windows-Firewall mit erweiterter Sicherheit. Irgendeinen Grund wird es haben, das dort zu verstecken. Ich hätte dort nie gesucht.

Der Klickpfad: Windows Firewall → Rechtsklick auf „Windows-Firewall mit erweiterter Sicherheit“ → Eigenschaften → IPsec-Einstellungen → IPsec-Standardeinstellungen → „Anpassen“ → Schlüsselaustausch.

Screenshot der Windows-Firewall mit erweiterter Sicherheit und angezeichnetem Klickpfad um die Sicherheitsmethoden zu konfigurieren.

Hier kann man die Sicherheitsmethoden und Datenschutzeinstellungen anpassen. Windows Firewall als Ort für VPN-Cipher-Konfiguration. Kopfschütteln.

Screenshot der Windows-Firewall mit erweiterter Sicherheit und angezeichnetem Klickpfad um die Datenschutzeinstellungen zu konfigurieren.

UDP Encapsulation hinter NAT

Steht der RRAS hinter einem NAT, muss man noch UDP Encapsulation per Registry aktivieren. Dafür habe ich ein Registry-File:

Registry-File für IPsec UDP Encapsulation

Nach allen Änderungen den Server neu starten. Microsoft halt.

Prüfen ob es geklappt hat

Auf einem Windows-Client per PowerShell (mit erweiterten Rechten) prüfen, welche Cipher die VPN-Verbindung tatsächlich nutzt:

Get-NetIPsecMainModeSA | Select-Object -First 1
Screenshot des Kommandos Get-NetIPsecMainModeSA inkl Konsolenausgabe.

Relevant sind CipherAlgorithm, HashAlgorithm und GroupId. Im Standard steht da 3DES, SHA-1 und DH Group 2 (1024 Bit). Nach den Änderungen:

Encryption:                AES256
Authentication/Integrity:  SHA-1
Key Size:                  DH Group 20 (384-bit ECC)

Immer noch SHA-1 für die Integrity, aber AES-256 und ECC sind ein großer Sprung. Über Gruppenrichtlinien ließe sich das Ganze auch zentral ausrollen, aber das ist nochmal ein eigenes Thema. Vor allem die Reihenfolge korrekt vorzugeben ist dort unerwartet fummelig.

Wer auch die TLS-Cipher für Exchange/OWA härten will: SSL Labs A+ mit Exchange. Fragen? Einfach melden.

TLS-ECDHE mit AES-256-GCM-SHA384 einfach erklärt

Verschlüsselung-cipher

Wer sich mit TLS beschäftigt, stolpert früher oder später über Zeichenketten wie TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 oder TLS_AES_256_GCM_SHA384. Was da genau drinsteht, ist auf den ersten Blick nicht offensichtlich. Dabei folgt die Benennung einem klaren Schema.

Die Bestandteile einer Cipher Suite

Jede Cipher Suite beschreibt vier Dinge:

  • Key Exchange — wie sich Client und Server auf einen gemeinsamen Sitzungsschlüssel einigen.
  • Certificate Verification — wie das Serverzertifikat geprüft wird (Signaturverfahren).
  • Bulk Encryption — die symmetrische Verschlüsselung der eigentlichen Daten.
  • Hashing — die Prüfsummen, die Integrität und Authentizität sicherstellen.

TLS 1.2 vs. TLS 1.3

In TLS 1.2 stehen alle vier Bestandteile im Namen der Cipher Suite. Nehmen wir TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 auseinander:

  • TLS — das Protokoll (Transport Layer Security)
  • ECDHE — Key Exchange (Elliptic Curve Diffie-Hellman Ephemeral)
  • ECDSA — Certificate Verification (Elliptic Curve Digital Signature Algorithm)
  • AES_256_GCM — Bulk Encryption (AES mit 256 Bit im Galois/Counter Mode)
  • SHA384 — Hashing (SHA-2 mit 384 Bit)

TLS 1.3 hat das Namensschema verkürzt. Key Exchange und Certificate Verification sind nicht mehr Teil des Cipher-Suite-Namens, weil sie separat verhandelt werden. Darum sieht TLS_AES_256_GCM_SHA384 so kompakt aus: nur Protokoll, Verschlüsselung und Hash.

Key Exchange

Der Schlüsselaustausch legt fest, wie Client und Server einen temporären Sitzungsschlüssel aushandeln. Man will hier Ephemeral-Verfahren, also temporäre Schlüssel. Warum? Selbst wenn jemand den Traffic mitschneidet und später an den privaten Schlüssel des Servers kommt, kann er die aufgezeichneten Verbindungen nicht entschlüsseln. Der Sitzungsschlüssel existiert nur für die Dauer der Verbindung. Das nennt sich Perfect Forward Secrecy.

DHE (Diffie-Hellman Ephemeral) funktioniert, sollte aber mindestens 2048 Bit nutzen. Besser ist ECDHE (Elliptic Curve DHE), weil es bei gleicher Sicherheit deutlich kleiner und schneller ist. Idealerweise bietet der Server nur ECDHE an. Alles ohne das E am Ende (also statisches DH) hat kein Forward Secrecy und gehört abgeschaltet.

In Zukunft kommt hier noch Post-Quantum dazu. Mit X25519MLKEM768 lassen sich hybride Verfahren nutzen, die auch gegen Quantencomputer absichern. Wer das auf Nginx einrichten will, findet bei mir eine Anleitung: Post-Quantum TLS.

Certificate Verification

Verschlüsselung allein hilft nicht, wenn man mit dem falschen Server spricht. Das Serverzertifikat beweist die Identität. Es wird von einer CA signiert, kann per DANE/TLSA im DNSSEC-geschützten DNS verankert sein und sollte nicht trivial fälschbar sein.

RSA-Zertifikate sollten mindestens 2048 Bit haben, besser 4096 Bit. Allerdings werden RSA-Schlüssel mit steigender Sicherheit immer größer und langsamer. ECDSA-Zertifikate lösen das elegant: Ein ECDSA-Schlüssel mit 256 Bit bietet vergleichbare Sicherheit wie RSA mit 3072 Bit, ist aber deutlich kleiner und schneller zu verifizieren. Als Kurve sollte es mindestens secp256r1 (P-256) sein. secp384r1 geht auch, bringt aber aktuell keinen praktischen Vorteil.

Bulk Encryption

Das ist die eigentliche Datenverschlüsselung. Brauchbare Kombinationen sind:

  • AES-128-GCM oder AES-256-GCM — Standard, schnell, hardware-beschleunigt auf den meisten CPUs
  • ChaCha20-Poly1305 — gute Alternative, besonders auf Geräten ohne AES-NI

AES mit CBC ist noch akzeptabel, aber GCM ist vorzuziehen. Von 3DES sollte man die Finger lassen. Wenn irgendwo RC4 oder DES auftaucht: abschalten.

Hashing

Der Hash sichert die Integrität der übertragenen Daten. Minimum ist SHA-256, ein guter Mittelweg ist SHA-384. SHA-1 sollte man nicht mehr einsetzen. Taucht MD5 auf, stimmt etwas grundlegend nicht.

Fragen, Korrekturen oder Ergänzungen? Einfach melden.

Von RSA zu ECDSA: Zertifikate für Nginx und Postfix umstellen

ECDSA-Zertifikate (Elliptic Curve Digital Signature Algorithm) bieten bei 256 Bit das gleiche Sicherheitsniveau wie RSA mit 3072 Bit. Die Schlüssel sind deutlich kleiner, der TLS-Handshake ist schneller und die Signaturen kürzer. Für Webserver ist die Umstellung trivial. Bei Mailservern gibt es eine Besonderheit: Nicht alle sendenden Server können ECDSA. Postfix löst das elegant mit Dual-Zertifikaten.

ECDSA-Schlüssel erstellen

# EC-Schlüssel mit P-256 erzeugen
openssl ecparam -genkey -name prime256v1 | openssl ec -out ec-server.key

# CSR erstellen (für CA-signierte Zertifikate)
openssl req -new -key ec-server.key -out ec-server.csr

# Oder gleich ein selbstsigniertes Zertifikat (z.B. für Tests)
openssl req -new -x509 -key ec-server.key -out ec-server.pem -days 365

P-256 (prime256v1) ist die gängige Kurve. Let’s Encrypt, DigiCert und andere CAs signieren ECDSA-CSRs problemlos. Bei Let’s Encrypt/certbot: certbot certonly --key-type ecdsa.

Nginx

Beim Webserver einfach den neuen Schlüssel und das Zertifikat hinterlegen. An der Cipher-Konfiguration muss nichts geändert werden, solange ECDSA-Ciphers enthalten sind:

ssl_certificate     /path/to/ec-server.pem;
ssl_certificate_key /path/to/ec-server.key;
ssl_ciphers         TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256;

Alle modernen Browser unterstützen ECDSA seit Jahren. Probleme gibt es nur noch mit sehr alten Clients (Android 2.x, IE 6). Wer die nicht bedienen muss, kann RSA komplett aus der Cipher-Liste streichen.

Postfix: Dual-Zertifikate

Bei E-Mail sieht es anders aus. Manche Mailserver (ältere Exchange-Installationen, schlecht gewartete Systeme) können kein ECDSA. Postfix bietet dafür eine saubere Lösung: Man hinterlegt sowohl ein EC-Zertifikat als auch ein RSA-Zertifikat. Der Server bietet dem Client beide an, der Client wählt das passende.

# ECDSA (bevorzugt)
smtpd_tls_eckey_file = /usr/local/etc/postfix/ec-postfix.key
smtpd_tls_eccert_file = /usr/local/etc/postfix/ec-postfix.pem

# RSA (Fallback)
smtpd_tls_key_file = /usr/local/etc/postfix/postfix.key
smtpd_tls_cert_file = /usr/local/etc/postfix/postfix.pem

Die Cipher-Reihenfolge entscheidet, was bevorzugt wird. ECDSA-Ciphers sollten vor den RSA-Ciphers stehen. Mit tls_preempt_cipherlist = yes bestimmt der Server die Reihenfolge:

tls_preempt_cipherlist = yes
tls_high_cipherlist = TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256

Die TLS-1.3-Ciphers (TLS_AES_*) stehen ganz vorn. Danach kommen ECDHE-ECDSA für TLS 1.2 mit EC-Zertifikat, dann ECDHE-RSA als Fallback für Clients die kein ECDSA können. Alle Ciphers haben Perfect Forward Secrecy durch ECDHE.

Dovecot

Dovecot unterstützt seit Version 2.3.15 ebenfalls mehrere Zertifikate. In 10-ssl.conf:

ssl_cert = </path/to/ec-dovecot.pem
ssl_key = </path/to/ec-dovecot.key
ssl_alt_cert = </path/to/rsa-dovecot.pem
ssl_alt_key = </path/to/rsa-dovecot.key

Verifizieren

Im Postfix-Log erkennt man am Cipher, welches Zertifikat verwendet wurde:

# ECDSA-Verbindung
TLS connection established: TLSv1.3 with cipher TLS_AES_256_GCM_SHA384

# RSA-Fallback (TLS 1.2)
TLS connection established: TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384

Mit openssl s_client lässt sich gezielt prüfen:

# ECDSA-Zertifikat anfordern
openssl s_client -starttls smtp -connect smtp.kernel-error.de:25 2>/dev/null | grep "Server public key\|Cipher"

# Ergebnis: Server public key is 256 bit (EC)

Wer den nächsten Schritt gehen will: Mit Post-Quantum-Schlüsselaustausch (X25519MLKEM768) lässt sich zusätzlich der Key Exchange gegen Quantencomputer absichern. Das Zertifikat bleibt dabei ECDSA, nur der Schlüsselaustausch wird hybrid. Und natürlich gehört zu jedem Zertifikat ein DANE/TLSA-Record im DNS. Fragen? Einfach melden.

internet.nl verschärft die TLS-Anforderungen für Mailserver

E-Mail Test der Niederlande für die E-Mail Domain kernel-error.de
Die Domain kernel-error.de ist in der Hall of Fame der niederländischen IT Security Tests.

Der niederländische internet.nl Mailserver-Test hat die Anforderungen verschärft. Die neuen Guidelines orientieren sich an den aktuellen niederländischen IT-Sicherheitsrichtlinien und ziehen die Messlatte deutlich an.

Was sich geändert hat

TLS 1.0 und 1.1 geben jetzt Abzug. Vorher wurden sie toleriert, jetzt gibt es eine explizite Warnung. Schwache Diffie-Hellman-Parameter und weitere veraltete Cipher sind herausgefallen. Alles um TLS 1.3 den Weg zu ebnen.

Die Hall of Fame hat eine neue Sektion für Champions bekommen: Domains die sowohl beim Webserver als auch beim Mailserver 100 Prozent erreichen.

Warum das relevant ist

internet.nl ist kein akademisches Testtool. Die Ergebnisse fließen in die Bewertung niederländischer Behörden und Dienstleister ein. Wenn dort die Standards steigen, zieht das langfristig auch die Anforderungen an internationale Kommunikationspartner nach oben. Wer mit niederländischen Behörden oder Unternehmen per E-Mail kommuniziert, sollte seinen Score im Auge behalten.

Siehe auch: MTA-STS einrichten

Fragen? Einfach melden.

FreeBSD: Native ZFS Encryption einrichten und nutzen

Seit FreeBSD 13 steht native ZFS Encryption zur Verfügung. Datasets lassen sich mit AES-256-GCM verschlüsseln, ohne dass der gesamte Pool verschlüsselt sein muss. Die Verschlüsselung greift pro Dataset und vererbt sich auf Kind-Datasets.

Verschlüsseltes Dataset anlegen

Ein neues Dataset mit Passphrase-Abfrage:

zfs create -o encryption=aes-256-gcm -o keyformat=passphrase usbpool/test01
Enter passphrase:
Re-enter passphrase:

Das Dataset wird sofort gemountet und ist einsatzbereit. Alles was hineingeschrieben wird, liegt verschlüsselt auf der Platte:

zfs list usbpool/test01
NAME             USED  AVAIL     REFER  MOUNTPOINT
usbpool/test01    99K   899G       99K  /usbpool/test01

zfs get encryption usbpool/test01
NAME            PROPERTY    VALUE        SOURCE
usbpool/test01  encryption  aes-256-gcm  -

Nach einem Reboot

Bei einem Passphrase-geschützten Dataset hat ZFS nach einem Reboot den Schlüssel nicht mehr. Das Dataset existiert, ist aber nicht gemountet:

zfs get mounted usbpool/test01
NAME            PROPERTY  VALUE    SOURCE
usbpool/test01  mounted   no       -

Mit zfs mount -l wird der Schlüssel geladen und das Dataset eingehängt:

zfs mount -l usbpool/test01
Enter passphrase for 'usbpool/test01':

zfs get mounted usbpool/test01
NAME            PROPERTY  VALUE    SOURCE
usbpool/test01  mounted   yes      -

Keyfile statt Passphrase

Statt einer Passphrase-Abfrage kann der Schlüssel auch in einer Datei liegen. Praktisch für Server die ohne Interaktion booten sollen:

zfs create -o encryption=aes-256-gcm \
  -o keyformat=passphrase \
  -o keylocation=file:///root/keys/pool.key \
  zroot/encrypted-data

Die Key-Datei enthält das Passphrase als Text. Wichtig: Die Datei muss beim Boot erreichbar sein, also auf einem unverschlüsselten Dataset liegen. Berechtigungen auf 0400 setzen.

Bestehende Datasets verschlüsseln

Verschlüsselung lässt sich nicht nachträglich auf ein bestehendes Dataset aktivieren. Man muss die Daten per zfs send | zfs receive in ein neues, verschlüsseltes Dataset migrieren. Die komplette Anleitung dafür steht im Beitrag ZFS-Dataset nachträglich verschlüsseln.

Eine Übersicht über alle ZFS-Funktionen gibt es im ZFS-Überblick. Wer sich für ZFS Encryption unter Solaris/OpenIndiana interessiert, findet die Anleitung unter ZFS Encryption unter Solaris. Fragen? Einfach melden.

Postfix: Eingehende E-Mails ohne TLS ablehnen

Standardmäßig nimmt Postfix E-Mails auch ohne Transportverschlüsselung an. Mit smtpd_tls_security_level = may bietet der Server TLS an, erzwingt es aber nicht. Das bedeutet: Wenn die Gegenseite kein STARTTLS kann oder will, wird die Mail trotzdem im Klartext übertragen.

Man kann das ändern und E-Mails ohne TLS komplett ablehnen. Die Frage ist ob man sich das leisten kann.

Konfiguration

# /usr/local/etc/postfix/main.cf
smtpd_tls_security_level = encrypt

Mit encrypt verweigert Postfix die Annahme wenn der sendende Server kein STARTTLS aushandelt. Die Gegenseite bekommt einen temporären Fehler (454) und kann es später nochmal versuchen. Im Log steht dann:

postfix/smtpd: NOQUEUE: reject: RCPT from mail.example.de[...]: 454 4.7.0 TLS is required but was not offered

Vorher prüfen

Bevor man TLS erzwingt, sollte man wissen wie viele Mails betroffen wären. Im Postfix-Log lässt sich das auswerten:

# Anteil TLS vs. Klartext bei eingehenden Verbindungen
grep "TLS connection established" /var/log/maillog | wc -l
grep "connect from" /var/log/maillog | wc -l

In der Praxis liegt der TLS-Anteil bei den meisten Mailservern über 95 Prozent. Die letzten paar Prozent sind oft schlecht gewartete Systeme, Onlineshop-Bestätigungen oder Geräte aus Asien die sich nie um TLS gekümmert haben. Ob das ein Problem ist, hängt davon ab wessen Mails man bereit ist zu verlieren.

Ausgehend erzwingen

Für ausgehende Mails ist die Situation anders. Mit smtp_tls_security_level = encrypt verweigert Postfix die Zustellung wenn die Gegenseite kein TLS anbietet. Das ist riskant, weil man keine Kontrolle darüber hat ob der Empfänger-Server TLS kann.

Der bessere Weg für ausgehende Mails: MTA-STS und DANE prüfen automatisch ob die Zieldomain TLS verlangt und welches Zertifikat erwartet wird. Damit erzwingt man TLS nur dort wo die Gegenseite es auch unterstützt und verifiziert gleichzeitig die Identität.

# Ausgehend: opportunistisch, aber DANE wenn verfügbar
smtp_tls_security_level = dane
smtp_dns_support_level = dnssec

Mit dane als Security-Level nutzt Postfix DANE/TLSA-Records aus dem DNS. Ist ein TLSA-Record vorhanden, wird TLS erzwungen und das Zertifikat verifiziert. Ohne TLSA-Record bleibt es bei opportunistischem TLS. Zusammen mit dem Abschalten von TLS 1.0/1.1 ergibt das eine saubere Konfiguration. Fragen? Einfach melden.

internet.nl: Mailserver-Sicherheit testen mit dem niederländischen Standard

Die niederländische Regierung betreibt mit internet.nl ein kostenloses Testtool für Webserver und Mailserver. Im Gegensatz zu Qualys SSL Labs, das sich auf TLS-Konfiguration konzentriert, prüft internet.nl das gesamte E-Mail-Sicherheitsbild einer Domain.

Was getestet wird

Der Mailserver-Test prüft:

STARTTLSOb der MX TLS anbietet und welche Protokollversionen und Cipher unterstützt werden
ZertifikatGültigkeit, Kette, Hostname-Match
DANE/TLSAOb TLSA-Records im DNS vorhanden und korrekt sind
SPFOb ein SPF-Record existiert und syntaktisch korrekt ist
DKIMOb ausgehende Mails DKIM-signiert sind
DMARCOb eine DMARC-Policy veröffentlicht ist und welche Einstellung sie hat
MTA-STSOb MTA-STS konfiguriert ist und die Policy konsistent ist
DNSSECOb die Domain mit DNSSEC gesichert ist

Für jede Kategorie gibt es Punkte. 100 Prozent erreicht man nur wenn alles korrekt konfiguriert ist. Domains die sowohl beim Web- als auch beim Mailtest 100 Prozent erreichen, landen in der Hall of Fame.

Strenge Anforderungen

internet.nl ist strenger als die meisten anderen Testtools. TLS 1.0 und 1.1 geben Abzug. Ohne DANE ist kein voller Score möglich. Die Cipher-Anforderungen orientieren sich an den niederländischen IT-Sicherheitsrichtlinien, die auch für Behörden gelten.

Das macht den Test besonders nützlich als Benchmark. Wer dort 100 Prozent hat, hat sein E-Mail-Setup nach aktuellem Stand abgesichert. Wer Abzüge bekommt, sieht genau wo es hakt.

Fremde Domains testen

Man kann beliebige Domains testen, nicht nur die eigene. Das ist praktisch um Dienstleister, Geschäftspartner oder den eigenen Provider zu prüfen. Ein kurzer Test zeigt schnell ob der Mailserver auf der anderen Seite zeitgemäß konfiguriert ist oder ob dort noch SSLv3 mit RC4 läuft.

Siehe auch: MTA-STS einrichten

Fragen? Einfach melden.

TLS 1.3 für Postfix & Dovecot: Einrichtung und Konfiguration

TLS 1.3 ist im Mailbetrieb der Normalfall. Sobald Postfix und Dovecot gegen ein aktuelles OpenSSL gelinkt sind, wird es ohne Zutun verwendet. Die Konfigurationsarbeit dreht sich nicht mehr darum, TLS 1.3 zu aktivieren, sondern darum, die alten Protokollversionen sauber abzuschalten und für den verbleibenden TLS-1.2-Fallback eine kontrollierte Cipher-Policy zu definieren.

Illustration zu TLS 1.3 im Mailbetrieb: Symbolische Darstellung von Postfix und Dovecot mit Schloss und Schlüssel vor Server-Hintergrund, steht für verschlüsselte SMTP- und IMAP-Verbindungen mit modernen TLS-Standards.

Voraussetzungen

Auf jedem aktuellen Linux oder BSD ist OpenSSL 3.x längst Default. OpenSSL 1.1.1 ist seit September 2023 End-of-Life und sollte nicht mehr im Einsatz sein. Postfix und Dovecot übernehmen den TLS-Stack vollständig aus der Library, eine eigene Aktivierung von TLS 1.3 entfällt. Welche Version tatsächlich verwendet wird, lässt sich auf dem Server eindeutig prüfen:

postconf -a | grep -i tls
dovecot --version
ldd $(which dovecot) | grep ssl
openssl version

Erscheint OpenSSL 3.x, ist alles an Bord was man braucht. Auch ältere 1.1.1-Builds beherrschen TLS 1.3, sind heute aber kein Argument mehr.

Postfix

Postfix verwendet TLS 1.3 automatisch, sobald die Gegenstelle es anbietet. Wichtig ist die Mindestversion. TLS 1.0 und TLS 1.1 sind kryptografisch tot und gehören aus der Aushandlung ausgeschlossen. Für Submission auf 587 und 465 ist heute realistisch sogar TLS 1.3 only sinnvoll, weil dort nur Mail-Clients hochkommen die eine moderne Library mitbringen. Für SMTP-Relay auf Port 25 zwischen Mailservern bleibt TLS 1.2 als Fallback notwendig, weil die Internet-Realität dort heterogener ist.

Eine solide Basis-Konfiguration für Postfix sieht so aus:

smtpd_tls_protocols = >=TLSv1.2
smtp_tls_protocols  = >=TLSv1.2

smtpd_tls_security_level = may
smtp_tls_security_level  = may

smtpd_tls_cert_file = /etc/letsencrypt/live/DOMAIN/fullchain.pem
smtpd_tls_key_file  = /etc/letsencrypt/live/DOMAIN/privkey.pem

Die Cipher-Optionen in Postfix wirken ausschließlich auf TLS 1.2 und älter. TLS 1.3 hat eine fest definierte Liste von AEAD-Cipher-Suites und ignoriert die Postfix-Optionen vollständig. Trotzdem ist es sinnvoll, für den Fallback eine saubere Policy zu setzen:

tls_preempt_cipherlist = yes

smtpd_tls_ciphers = high
smtp_tls_ciphers  = high

smtpd_tls_mandatory_ciphers = high
smtp_tls_mandatory_ciphers  = high

Damit greifen ausschließlich AEAD-Cipher mit Forward Secrecy. Welche das konkret sind, regelt OpenSSL über seine Defaults der jeweiligen Distribution. Für die Submission-Ports darf man strenger sein und auf encrypt oder secure hochziehen, während Port 25 mit may opportunistisch bleibt.

Session-Caching reduziert Handshake-Overhead und sollte aktiv sein:

smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database  = btree:${data_directory}/smtp_scache

Dovecot

Dovecot nutzt TLS 1.3 ebenfalls automatisch, sofern OpenSSL es liefert. Konfiguriert wird die minimale Protokollversion, alles darunter wird hart abgeschaltet:

ssl = required
ssl_min_protocol = TLSv1.2

Wer nur noch moderne Clients erwartet, kann das auf TLSv1.3 heben. Eigene Praxiserfahrung: für IMAPS auf 993 und Submission auf 587/465 ist das auf einem privat betriebenen Server problemlos machbar. Auf öffentlichen Hostern mit unbekannter Client-Basis lieber bei TLS 1.2 als Untergrenze bleiben.

Die Cipher-Liste betrifft auch in Dovecot nur TLS 1.2 und älter. Eine restriktive Liste verhindert unsaubere Fallbacks bei alten Clients:

ssl_cipher_list = \
ECDHE-ECDSA-CHACHA20-POLY1305:\
ECDHE-RSA-CHACHA20-POLY1305:\
ECDHE-ECDSA-AES256-GCM-SHA384:\
ECDHE-RSA-AES256-GCM-SHA384

ssl_prefer_server_ciphers = yes

Zertifikate werden wie gewohnt eingebunden:

ssl_cert = </etc/letsencrypt/live/DOMAIN/fullchain.pem
ssl_key  = </etc/letsencrypt/live/DOMAIN/privkey.pem

TLS 1.3 und Cipher-Suites

TLS 1.3 unterscheidet sich grundlegend von älteren Versionen. Die Cipher-Suites sind in RFC 8446 fest definiert und bestehen ausschließlich aus AEAD-Verfahren mit integrierter Authentifizierung und Forward Secrecy. Der Mailbetrieb sieht in der Praxis vor allem drei Suites: TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256 und TLS_AES_128_GCM_SHA256.

Postfix und Dovecot bieten keine Möglichkeit, diese Cipher direkt anzusteuern. Die Auswahl erfolgt während des Handshakes durch OpenSSL. Das ist kein Mangel, sondern Absicht und reduziert Fehlkonfigurationen erheblich.

Wer trotzdem versucht, TLS-1.3-Cipher über Applikationsoptionen zu beeinflussen, konfiguriert in Wahrheit nur TLS 1.2.

Der vollständige Mail-Crypto-Stack

TLS 1.3 alleine schützt eine SMTP-Verbindung nur dann zuverlässig, wenn die Gegenstelle die Verschlüsselung auch wirklich erwartet. Bei opportunistischem TLS auf Port 25 entscheidet jeder Server selbst, ob er sich auf eine unverschlüsselte Verbindung einlässt. Damit das nicht passiert, gibt es zwei Mechanismen die heute zum Standard gehören:

  • DANE nutzt DNSSEC und einen TLSA-Record, um den erwarteten Zertifikat-Fingerprint im DNS zu hinterlegen. Postfix kann das nativ verifizieren, sobald smtp_dns_support_level = dnssec und smtp_tls_security_level = dane gesetzt sind. Voraussetzung ist eine funktionierende DNSSEC-Validierung im lokalen Resolver.
  • MTA-STS publiziert die TLS-Erwartung über HTTPS und einen DNS-TXT-Record. Während DANE auf DNSSEC angewiesen ist, kommt MTA-STS ohne aus und wird daher von Anbietern wie Google, Microsoft und Apple breit unterstützt.
  • TLS-RPT liefert die Reports zurück, wenn ein Empfangsserver die TLS-Erwartung gerissen hat. Ohne TLS-RPT merkt man Konfigurationsdrift nur durch Zufall, mit TLS-RPT als JSON-Bericht ins Postfach.

In der Praxis lohnt sich keiner der drei Mechanismen alleine. DANE, MTA-STS und TLS-RPT bilden zusammen die durchgängige Kette aus Erwartung, Verifikation und Auditing. Wer nur einen davon hat, verliert eine Etappe.

Logging, Monitoring und Adoption messen

Ohne TLS-Logging fliegt man blind. Postfix bringt das frei Haus mit:

smtpd_tls_loglevel = 1
smtp_tls_loglevel  = 1

Damit landet pro Verbindung eine Zeile im Log mit Protokoll, Cipher und Schlüsselaustausch. Aus diesen Zeilen lässt sich auch die TLS-Adoption auswerten, also wer mit welcher Version und welchem Cipher kommt. Das gleiche Vorgehen habe ich für die Webseite mit dem Beitrag Post-Quantum TLS auf Nginx: 15 Tage $ssl_curve ausgewertet dokumentiert. Für SMTP funktioniert das analog, der einzige Unterschied ist die Logquelle.

Bei Dovecot reicht ein verbose_ssl = yes in der relevanten Service-Sektion, wenn man im Detail wissen will, was der TLS-Handshake gerade tut. Im Normalbetrieb genügt der Default.

Verifikation

Ob TLS 1.3 wirklich genutzt wird, lässt sich von außen sauber prüfen.

SMTP mit STARTTLS:

openssl s_client -starttls smtp -connect mail.example.com:25 -tls1_3

Submission und IMAPS direkt:

openssl s_client -starttls smtp -connect mail.example.com:587 -tls1_3
openssl s_client -connect mail.example.com:465 -tls1_3
openssl s_client -connect mail.example.com:993 -tls1_3

Wird der Handshake mit einem AEAD-Cipher aufgebaut, ist TLS 1.3 aktiv. Fällt die Verbindung auf TLS 1.2 zurück, greift die konfigurierte Cipher-Liste.

Für eine zweite Meinung lohnt sich ein Blick auf Hardenize oder internet.nl. Beide testen den Mail-Stack inklusive DANE, MTA-STS, TLS-RPT und Cipher-Set in einem Rutsch.

Wohin geht die Reise

TLS 1.2 wird in den nächsten Jahren auch im Mail-Bereich aussterben. Auf der Web-Seite ist das praktisch schon passiert, im SMTP-Relay zwischen Mailservern dauert es länger, weil dort die langsameren Migrationszyklen großer Provider den Takt vorgeben. Wer heute neu konfiguriert, sollte TLS 1.0 und 1.1 hart raushalten und TLS 1.2 als reine Fallback-Etappe behandeln.

Die nächste Stufe ist Post-Quantum-Kryptografie. X25519MLKEM768 ist bei mir auf dem Mail-Server seit Anfang 2026 produktiv und ich habe das Setup im Beitrag Post-Quantum TLS für E-Mail dokumentiert. Auf der Webseite habe ich die Adoption über 15 Tage gemessen und die Ergebnisse in 15 Tage $ssl_curve ausgewertet aufgeschrieben. Für den Mail-Stack steht eine analoge Auswertung noch aus, das Setup dafür ist aber identisch.

Fazit

TLS 1.3 erfordert in Postfix und Dovecot keine Sonderbehandlung. Was zählt, ist eine moderne OpenSSL-Version, eine klare Mindest-TLS-Policy, eine saubere Cipher-Liste für den TLS-1.2-Fallback und das Zusammenspiel aus DANE, MTA-STS und TLS-RPT für die Transport-Verschlüsselung im Internet.

Kein Feature-Flag.
Keine Magie.
Nur korrekte Defaults, bewusst begrenzt.

Siehe auch: Post-Quantum TLS für E-Mail mit X25519MLKEM768, MTA-STS einrichten, DNSSEC und DANE: TLS-Zertifikate mit TLSA-Records absichern und Rspamd: Automatisches Spam/Ham-Lernen mit Dovecot und IMAPSieve.

Fragen? Einfach melden.

« Ältere Beiträge Neuere Beiträge »

© 2026 -=Kernel-Error=-RSS

Theme von Anders NorénHoch ↑