IT-Blog von Sebastian van de Meer

Schlagwort: TLS

Post-Quantum TLS für Nginx — X25519MLKEM768 auf FreeBSD 15 konfigurieren

Nachdem ich zuerst OpenSSH und dann Postfix und Dovecot mit Post-Quantum-Kryptografie ausgestattet habe, kamen einige Rückfragen: Wie sieht das eigentlich für Nginx aus? Kann man das auf dem Webserver genauso einfach aktivieren? Kurze Antwort: Ja. Noch kürzer sogar als bei E-Mail.

Nginx TLS-Konfiguration mit Post-Quantum-Key-Exchange X25519MLKEM768 für HTTPS.

Spannend finde ich dabei, dass ausgerechnet der Webserver die meisten Nachfragen erzeugt hat. SSH und E-Mail laufen hier längst mit X25519MLKEM768, aber die Leser wollten vor allem wissen, wie das für HTTPS geht. Vermutlich weil jeder eine Webseite hat, aber nicht jeder seinen eigenen Mailserver betreibt?! Es kommt ja immer darauf an, was man macht und welche Daten man übermittelt. Aber SSH oder E-Mail würde mich selbst nervöser machen als normales surfen. Wobei…. Ich melde mich ja auch an, hm. OK, immer MFA. Na, eine normale E-Mail ist ja schon immer eine Postkarte, wenn man keine zusätzliche Verschlüsselung nutzt (was kaum jemand macht).

Worum geht es?

Wer die Vorgeschichte noch nicht kennt: X25519MLKEM768 ist ein hybrider Schlüsselaustausch, der klassisches X25519 (Curve25519 ECDH) mit dem Post-Quantum-Algorithmus ML-KEM-768 kombiniert. Standardisiert vom NIST als FIPS 203. Der Vorteil des hybriden Ansatzes: Selbst wenn sich ML-KEM irgendwann als unsicher herausstellt, bleibt X25519 als Absicherung. Und andersherum genauso.

Das „Store now, decrypt later“ Szenario kennt ihr vielleicht schon aus den anderen Beiträgen. Jemand schneidet heute euren TLS-verschlüsselten Datenverkehr mit und entschlüsselt ihn in ein paar Jahren mit einem Quantencomputer. Bei HTTPS betrifft das alles, was über die Leitung geht: Formulardaten, Login-Credentials, API-Aufrufe, Session-Cookies. Ob das in der Praxis relevant ist? Kommt auf euer Bedrohungsmodell an. Aber der Aufwand für die Absicherung ist so gering, dass es keinen Grund gibt, es nicht zu tun.

Es hängt an OpenSSL, nicht an Nginx

Das ist eigentlich die zentrale Erkenntnis aus allen drei Beiträgen: Ob PQC funktioniert oder nicht, entscheidet fast ausschließlich die OpenSSL-Version. Nginx, Postfix, Dovecot, OpenSSH, sie alle delegieren den Schlüsselaustausch an OpenSSL (oder LibreSSL, BoringSSL, je nach System). Die Anwendung selbst muss lediglich die gewünschte Gruppe konfigurieren können. Und das können alle genannten Programme seit Jahren.

Konkret braucht ihr OpenSSL 3.5 oder neuer. Erst ab dieser Version ist ML-KEM nativ im Default-Provider enthalten, ohne externen OQS-Provider, ohne liboqs, ohne selbst kompilieren. FreeBSD 15 liefert das von Haus aus. Bei den meisten Linux-Distributionen sieht es Stand heute leider noch anders aus. Ubuntu 24.04 hat OpenSSL 3.0, Debian 12 hat 3.0, RHEL 9 hat 3.0. Für ein aktuelles OpenSSL müsst ihr dort entweder selbst bauen oder auf neuere Releases warten.

Voraussetzungen prüfen

Auf meinem FreeBSD 15:

$ openssl version
OpenSSL 3.5.4 30 Sep 2025 (Library: OpenSSL 3.5.4 30 Sep 2025)

Nginx muss natürlich gegen dieses OpenSSL gelinkt sein. Das prüft ihr so:

$ nginx -V 2>&1 | grep -oE 'OpenSSL [0-9]+\.[0-9]+\.[0-9]+'
OpenSSL 3.5.4

Und dann die entscheidende Frage: Kennt OpenSSL die Gruppe X25519MLKEM768?

$ openssl list -tls-groups | grep -i mlkem
  X25519MLKEM768
  SecP256r1MLKEM768
  SecP384r1MLKEM1024

Wenn X25519MLKEM768 in der Liste auftaucht, kann es losgehen.

Nginx konfigurieren

In Nginx heißt die relevante Direktive ssl_ecdh_curve. Der Name ist etwas irreführend, denn sie steuert nicht nur ECDH-Kurven, sondern alle Key-Exchange-Gruppen die OpenSSL kennt. Also auch hybride PQC-Gruppen.

Meine Konfiguration in der TLS-Defaults-Datei, die per include in alle vHosts eingebunden wird:

ssl_ecdh_curve  X25519MLKEM768:X25519:secp384r1:prime256v1;

Das war’s. Eine Zeile. X25519MLKEM768 steht als bevorzugte Gruppe ganz vorne. Dahinter folgen die klassischen Kurven als Fallback für Clients, die noch kein ML-KEM sprechen. Die Reihenfolge ist die Präferenz.

Wer die Direktive lieber pro vHost setzen möchte, statt global, kann das natürlich auch tun. Ich bevorzuge eine zentrale TLS-Datei, weil ich sonst bei jedem TLS-Update zwanzig Configs anfassen müsste.

Zusätzlich habe ich die TLS 1.3 Cipher Suites explizit gesetzt:

ssl_conf_command  Ciphersuites TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256;
ssl_conf_command  Options PrioritizeChaCha;

ChaCha20 als erste Wahl, weil es auf Clients ohne AES-NI (ältere Smartphones, ARM-Geräte) deutlich schneller ist. Auf Servern mit AES-NI ist der Unterschied minimal. PrioritizeChaCha sorgt dafür, dass der Server ChaCha20 bevorzugt, wenn der Client es an erster Stelle anbietet.

Die komplette TLS-Konfiguration sieht bei mir so aus:

# Protokolle
ssl_protocols              TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers  on;

# Key-Exchange-Gruppen (Reihenfolge = Präferenz)
ssl_ecdh_curve             X25519MLKEM768:X25519:secp384r1:prime256v1;

# TLS 1.3 Cipher Suites
ssl_conf_command           Ciphersuites TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256;
ssl_conf_command           Options PrioritizeChaCha;

# TLS 1.2 Cipher Suites (nur ECDSA, kein RSA)
ssl_ciphers                ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256;

# Session Handling
ssl_session_cache          shared:SSL:50m;
ssl_session_timeout        1d;
ssl_session_tickets        off;

# OCSP Stapling
ssl_stapling               on;
ssl_stapling_verify        on;

# HSTS
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

Danach die Konfiguration testen und Nginx neu laden:

# nginx -t
nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful
# service nginx reload

Überprüfen

Funktioniert es? Mit openssl s_client lässt sich das schnell prüfen:

$ openssl s_client -connect www.kernel-error.de:443 \
    -groups X25519MLKEM768 -brief </dev/null 2>&1 | grep -E 'Protocol|group|Cipher'
Protocol version: TLSv1.3
Ciphersuite: TLS_CHACHA20_POLY1305_SHA256
Negotiated TLS1.3 group: X25519MLKEM768

TLSv1.3 mit X25519MLKEM768. Läuft. Der hybride Post-Quantum-Schlüsselaustausch ist aktiv.

Und was passiert, wenn ein Client kein ML-KEM kann?

$ openssl s_client -connect www.kernel-error.de:443 \
    -groups X25519 -brief </dev/null 2>&1 | grep -E 'Protocol|group|Cipher'
Protocol version: TLSv1.3
Ciphersuite: TLS_CHACHA20_POLY1305_SHA256

Sauberer Fallback auf X25519. Kein Fehler, keine Unterbrechung. Der Client bekommt einfach die stärkste Gruppe, die beide Seiten gemeinsam haben.

Browser-Support

Das Schöne bei HTTPS im Vergleich zu E-Mail oder SSH: Die Browser haben Post-Quantum-Kryptografie teilweise schon vor den Servern implementiert. Chrome verwendet seit Version 124 (April 2024) X25519MLKEM768 als bevorzugte Gruppe. Firefox seit Version 124 ebenfalls. Safari seit macOS 15 Sequoia und iOS 18. Edge zieht mit Chrome mit.

Wenn ihr also Nginx mit X25519MLKEM768 konfiguriert, profitieren die meisten eurer Besucher sofort davon. Ohne dass sie irgendetwas tun müssen. Das ist bei SSH und E-Mail anders, da sind die Clients noch nicht so weit. Womit sich auch erklärt, warum das Thema bei Webservern mehr Aufmerksamkeit bekommt.

HTTP/3 und QUIC

Wer wie ich HTTP/3 (QUIC) aktiviert hat, bekommt PQC dort automatisch mit. QUIC verwendet TLS 1.3 als Transportverschlüsselung und nutzt dieselbe ssl_ecdh_curve Konfiguration. Kein zusätzlicher Konfigurationsaufwand.

listen [::]:443 quic reuseport;
listen 443 quic reuseport;

Wer QUIC noch nicht nutzt: Der Overhead ist minimal, der Vorteil bei mobilen Verbindungen deutlich spürbar. Mehr dazu in meinem HTTP/3 Beitrag.

Davon abgesehen, wie ist das eigentlich mit Microsoft? Cloudflare macht ja schon knapp zu 66% PQC im HTTP Traffic. Es ist 2026, fragen wir doch mal eine AI: claude „Sag mal, wie ist das eigentlich bei Microsoft Produkten, wie Exchange oder IIS im Bezug auf PQC? Wird das schon unterstützt oder kommt das bald?“

● Gute Frage — Microsoft ist da tatsächlich in einer interessanten Position:                                                                                                                                                                                                                                                  
                 
  Windows / Schannel (TLS-Stack)                                                                                                                                                                                                                                                                                              
                  
  - Windows 11 24H2 / Windows Server 2025 haben experimentelle Unterstützung für ML-KEM (X25519MLKEM768) in TLS 1.3 bekommen — allerdings zunächst nur als Preview/Feature-Flag, nicht standardmäßig aktiv.                                                                                                                   
  - Der zugrunde liegende TLS-Stack (Schannel) muss das können, damit IIS und Exchange davon profitieren.                                                                                                                                                                                                                     

  IIS

  - IIS nutzt Schannel direkt. Sobald Schannel auf dem jeweiligen Windows Server PQC-Key-Exchange unterstützt und es aktiviert ist, kann IIS das theoretisch sofort.
  - Stand meines Wissens (Mai 2025): Noch kein produktiver PQC-Support in IIS. Die Preview in Windows Server 2025 ist eher für Tests gedacht.

  Exchange

  - Exchange Online (Microsoft 365): Microsoft hat angekündigt, PQC schrittweise in ihre Cloud-Dienste zu integrieren. Für TLS-Verbindungen zwischen Microsoft-Datacentern wurde bereits mit PQC experimentiert.
  - Exchange On-Premises: Hängt komplett am darunterliegenden Windows Server / Schannel. Solange Schannel kein produktives PQC kann, kann Exchange es auch nicht.

  Microsofts Roadmap

  - Microsoft hat ein "Quantum-Safe Program" und arbeitet aktiv an PQC-Integration in Windows, Azure und M365.
  - Die Priorität liegt auf TLS 1.3 mit ML-KEM (hybrid, also X25519MLKEM768.
  - Einen festen Zeitplan für "PQC by default" in Exchange/IIS gibt es meines Wissens noch nicht.

  Fazit

  Microsoft ist hintendran verglichen mit dem Open-Source-Stack. OpenSSL 3.5+ / LibreSSL / BoringSSL haben PQC-Support bereits produktionsreif. Bei Microsoft wartet man darauf, dass Schannel das nativ und stabil liefert — und bis das
  in Exchange On-Prem ankommt, dauert es erfahrungsgemäß nochmal länger.

  Für Exchange Online dürfte Microsoft das irgendwann einfach serverseitig einschalten, ohne dass Admins etwas tun müssen. Für On-Prem heißt es: warten auf den nächsten Windows Server Release, der PQC in Schannel GA (General Availability) hat.

  Caveat: Mein Wissensstand ist Mai 2025 — es kann sein, dass Microsoft seitdem konkretere Termine genannt hat. Wäre ggf. einen Blick in den Microsoft Security Blog wert.

Klingt gut. Ich muss ja zugeben, dass ich, seit ich nicht mehr mit Martin Peuker bei Items arbeite, irgendwie komplett von der Microsoft-Welt abgekoppelt bin. Oh, ist das jetzt korrekt von der AI? Keine Ahnung, „klingt“ richtig.

Was das nicht leistet

Den Absatz kennt ihr inzwischen aus den anderen Beiträgen, aber er gehört dazu: Wir sichern hier den Schlüsselaustausch ab, nicht die Authentifizierung. Die TLS-Zertifikate nutzen weiterhin klassische Algorithmen (in meinem Fall ECDSA P-384). Für Post-Quantum-Signaturen bräuchte man ML-DSA (ehemals CRYSTALS-Dilithium) in den Zertifikaten, aber keine öffentliche CA stellt solche Zertifikate aus. Das wird kommen, aber noch nicht heute.

In der Praxis heißt das: Ein Angreifer mit Quantencomputer könnte die Serverauthentifizierung angreifen, müsste das aber in Echtzeit tun. „Store now, decrypt later“ greift dort nicht. Der Schlüsselaustausch und damit die Vertraulichkeit eurer Daten ist durch X25519MLKEM768 geschützt. Auch in Zukunft.

Fazit

Eine Zeile in der Nginx-Konfiguration, ein Reload, fertig. Euer Webserver verhandelt danach mit jedem modernen Browser einen quantensicheren Schlüsselaustausch. Vollständig abwärtskompatibel für ältere Clients. Kein Risiko, kein Aufwand, kein Nachteil.

Die eigentliche Hürde ist nicht Nginx, sondern die OpenSSL-Version auf eurem System. Wer FreeBSD 15 oder ein System mit OpenSSL 3.5+ hat, kann sofort loslegen. Alle anderen müssen auf ihre Distribution warten oder selbst bauen.

Damit habe ich jetzt SSH, E-Mail und Webserver mit Post-Quantum-Kryptografie abgedeckt. Fehlt eigentlich nur noch DNS. Aber DoH und DoT laufen ja auch über TLS … *grübel*

Wie immer: Bei Fragen, fragen.

Post-Quantum TLS für E-Mail — Postfix und Dovecot mit X25519MLKEM768 auf FreeBSD 15

Visualisierung hybrider Post-Quantum-TLS-Verschlüsselung für E-Mail mit X25519MLKEM768 (ML-KEM-768 + X25519) auf Postfix und Dovecot unter FreeBSD 15

Nachdem ich im letzten Beitrag OpenSSH mit hybriden Post-Quantum-Algorithmen abgesichert habe, lag die Frage nahe: Was ist eigentlich mit E-Mail? Mein FreeBSD 15 liefert Postfix 3.10.6, Dovecot 2.3.21.1 und OpenSSL 3.5.4 – und genau diese Kombination bringt alles mit, was man für quantensichere Verschlüsselung im Mailverkehr braucht. Ohne zusätzliche Pakete, ohne Patches, ohne Gefrickel.

Warum überhaupt PQC für E-Mail?

Das „Store now, decrypt later„-Szenario, das ich beim SSH-Beitrag angesprochen habe, trifft auf E-Mail mindestens genauso zu. E-Mails werden über SMTP zwischen Servern transportiert – und dieser Transport ist grundsätzlich abfangbar. Wer heute TLS-verschlüsselten Mailverkehr mitschneidet und archiviert, könnte diesen in einigen Jahren mit einem ausreichend leistungsfähigen Quantencomputer entschlüsseln. Zumindest theoretisch.

Heißt das, morgen liest jemand eure Mails? Nein. Aber wenn ihr vertrauliche Kommunikation betreibt und die heute eingesetzte Kryptografie in zehn Jahren noch standhalten soll, ist jetzt der richtige Zeitpunkt zum Handeln. Zumal der Aufwand (wie ihr gleich seht) überschaubar ist.

Was steckt hinter X25519MLKEM768?

Kurz zur Einordnung: ML-KEM (ehemals CRYSTALS-Kyber) ist der vom NIST im August 2024 standardisierte Post-Quantum-Algorithmus für den Schlüsselaustausch (FIPS 203). X25519MLKEM768 ist ein sogenannter Hybrid-Algorithmus – er kombiniert das klassische X25519 (Curve25519 ECDH) mit ML-KEM-768 zu einem gemeinsamen Schlüssel.

Der Clou dabei: Selbst wenn ML-KEM irgendwann gebrochen werden sollte, bleibt die klassische X25519-Komponente intakt. Und umgekehrt. Man muss also nicht darauf vertrauen, dass der neue Algorithmus auch wirklich hält – man bekommt das Beste aus beiden Welten.

Wer Firefox nutzt, hat das übrigens vermutlich schon in Aktion gesehen: Seit Firefox 124 wird bei TLS 1.3 standardmäßig X25519MLKEM768 für den Schlüsselaustausch verwendet. Schaut mal in die Verbindungsdetails einer HTTPS-Seite – die Chancen stehen gut, dass dort bereits ein hybrider PQC-Schlüsselaustausch stattfindet. Also, wenn der Server das anbietet, wie dieser hier *zwinker*.

Voraussetzungen prüfen

Bevor ihr konfiguriert, solltet ihr sicherstellen, dass euer OpenSSL ML-KEM überhaupt kann. Auf meinem FreeBSD 15:

$ openssl version
OpenSSL 3.5.4 30 Sep 2025 (Library: OpenSSL 3.5.4 30 Sep 2025)

Und dann die entscheidende Frage – kennt OpenSSL die benötigten KEM-Algorithmen?

$ openssl list -kem-algorithms | grep -i mlkem
  ML-KEM-512
  ML-KEM-768
  ML-KEM-1024
  X25519MLKEM768
  SecP256r1MLKEM768

Wenn X25519MLKEM768 in der Liste auftaucht, seid ihr startklar. Das ist bei OpenSSL ab Version 3.5 der Fall – der ML-KEM-Support ist im Default-Provider enthalten, es wird kein zusätzlicher OQS-Provider und kein liboqs benötigt.

Noch ein Check – sind die Algorithmen auch als TLS-Gruppen verfügbar?

$ openssl list -tls-groups | grep -i mlkem
  X25519MLKEM768
  SecP256r1MLKEM768
  SecP384r1MLKEM1024

Perfekt. Weiter geht’s.

Postfix konfigurieren

Postfix steuert die verwendeten TLS-Gruppen für den Schlüsselaustausch über den Parameter tls_eecdh_auto_curves. Dieser gilt sowohl für eingehende (smtpd) als auch für ausgehende (smtp) Verbindungen.

Vorher:

tls_eecdh_auto_curves = X25519, prime256v1, secp384r1

Nachher:

tls_eecdh_auto_curves = X25519MLKEM768, X25519, prime256v1, secp384r1

Das war’s. Eine Zeile. X25519MLKEM768 wird als bevorzugte Gruppe an den Anfang gestellt, die klassischen Kurven bleiben als Fallback erhalten. Clients die kein ML-KEM beherrschen, verhandeln einfach X25519 oder prime256v1 – die Abwärtskompatibilität bleibt also vollständig gewahrt.

Die Änderung setzt ihr entweder direkt in /usr/local/etc/postfix/main.cf oder über:

# postconf "tls_eecdh_auto_curves = X25519MLKEM768, X25519, prime256v1, secp384r1"
# postfix reload

Wichtig: Dieser Parameter beeinflusst alle Postfix-Dienste – SMTP (Port 25), Submission (Port 587) und SMTPS (Port 465). Ihr müsst also nicht jeden Port einzeln konfigurieren.

Dovecot konfigurieren

Dovecot verwendet den Parameter ssl_curve_list um die TLS-Gruppen für IMAP-Verbindungen festzulegen. Standardmäßig ist dieser leer, was bedeutet, dass OpenSSL seine eigenen Defaults verwendet. Das kann funktionieren, muss aber nicht.

In /usr/local/etc/dovecot/conf.d/10-ssl.conf:

ssl_curve_list = X25519MLKEM768:X25519:prime256v1:secp384r1

Achtung: Dovecot verwendet Doppelpunkte als Trennzeichen (OpenSSL-Syntax), Postfix verwendet Kommas. Nicht verwechseln. Ja, passiert mir oft 😀

Danach:

# doveadm reload

Überprüfen

Jetzt wird’s spannend. Funktioniert es tatsächlich? Zum Testen verwende ich openssl s_client direkt auf dem Server; denn euer lokales Linux oder macOS hat möglicherweise noch kein OpenSSL 3.5 mit ML-KEM-Support. Mein Linux Mint 22.3 hat es leider noch nicht *schnief*

SMTP (Port 25, STARTTLS):

$ openssl s_client -connect smtp.kernel-error.de:25 -starttls smtp \
    -groups X25519MLKEM768 -brief </dev/null 2>&1 | grep -E 'Protocol|group'
Protocol version: TLSv1.3
Negotiated TLS1.3 group: X25519MLKEM768

SMTPS (Port 465):

$ openssl s_client -connect smtp.kernel-error.de:465 \
    -groups X25519MLKEM768 -brief </dev/null 2>&1 | grep -E 'Protocol|group'
Protocol version: TLSv1.3
Negotiated TLS1.3 group: X25519MLKEM768

Submission (Port 587, STARTTLS):

$ openssl s_client -connect smtp.kernel-error.de:587 -starttls smtp \
    -groups X25519MLKEM768 -brief </dev/null 2>&1 | grep -E 'Protocol|group'
Protocol version: TLSv1.3
Negotiated TLS1.3 group: X25519MLKEM768

IMAPS (Port 993):

$ openssl s_client -connect imap.kernel-error.de:993 \
    -groups X25519MLKEM768 -brief </dev/null 2>&1 | grep -E 'Protocol|group'
Protocol version: TLSv1.3
Negotiated TLS1.3 group: X25519MLKEM768

Alle vier Ports verhandeln TLSv1.3 mit X25519MLKEM768. Die hybride Post-Quantum-Verschlüsselung ist aktiv.

Wenn ihr testen wollt, was passiert wenn ein Client kein ML-KEM unterstützt:

$ openssl s_client -connect imap.kernel-error.de:465 \
    -groups X25519 -brief </dev/null 2>&1 | grep -E 'Protocol|group'
Protocol version: TLSv1.3
Negotiated TLS1.3 group: X25519

Fallback auf X25519 – funktioniert sauber.

Was das nicht leistet

Wie schon beim SSH-Beitrag muss ich auch hier einschränken: Wir sichern damit den Schlüsselaustausch ab, nicht die Authentifizierung. Die TLS-Zertifikate verwenden weiterhin klassische Algorithmen (RSA, ECDSA). Für Post-Quantum-Signaturen in Zertifikaten bräuchte man ML-DSA (ehemals CRYSTALS-Dilithium) – und obwohl OpenSSL 3.5 das theoretisch unterstützt, gibt es Stand heute keine öffentliche Zertifizierungsstelle, die ML-DSA-Zertifikate ausstellt. Das wird kommen, ist aber noch Zukunftsmusik. Hey, wie ECDSA bei S/MIME (oder ist das schon anders?).

Für die Praxis bedeutet das: Ein Angreifer mit einem Quantencomputer könnte theoretisch die Serverauthentifizierung angreifen (ECDSA/RSA brechen), müsste das aber in Echtzeit tun – hier greift „store now, decrypt later“ nicht, weil eine gefälschte Authentifizierung nur im Moment der Verbindung nützt. Der Schlüsselaustausch hingegen – und damit die eigentliche Vertraulichkeit der transportierten E-Mails – ist durch X25519MLKEM768 auch gegen zukünftige Quantenangriffe geschützt.

Zwei Zeilen Konfiguration, ein Reload pro Dienst – und euer Mailserver verhandelt quantensichere Verschlüsselung. Vollständig abwärtskompatibel, ohne Einschränkungen für bestehende Clients. Es gibt eigentlich keinen Grund, das nicht zu tun. Oder fällt euch etwas ein?

Viel Spaß beim Nachbauen – und wie immer: bei Fragen, fragen.

S/MIME-Zertifikat per DNS veröffentlichen – SMIMEA

smimea S/MIME Blog Image

Mal wieder soweit: Mein aktuelles S/MIME-Zertifikat zum Signieren von E-Mails läuft aus. Also habe ich mir ein neues besorgt. Da GlobalSign keine Class-2-Zertifikate mehr für Privatpersonen anbietet, musste ich die CA wechseln. Durch Zufall bin ich auf SSLplus gestoßen – die haben echt gute Angebote für alle möglichen Zertifikate. Aber darum soll es in diesem Beitrag nicht gehen.

Wie immer will ich mein Zertifikat öffentlich zugänglich machen, sonst müsste jeder erst eine von mir signierte E-Mail erhalten, bevor er mein Zertifikat hat. Erst dann könnten Absender mir verschlüsselte E-Mails schicken.

Dafür gibt es ein experimentelles RFC 8162, das beschreibt, wie sich ein solches Zertifikat in einer DNSSEC-geschützten Zone veröffentlichen lässt. Natürlich gibt es im Internet wieder zig verschiedene Anleitungen und Wege, um das zu realisieren. Aber nichts wirklich Zuverlässiges, was ich finden konnte. Den DNS-Record für meine Bind9-Zone wieder manuell zu erstellen, hatte ich jedenfalls keine Lust.

Also habe ich zwei kleine Python3-Skripte geschrieben:

smimea_generate_record.py – Erstellt einen kopierbaren RR für die DNS-Zone. Kann interaktiv genutzt werden: Fragt nach E-Mail-Adresse und PEM-Zertifikat. Oder direkt mit Parametern aufgerufen werden. Prüft, ob E-Mail-Adresse und Zertifikat zusammenpassen, und gibt den fertigen Record aus.

./smimea_generate_record.py
Enter the email address: kernel-error@kernel-error.com
Enter the path to the PEM certificate: mail.pem
✅ Email 'kernel-error@kernel-error.com' matches the certificate!

🔹 **Generated BIND9 DNS Record:**

70e1c7d87e825b3aba45e2a478025ea0d91d298038436abde5a4c2d0._smimecert.kernel-error.com. 3600 IN SMIMEA 3 0 0 (
   30820714308204FCA003020102021073C13C478DA7B114B871F00737F1B0FB30
   0D06092A864886F70D01010B0500304E310B300906035504061302504C312130
   1F060355040A0C1841737365636F20446174612053797374656D7320532E412E
   311C301A06035504030C1343657274756D20534D494D4520525341204341301E
   170D3235303331333133343135355A170D3237303331333133343135345A3078
   3114301206035504040C0B76616E206465204D65657231123010060355042A0C
   0953656261737469616E311E301C06035504030C1553656261737469616E2076
   616E206465204D656572312C302A06092A864886F70D010901161D6B65726E65
   6C2D6572726F72406B65726E656C2D6572726F722E636F6D30820222300D0609
   2A864886F70D01010105000382020F003082020A0282020100D0A90BC53ABA04
   08543FE600F0F71C17BE7EB4A8996A8EF5E9122AAC8E7F39D627186617C4D6CA
   734E1A9E6302F8076065EA93D762542D2C12BFF32D5D4942B9A8AA84E2E63CE9
   B843C1665C014A6572A42E376ED0629694FCC942FE53D76052A40CDAB1257A1D
   501D9C65DE18F27C5490A24181498A202E56F4DC0FDCBFE94766F96EBF47C872
   3744ABD69DC684417106DF3D4F12FD52A13B786490366DBF6CB5A843621CD686
   B06D072FD7D486BD0AC706021D137A365718DCD8709D55B64428F8DB56B268BD
   BED463A25231B40566C041A48958BE1767E27E21881D2109935C02F27EA306B6
   4997683EEFDF8685F4F090AB09692F232CD34AC7FF2296768CED62C68C37B4C3
   DD9F04EC9F5C9BB9F712A5032AC2F83D68DA756E4F2886A6F65889CFAEA0C15E
   3624EA3D9E3EFF91D68606F7B7B1B7120035AD4F71369E6D79977B4B2CC3575A
   C51CAF419E795B78822DD36B6D0B0E4622BCE55F7B27FCB52FDCD6A4FBD33EF0
   9F897CADA2E793D1509DE54773B3FBE9091CEA2E27A41CBA38A08BBBE1B15BF5
   6EB35B21D66F5B1B1CC6FDD6362AA88A4010F3D2732F071A841BC765D6F74C3B
   430D036A327918D08156BA2882D78113DD15633599319F4BD5D4F12E1F0102BA
   33766ADF09DC58323246D20BAC815BE5B8822C260EFBB07ADBAB98FA42F31650
   FEFAE5D679D4AD29992F199D59F38D54988D77B61E740CBF470203010001A382
   01C2308201BE300C0603551D130101FF0402300030410603551D1F043A303830
   36A034A0328630687474703A2F2F63736D696D6572736163612E63726C2E6365
   7274756D2E706C2F63736D696D6572736163612E63726C30818306082B060105
   0507010104773075302E06082B060105050730018622687474703A2F2F63736D
   696D6572736163612E6F6373702D63657274756D2E636F6D304306082B060105
   050730028637687474703A2F2F63736D696D6572736163612E7265706F736974
   6F72792E63657274756D2E706C2F63736D696D6572736163612E636572301F06
   03551D2304183016801466FBC30FBEF4BFE09CC9AB4DDE4719BDC0CAA668301D
   0603551D0E041604148D8C102E11D87004F7DDB4E04FF01781888A32A0304C06
   03551D20044530433009060767810C010504023036060B2A84680186F6770264
   01013027302506082B06010505070201161968747470733A2F2F7777772E6365
   7274756D2E706C2F435053301D0603551D250416301406082B06010505070304
   06082B06010505070302300E0603551D0F0101FF0404030204F030280603551D
   110421301F811D6B65726E656C2D6572726F72406B65726E656C2D6572726F72
   2E636F6D300D06092A864886F70D01010B0500038202010070724799F05CF4C8
   21854F43BD950BB608B989046349214F9D0EEC79F73A59DBF4063608FE5A7A7F
   A50CD46A15486018EB9C334418084D8F97FE32EA21CCBAFE902BF6472DB6CA60
   D79EBE09919AFA0652D92CB13B506400BAF4774F3263967A49548A6F723ADCBB
   715AF79705099E5EC84E283DAFA3465908F4148C2B153C41D051C94295D4F042
   54217D1C8E48DF59D92ECBCB4A872EC728A954DAF7B661DE8037F7F103393612
   14163901ACFE98F3D597A67DBE87A8EE1FEC33DB71712F4907E0F3B1171E9176
   158189AC8229B26B369C0FE2BBD5964CA2ABFC7D955485056102844E84E8F79E
   0F30BF41D5F42B3C4F4CCA9BF9334D5728518473A0E61A3AFC88F59034F27154
   6B5D806D86F1E8BC6B54B4E05F80C44835DCC2C534E419F63BBFDB305C1733B4
   2DD2CC5795876F004F18C2E4D64B2C9FC6939590BE32501B6A6CEDB19B5FBF47
   887C76E14C99A36D46E99B5C76782E4E345ECB37E8886303C84849ADC8BDE1AF
   4E3A8096AEE407A40699D5C000ADCD16A4805DDF8FB208FFB902EF14031CFFBE
   3C0DC03588EBF15557B3B1029B2CD196064BC0DEE1F11D12391825B86CB34A6F
   BEBBAD43B0FE0EA43301F93D0B26ACED182B1E27063AE578C003D4D4498132B8
   D980532754CFFBD9E6D8917615B62AE08295FC46391AA0FD9815FDD822D95E9B
   7573CA35477D59B98DE4852065F58FB60E0E620D3E2F5CAD
   )

smimea_lookup.py – Fragt den SMIMEA-Record im DNS ab, lädt das Zertifikat herunter und prüft es mit OpenSSL auf Gültigkeit. Funktioniert interaktiv oder mit übergebenen Werten.

./smimea_lookup.py 
Enter the email address: kernel-error@kernel-error.com

Querying DNS for SMIMEA record:
  70e1c7d87e825b3aba45e2a478025ea0d91d298038436abde5a4c2d0._smimecert.kernel-error.com

Certificate saved as smimea_cert.der
Certificate successfully retrieved and verified:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            73:c1:3c:47:8d:a7:b1:14:b8:71:f0:07:37:f1:b0:fb
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = PL, O = Asseco Data Systems S.A., CN = Certum SMIME RSA CA
        Validity
            Not Before: Mar 13 13:41:55 2025 GMT
            Not After : Mar 13 13:41:54 2027 GMT
        Subject: SN = van de Meer, GN = Sebastian, CN = Sebastian van de Meer, emailAddress = kernel-error@kernel-error.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (4096 bit)
                Modulus:
                    00:d0:a9:0b:c5:3a:ba:04:08:54:3f:e6:00:f0:f7:
                    1c:17:be:7e:b4:a8:99:6a:8e:f5:e9:12:2a:ac:8e:
                    7f:39:d6:27:18:66:17:c4:d6:ca:73:4e:1a:9e:63:
                    02:f8:07:60:65:ea:93:d7:62:54:2d:2c:12:bf:f3:
                    2d:5d:49:42:b9:a8:aa:84:e2:e6:3c:e9:b8:43:c1:
                    66:5c:01:4a:65:72:a4:2e:37:6e:d0:62:96:94:fc:
                    c9:42:fe:53:d7:60:52:a4:0c:da:b1:25:7a:1d:50:
                    1d:9c:65:de:18:f2:7c:54:90:a2:41:81:49:8a:20:
                    2e:56:f4:dc:0f:dc:bf:e9:47:66:f9:6e:bf:47:c8:
                    72:37:44:ab:d6:9d:c6:84:41:71:06:df:3d:4f:12:
                    fd:52:a1:3b:78:64:90:36:6d:bf:6c:b5:a8:43:62:
                    1c:d6:86:b0:6d:07:2f:d7:d4:86:bd:0a:c7:06:02:
                    1d:13:7a:36:57:18:dc:d8:70:9d:55:b6:44:28:f8:
                    db:56:b2:68:bd:be:d4:63:a2:52:31:b4:05:66:c0:
                    41:a4:89:58:be:17:67:e2:7e:21:88:1d:21:09:93:
                    5c:02:f2:7e:a3:06:b6:49:97:68:3e:ef:df:86:85:
                    f4:f0:90:ab:09:69:2f:23:2c:d3:4a:c7:ff:22:96:
                    76:8c:ed:62:c6:8c:37:b4:c3:dd:9f:04:ec:9f:5c:
                    9b:b9:f7:12:a5:03:2a:c2:f8:3d:68:da:75:6e:4f:
                    28:86:a6:f6:58:89:cf:ae:a0:c1:5e:36:24:ea:3d:
                    9e:3e:ff:91:d6:86:06:f7:b7:b1:b7:12:00:35:ad:
                    4f:71:36:9e:6d:79:97:7b:4b:2c:c3:57:5a:c5:1c:
                    af:41:9e:79:5b:78:82:2d:d3:6b:6d:0b:0e:46:22:
                    bc:e5:5f:7b:27:fc:b5:2f:dc:d6:a4:fb:d3:3e:f0:
                    9f:89:7c:ad:a2:e7:93:d1:50:9d:e5:47:73:b3:fb:
                    e9:09:1c:ea:2e:27:a4:1c:ba:38:a0:8b:bb:e1:b1:
                    5b:f5:6e:b3:5b:21:d6:6f:5b:1b:1c:c6:fd:d6:36:
                    2a:a8:8a:40:10:f3:d2:73:2f:07:1a:84:1b:c7:65:
                    d6:f7:4c:3b:43:0d:03:6a:32:79:18:d0:81:56:ba:
                    28:82:d7:81:13:dd:15:63:35:99:31:9f:4b:d5:d4:
                    f1:2e:1f:01:02:ba:33:76:6a:df:09:dc:58:32:32:
                    46:d2:0b:ac:81:5b:e5:b8:82:2c:26:0e:fb:b0:7a:
                    db:ab:98:fa:42:f3:16:50:fe:fa:e5:d6:79:d4:ad:
                    29:99:2f:19:9d:59:f3:8d:54:98:8d:77:b6:1e:74:
                    0c:bf:47
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 CRL Distribution Points: 
                Full Name:
                  URI:http://csmimersaca.crl.certum.pl/csmimersaca.crl
            Authority Information Access: 
                OCSP - URI:http://csmimersaca.ocsp-certum.com
                CA Issuers - URI:http://csmimersaca.repository.certum.pl/csmimersaca.cer
            X509v3 Authority Key Identifier: 
                66:FB:C3:0F:BE:F4:BF:E0:9C:C9:AB:4D:DE:47:19:BD:C0:CA:A6:68
            X509v3 Subject Key Identifier: 
                8D:8C:10:2E:11:D8:70:04:F7:DD:B4:E0:4F:F0:17:81:88:8A:32:A0
            X509v3 Certificate Policies: 
                Policy: 2.23.140.1.5.4.2
                Policy: 1.2.616.1.113527.2.100.1.1
                  CPS: https://www.certum.pl/CPS
            X509v3 Extended Key Usage: 
                E-mail Protection, TLS Web Client Authentication
            X509v3 Key Usage: critical
                Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment
            X509v3 Subject Alternative Name: 
                email:kernel-error@kernel-error.com
    Signature Algorithm: sha256WithRSAEncryption
    Signature Value:
        70:72:47:99:f0:5c:f4:c8:21:85:4f:43:bd:95:0b:b6:08:b9:
        89:04:63:49:21:4f:9d:0e:ec:79:f7:3a:59:db:f4:06:36:08:
        fe:5a:7a:7f:a5:0c:d4:6a:15:48:60:18:eb:9c:33:44:18:08:
        4d:8f:97:fe:32:ea:21:cc:ba:fe:90:2b:f6:47:2d:b6:ca:60:
        d7:9e:be:09:91:9a:fa:06:52:d9:2c:b1:3b:50:64:00:ba:f4:
        77:4f:32:63:96:7a:49:54:8a:6f:72:3a:dc:bb:71:5a:f7:97:
        05:09:9e:5e:c8:4e:28:3d:af:a3:46:59:08:f4:14:8c:2b:15:
        3c:41:d0:51:c9:42:95:d4:f0:42:54:21:7d:1c:8e:48:df:59:
        d9:2e:cb:cb:4a:87:2e:c7:28:a9:54:da:f7:b6:61:de:80:37:
        f7:f1:03:39:36:12:14:16:39:01:ac:fe:98:f3:d5:97:a6:7d:
        be:87:a8:ee:1f:ec:33:db:71:71:2f:49:07:e0:f3:b1:17:1e:
        91:76:15:81:89:ac:82:29:b2:6b:36:9c:0f:e2:bb:d5:96:4c:
        a2:ab:fc:7d:95:54:85:05:61:02:84:4e:84:e8:f7:9e:0f:30:
        bf:41:d5:f4:2b:3c:4f:4c:ca:9b:f9:33:4d:57:28:51:84:73:
        a0:e6:1a:3a:fc:88:f5:90:34:f2:71:54:6b:5d:80:6d:86:f1:
        e8:bc:6b:54:b4:e0:5f:80:c4:48:35:dc:c2:c5:34:e4:19:f6:
        3b:bf:db:30:5c:17:33:b4:2d:d2:cc:57:95:87:6f:00:4f:18:
        c2:e4:d6:4b:2c:9f:c6:93:95:90:be:32:50:1b:6a:6c:ed:b1:
        9b:5f:bf:47:88:7c:76:e1:4c:99:a3:6d:46:e9:9b:5c:76:78:
        2e:4e:34:5e:cb:37:e8:88:63:03:c8:48:49:ad:c8:bd:e1:af:
        4e:3a:80:96:ae:e4:07:a4:06:99:d5:c0:00:ad:cd:16:a4:80:
        5d:df:8f:b2:08:ff:b9:02:ef:14:03:1c:ff:be:3c:0d:c0:35:
        88:eb:f1:55:57:b3:b1:02:9b:2c:d1:96:06:4b:c0:de:e1:f1:
        1d:12:39:18:25:b8:6c:b3:4a:6f:be:bb:ad:43:b0:fe:0e:a4:
        33:01:f9:3d:0b:26:ac:ed:18:2b:1e:27:06:3a:e5:78:c0:03:
        d4:d4:49:81:32:b8:d9:80:53:27:54:cf:fb:d9:e6:d8:91:76:
        15:b6:2a:e0:82:95:fc:46:39:1a:a0:fd:98:15:fd:d8:22:d9:
        5e:9b:75:73:ca:35:47:7d:59:b9:8d:e4:85:20:65:f5:8f:b6:
        0e:0e:62:0d:3e:2f:5c:ad

Beide Skripte findet ihr auf GitHub, damit ihr sie nutzen oder verbessern könnt.

Warum habe ich geschrieben, dass ich nichts Zuverlässiges finden konnte? Nun, oft stoße ich auf Anleitungen, die noch auf TYPE53 basieren. Das ist nötig, wenn Bind9 den eigentlichen RR-Type noch nicht kennt – also ein klares Zeichen dafür, dass es sich um eine sehr frühe Implementierung handelt.

Ein weiteres häufiges Problem: Der Hash des Local-Parts wird einfach weggelassen. Stattdessen erfolgen die Abfragen direkt auf _smimecert., was aber falsch ist. Ohne den SHA256-Hash des Local-Parts gibt es keine eindeutige Zuordnung zur jeweiligen E-Mail-Adresse.

Warum ist der SMIMEA-DNS-Record so aufgebaut? Ganz einfach:

Der erste Teil, also , sorgt dafür, dass nicht einfach jeder direkt aus der DNS-Zone die E-Mail-Adressen auslesen kann. Statt die E-Mail-Adresse im Klartext zu speichern, wird stattdessen nur der SHA256-Hash des Local-Parts (also der Teil vor dem @) genutzt. Das bedeutet: Wer die genaue E-Mail-Adresse kennt, kann den passenden DNS-Eintrag finden – aber jemand, der einfach nur blind durch die Zone scannt, sieht nur Hashes und kann damit nichts anfangen.

Der _smimecert-Prefix zeigt an, dass es sich um einen SMIMEA-Record handelt, ähnlich wie es bei ._tcp. für SRV-Records oder _acme-challenge. für Let’s Encrypt-Zertifikate der Fall ist.

Und schließlich kommt die Domain, zu der die E-Mail-Adresse gehört.

Zusammen ergibt das einen sicheren, einfach abfragbaren und nicht direkt durchsuchbaren DNS-Eintrag für dein S/MIME-Zertifikat.

Möchte man die Abfrage manuell mit dig für die E-Mail-Adresse „kernel-error@kernel-error.com“ durchführen, muss man zuerst den Local-Part der E-Mail-Adresse (kernel-error) mit SHA256 hashen. Laut RFC 8162, Abschnitt 3.1 wird der SHA-256-Hash auf die ersten 28 Bytes (56 Hex-Zeichen) gekürzt, um die DNS-Label-Längenbeschränkung von 63 Zeichen pro Label (RFC 1035, Abschnitt 2.3.4) einzuhalten.

echo -n "kernel-error" | sha256sum | awk '{print $1}' | cut -c1-56
70e1c7d87e825b3aba45e2a478025ea0d91d298038436abde5a4c2d0

Anschließend kann man die dig-Abfrage korrekt zusammensetzen:

dig +dnssec +short 70e1c7d87e825b3aba45e2a478025ea0d91d298038436abde5a4c2d0._smimecert.kernel-error.com. SMIMEA
3 0 0 30820714308204FCA003020102021073C13C478DA7B114B871F00737 F1B0FB300D06092A864886F70D01010B0500304E310B300906035504 061302504C3121301F060355040A0C1841737365636F204461746120 53797374656D7320532E412E311C301A06035504030C134365727475 6D20534D494D4520525341204341301E170D32353033313331333431 35355A170D3237303331333133343135345A30783114301206035504 040C0B76616E206465204D65657231123010060355042A0C09536562 61737469616E311E301C06035504030C1553656261737469616E2076 616E206465204D656572312C302A06092A864886F70D010901161D6B 65726E656C2D6572726F72406B65726E656C2D6572726F722E636F6D 30820222300D06092A864886F70D01010105000382020F003082020A 0282020100D0A90BC53ABA0408543FE600F0F71C17BE7EB4A8996A8E F5E9122AAC8E7F39D627186617C4D6CA734E1A9E6302F8076065EA93 D762542D2C12BFF32D5D4942B9A8AA84E2E63CE9B843C1665C014A65 72A42E376ED0629694FCC942FE53D76052A40CDAB1257A1D501D9C65 DE18F27C5490A24181498A202E56F4DC0FDCBFE94766F96EBF47C872 3744ABD69DC684417106DF3D4F12FD52A13B786490366DBF6CB5A843 621CD686B06D072FD7D486BD0AC706021D137A365718DCD8709D55B6 4428F8DB56B268BDBED463A25231B40566C041A48958BE1767E27E21 881D2109935C02F27EA306B64997683EEFDF8685F4F090AB09692F23 2CD34AC7FF2296768CED62C68C37B4C3DD9F04EC9F5C9BB9F712A503 2AC2F83D68DA756E4F2886A6F65889CFAEA0C15E3624EA3D9E3EFF91 D68606F7B7B1B7120035AD4F71369E6D79977B4B2CC3575AC51CAF41 9E795B78822DD36B6D0B0E4622BCE55F7B27FCB52FDCD6A4FBD33EF0 9F897CADA2E793D1509DE54773B3FBE9091CEA2E27A41CBA38A08BBB E1B15BF56EB35B21D66F5B1B1CC6FDD6362AA88A4010F3D2732F071A 841BC765D6F74C3B430D036A327918D08156BA2882D78113DD156335 99319F4BD5D4F12E1F0102BA33766ADF09DC58323246D20BAC815BE5 B8822C260EFBB07ADBAB98FA42F31650FEFAE5D679D4AD29992F199D 59F38D54988D77B61E740CBF470203010001A38201C2308201BE300C 0603551D130101FF0402300030410603551D1F043A30383036A034A0 328630687474703A2F2F63736D696D6572736163612E63726C2E6365 7274756D2E706C2F63736D696D6572736163612E63726C3081830608 2B0601050507010104773075302E06082B0601050507300186226874 74703A2F2F63736D696D6572736163612E6F6373702D63657274756D 2E636F6D304306082B060105050730028637687474703A2F2F63736D 696D6572736163612E7265706F7369746F72792E63657274756D2E70 6C2F63736D696D6572736163612E636572301F0603551D2304183016 801466FBC30FBEF4BFE09CC9AB4DDE4719BDC0CAA668301D0603551D 0E041604148D8C102E11D87004F7DDB4E04FF01781888A32A0304C06 03551D20044530433009060767810C010504023036060B2A84680186 F677026401013027302506082B06010505070201161968747470733A 2F2F7777772E63657274756D2E706C2F435053301D0603551D250416 301406082B0601050507030406082B06010505070302300E0603551D 0F0101FF0404030204F030280603551D110421301F811D6B65726E65 6C2D6572726F72406B65726E656C2D6572726F722E636F6D300D0609 2A864886F70D01010B0500038202010070724799F05CF4C821854F43 BD950BB608B989046349214F9D0EEC79F73A59DBF4063608FE5A7A7F A50CD46A15486018EB9C334418084D8F97FE32EA21CCBAFE902BF647 2DB6CA60D79EBE09919AFA0652D92CB13B506400BAF4774F3263967A 49548A6F723ADCBB715AF79705099E5EC84E283DAFA3465908F4148C 2B153C41D051C94295D4F04254217D1C8E48DF59D92ECBCB4A872EC7 28A954DAF7B661DE8037F7F10339361214163901ACFE98F3D597A67D BE87A8EE1FEC33DB71712F4907E0F3B1171E9176158189AC8229B26B 369C0FE2BBD5964CA2ABFC7D955485056102844E84E8F79E0F30BF41 D5F42B3C4F4CCA9BF9334D5728518473A0E61A3AFC88F59034F27154 6B5D806D86F1E8BC6B54B4E05F80C44835DCC2C534E419F63BBFDB30 5C1733B42DD2CC5795876F004F18C2E4D64B2C9FC6939590BE32501B 6A6CEDB19B5FBF47887C76E14C99A36D46E99B5C76782E4E345ECB37 E8886303C84849ADC8BDE1AF4E3A8096AEE407A40699D5C000ADCD16 A4805DDF8FB208FFB902EF14031CFFBE3C0DC03588EBF15557B3B102 9B2CD196064BC0DEE1F11D12391825B86CB34A6FBEBBAD43B0FE0EA4 3301F93D0B26ACED182B1E27063AE578C003D4D4498132B8D9805327 54CFFBD9E6D8917615B62AE08295FC46391AA0FD9815FDD822D95E9B 7573CA35477D59B98DE4852065F58FB60E0E620D3E2F5CAD

Was bedeutet das?
3 → Gibt an, dass es sich um einen S/MIMEA-Record handelt. Die Zahl steht für den sogenannten „Usage“-Wert, also wie das Zertifikat genutzt wird. In diesem Fall bedeutet 3, dass es für eine End-Entity-Zertifizierung gedacht ist, also für die tatsächliche E-Mail-Verschlüsselung und Signatur.

0 → Der „Selector“-Wert. Hier steht 0, was bedeutet, dass der gesamte Public Key aus dem Zertifikat gespeichert wird. Alternativ könnte 1 stehen, dann wäre nur der „Subject Public Key Info“-Teil enthalten.

0 → Gibt an, welche Hash-Funktion verwendet wird. Ist es 1, steht es für SHA-256 steht. Alternativ könnte 2 für SHA-512 verwendet werden oder, wie in unserem Fall 0, was für das komplette Zertifikat steht.

Hexwerte → Das ist der eigentliche Zertifikatsinhalt, also der öffentliche Schlüssel in hexadezimaler Darstellung.

Möchte man den kompletten DNS-Record einmal manuell auf der Konsole prüfen, geht das wie folgt:

dig +short 70e1c7d87e825b3aba45e2a478025ea0d91d298038436abde5a4c2d0._smimecert.kernel-error.com SMIMEA | sed 's/^3 0 0 //' | tr -d '[:space:]' > dns_cert.hex

Damit holen wir uns den SMIMEA-Eintrag, entfernen die vorderen 3 0 0, da diese nur die Nutzungsparameter angeben, und speichern den reinen HEX-Wert in eine Datei.

xxd -r -p dns_cert.hex dns_cert.der

Hier wandeln wir den HEX-String in eine binäre DER-Datei um.

openssl x509 -inform DER -in dns_cert.der -text -noout

So kann man sich das Zertifikat im lesbaren Format anzeigen lassen.

Und nun?

SMIMEA ist leider noch immer nicht besonders weit verbreitet. Das liegt sicherlich daran, dass das RFC noch immer experimental ist, aber auch daran, dass es auf weiteren Techniken aufbaut, die ebenfalls eher selten genutzt werden. So braucht man SMIMEA nur, wenn man überhaupt selbst ein S/MIME-Zertifikat zur Signatur und Verschlüsselung von E-Mails verwendet. Zusätzlich muss die Domain per DNSSEC geschützt sein – was noch weniger verbreitet ist – und dann muss auch noch der zusätzliche Mehrwert von SMIMEA verstanden werden.

Denn SMIMEA verteilt nicht nur die Zertifikate, sondern macht einen direkt initial verschlüsselt erreichbar. Wenn man der Empfänger einer solchen signierten Nachricht ist, kann man das Zertifikat zudem gegen eine vertrauenswürdige DNS-Zone halten und sich so vergewissern, dass es wirklich die Signatur des Absenders ist – ähnlich wie bei TLSA/DANE.

Ihr kennt das doch mit der Sicherheit im Internet: Sie ist nur relevant, wenn man damit Geld verdienen kann oder wenn man Opfer geworden ist. Die Implementierung von SMIMEA ist also aktuell sehr überschaubar. Es gibt Milter für beispielsweise Postfix oder Plugins für Thunderbird, aber vor allem im Enterprise-Umfeld ist mir momentan keine funktionierende Lösung bekannt.

Pffff… Eigentlich wollte ich doch nur schnell schreiben, dass ich da zwei Python-Skripte zusammengebastelt habe – und am Ende ist es doch wieder so ein riesiges Ding geworden. 😅

Aber ich denke, vor allem der Teil mit dem gekürzten Hash des Local-Parts der E-Mail-Adresse ist wichtig zu erklären. Das ist echt eine verrückte Konstruktion. Klar, das hat seinen Sinn, aber zumindest ich bin damals genau an diesem Punkt hängen geblieben.

Naja, jetzt könnt ihr die Skripte nutzen und euch den ganzen Fummel selbst auf der CLI anschauen, testen und vor allem auch verstehen.

Viel Spaß! 😃


B.t.w.: Das einzig korrekt funktionierende online Tool, was ich finden konnte ist: https://www.co.tt/smimea.cgi

Alle anderen sind nicht erreichbar, halten sich nicht ans RFC oder ich war zu blöde, sie zu bedienen.

DNS over TLS (DoT) mit BIND, Stunnel und Android 9 einrichten

Die Zeit ging weiter, die Entwicklung bei BIND und DNS ebenfalls. Daher gibt es nun einen neuen Beitrag, der das aktuelle Setup mit BIND 9.20 auf FreeBSD 15 beschreibt – inklusive sauberer Trennung von authoritative DNS (Port 53) und öffentlichem Resolver (DoT/DoH) sowie reproduzierbaren CLI-Tests für IPv4 und IPv6. Bitte dort weiterlesen.

Die eigenen DNS Anfragen über eine Verschlüsselte Verbindung an einen DNS Server zu schicken welchem man vertraut, dieses liest sich schon gut oder? Keiner verfolgt mein Surfverhalten und zusammen mit DNSSEC schiebt mir so schnell keiner falsche Records unter 🙂

Am ehesten vertraue ich meinem eigenen DNS Server (ns1.kernel-error.de). Auf diesem arbeitet ein Bind und vor diesen habe ich für DoT stunnel gestellt. Die Konfiguration vom stunnel sieht dabei grob wie folgt aus:

[dns4]
accept = 853
connect = 127.0.0.1:53
cert = /usr/local/etc/stunnel/ssl/dns.crt
key = /usr/local/etc/stunnel/ssl/dns.key
CAfile = /usr/local/etc/stunnel/ssl/ca.crt
ciphers = ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
options = NO_SSLv2
options = NO_SSLv3
options = NO_TLSv1
options = NO_TLSv1.1
options = CIPHER_SERVER_PREFERENCE
options = DONT_INSERT_EMPTY_FRAGMENTS
renegotiation = no
TIMEOUTclose = 0

[dns6]
accept = 2a03:4000:38:20e::53:853 connect = ::1:53 cert = /usr/local/etc/stunnel/ssl/dns.crt key = /usr/local/etc/stunnel/ssl/dns.key CAfile = /usr/local/etc/stunnel/ssl/ca.crt ciphers = ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 options = NO_SSLv2 options = NO_SSLv3 options = NO_TLSv1 options = NO_TLSv1.1 options = CIPHER_SERVER_PREFERENCE options = DONT_INSERT_EMPTY_FRAGMENTS renegotiation = no 

Die TLS Konfiguration ergibt dabei nun folgendes Bild: https://tls.imirhil.fr/tls/ns1.kernel-error.de:853

Auf einem Android 9 Gerät kann ich also nun unter den Einstellungen ==> Netzwerk & Internet ==> Erweitert ==> Privates DNS meinen Nameserver eintragen.

Screenshot der Konfigurationseinstellungen für DoT auf einem Android 9.

Jetzt sieht mir keiner mehr beim meinen DNS Abfragen zu 😀

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

TLS 1.3 ist im Mailbetrieb kein Sonderfall mehr, sondern der Normalzustand. Voraussetzung ist lediglich, dass Postfix und Dovecot gegen eine aktuelle OpenSSL-Version gelinkt sind. Sobald OpenSSL TLS 1.3 unterstützt, wird es automatisch verwendet. Eine explizite Aktivierung in der Applikation ist nicht erforderlich.

Die eigentliche Aufgabe der Konfiguration besteht daher nicht darin, TLS 1.3 „einzuschalten“, sondern darin, alte Protokollversionen sauber zu deaktivieren 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

Postfix und Dovecot müssen gegen OpenSSL ≥ 1.1.1 gebaut sein. OpenSSL 3.x funktioniert ebenfalls ohne Einschränkungen. Welche Version tatsächlich genutzt wird, lässt sich eindeutig prüfen:

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

Wenn hier OpenSSL 1.1.1 oder neuer auftaucht, ist TLS 1.3 verfügbar.

Postfix

Postfix verwendet TLS 1.3 automatisch, sofern der Client es anbietet. Entscheidend ist, welche Protokollversionen minimal erlaubt werden. TLS 1.0 und TLS 1.1 gelten als kryptographisch überholt und sollten nicht mehr akzeptiert werden.

Die folgende Konfiguration beschränkt Postfix auf TLS 1.2 und neuer. TLS 1.3 wird dabei bevorzugt ausgehandelt, TLS 1.2 dient nur noch als Fallback.

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

Cipher-Optionen in Postfix gelten ausschließlich für TLS 1.2 und ältere Protokolle. TLS 1.3 verwendet fest definierte Cipher-Suites und ignoriert diese Einstellungen vollständig. Dennoch ist es sinnvoll, für den TLS-1.2-Fallback eine saubere Policy zu setzen.

tls_preempt_cipherlist = yes

smtpd_tls_ciphers = high
smtp_tls_ciphers  = high

Damit werden nur moderne Cipher mit Forward Secrecy genutzt, abhängig von den OpenSSL-Defaults der jeweiligen Distribution.

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

Auch Dovecot nutzt TLS 1.3 automatisch, sofern OpenSSL es bereitstellt. Die relevante Einstellung ist die minimale Protokollversion. Alles darunter wird explizit ausgeschlossen.

ssl = required
ssl_min_protocol = TLSv1.2

Die Cipher-Liste in Dovecot betrifft ebenfalls nur TLS 1.2 und älter. TLS 1.3 wird davon nicht beeinflusst. Eine explizite, restriktive Cipher-Liste verhindert jedoch unsaubere Fallbacks bei älteren 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

Die 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 fest definiert und bestehen ausschließlich aus modernen AEAD-Verfahren mit integrierter Authentifizierung und Forward Secrecy. Typische Cipher sind AES-GCM und CHACHA20-POLY1305.

Postfix und Dovecot bieten keine Möglichkeit, diese Cipher direkt zu konfigurieren. Die Auswahl erfolgt intern durch OpenSSL während des Handshakes. Das ist beabsichtigt und reduziert Fehlkonfigurationen erheblich.

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

Verifikation

Ob TLS 1.3 tatsächlich genutzt wird, lässt sich eindeutig prüfen.

SMTP mit STARTTLS:

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

IMAPS:

openssl s_client -connect mail.example.com:993 -tls1_3

Wird der Handshake erfolgreich aufgebaut und ein moderner AEAD-Cipher angezeigt, ist TLS 1.3 aktiv. Fällt die Verbindung auf TLS 1.2 zurück, greift die konfigurierte Cipher-Liste.

Fazit

TLS 1.3 erfordert in Postfix und Dovecot keine Sonderbehandlung. Entscheidend ist eine aktuelle OpenSSL-Version, eine klare Mindest-TLS-Policy und eine saubere Cipher-Konfiguration für den unvermeidbaren TLS-1.2-Fallback.

Alles andere erledigt der TLS-Stack selbst.

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

TLS 1.3 ist da!

Im August wurde TLS 1.3 auf der IETFE-Tagung als fertig beschlossen 😀 Damit haben sich aber alle wirklich Zeit gelassen! OpenSSL hat am 11.09.2018 die Version 1.1.1 (LTS) freigegeben. Am 12.09.2018 ist diese in die FreeBSD Ports gekommen und:

root@www:/ # /usr/local/bin/openssl version
OpenSSL 1.1.1 11 Sep 2018

Fehlt also nur noch ein Eintrag in der make.conf und schon lässt sich nginx sauber dagegen bauen und alles automatisch mit portmaster auf dem neusten Stand halten 🙂

/etc/make.conf
DEFAULT_VERSIONS+= ssl=openssl111

Schaut mal nach, die meisten machen wohl jetzt schon TLS 1.3 beim lesen dieser Zeilen ^^

Qualys und SSL Labs hängen leider noch etwas nach, hier wird noch auf/gegen die Draft Version geprüft (For TLS 1.3 tests, we currently support draft version 28.). Aber ich wette das wird nicht mehr lange dauern!

Kleines Update, die HIGH-TECH Bridge Jungs testen sauber auf TLS 1.3.

Ich wurde gerade drauf hingewiesen, dass die Developer Version von ssllabs TLS 1.3 schon sauber testet. Danke Jost 😀

https://dev.ssllabs.com/ssltest/analyze.html?d=www.kernel%2derror.de&s=2a01%3a4f8%3a161%3a3ec%3a0%3a0%3a0%3a443&hideResults=on&latest

Kein TLS 1.0 mehr

Da TLS 1.0 zum 30.06.2018 aus dem PCI Support fliegt (was nach knapp 19 Jahren auch mal ok ist), habe ich bei mir gerade überall den TLSv1.0 Support deaktiviert. Nein ich möchte nicht PCI konform sein… Damit sorge ich nun wieder einmal dafür, dass man mich mit einiger alter Software/Hardware und Betriebssystemen nicht mehr erreicht. Für mich ganz persönlich kann ich damit sehr gut leben 🙂 Wer jetzt noch mit so einer „Kiste“ unterwegs ist…. Na, der ist Kummer gewohnt!

Wen es interessiert der kann mit Qualys SSL Labs alles Mögliche scannen und auch direkt sehen welche Systeme wohl bei einem selbst nicht mehr funktionieren werden.

Zusätzlich spiele ich schon länger mit dem Gedanken bei meinem Mailserver Übertragungen ohne Transportverschlüsselung komplett zu verbieten. Für mich selbst kann ich es ja frei entscheiden. Lieber keine E-Mail als eine ohne Krypto! Ich werde mal auswerten wie denn das Verhältnis ist und welche E-Mails mich nicht mehr erreichen würden. Dann sehen wir mal weiter! Ich bin nur deswegen etwas zögerlich, weil mir in der Vergangenheit immer mal wieder Gegenstellen unter die Nase gekommen sind, bei welchen ich fest davon ausgegangen wäre, dass sie TLS einsetzten. Städte, Krankenhäuser, Ärzte, Schulen, IT-Security Dienstleister usw. usw… Hier scheint noch immer Unverständnis darüber zu herrschen, für was man denn wohl bitte dieses TLS braucht. Der Dienstleister meiner Heimatstadt begrüßt mich zumindest inzwischen mit einem Cisco Demo Zertifikat. *kopfschüttel* da hat der Admin nach meinen letzten Fragen zu dem Thema wohl den „security ON Button“ in seiner GUI gefunden O_o

Wobei… Mein Brötchengeber setzt auf einen eigenen Exchange Server bei welchem zuletzt 3DES Cipher abgeschaltet werden mussten. Das macht keinen Spaß und keinen Sinn. Windows-Admins scheinen hier schmerzfrei zu sein, hm?

TLS 1.3, das wäre ja mal was 🙂 ich warte schon mit schwitzigen Fingern. Zumindest sind wir schon mal bei Beta 5 (29.05.2018). Die Beta 1 vom 20.03 habe ich mir zuletzt in einer Jail angesehen und damit sehr zufrieden etwas herumprobiert. Für so etwas bin ich einfach zu ungeduldig. Ist das bei euch anders? Wollt ihr lieber noch TLSv1.0 haben?

TLS 1 ist tot und damit ist es dann jetzt weg, egal ob im stunnel:

;/usr/local/etc/stunnel/conf.d/tls.conf
[...]
options = NO_SSLv3
options = NO_TLSv1
ciphers = ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DHE-RSA-AES256-SHA256
[...]

Oder unter Postfix:

#/usr/local/etc/postfix/main.cf
[...]
smtp_tls_protocols = TLSv1.2, TLSv1.1, !TLSv1, !SSLv2, !SSLv3
smtp_tls_ciphers = high
smtp_tls_mandatory_exclude_ciphers = MD5, DES, ADH, RC4, PSD, SRP, 3DES, eNULL, aNULL
smtp_tls_exclude_ciphers = MD5, DES, ADH, RC4, PSD, SRP, 3DES, eNULL, aNULL
smtp_tls_security_level = dane
smtp_dns_support_level = dnssec
smtp_tls_loglevel = 1
smtp_tls_mandatory_protocols = TLSv1.2, TLSv1.1, !TLSv1, !SSLv2, !SSLv3
smtp_tls_mandatory_ciphers = high
tls_preempt_cipherlist = yes
tls_random_source = dev:/dev/urandom
smtpd_tls_loglevel = 1 
smtpd_tls_received_header = yes
smtpd_use_tls = yes
smtpd_tls_security_level = may
smtpd_tls_auth_only = yes
smtpd_tls_key_file = /usr/local/etc/postfix/postfix.key
smtpd_tls_cert_file = /usr/local/etc/postfix/postfix.pem
smtpd_tls_session_cache_timeout = 3600s
smtpd_tls_mandatory_exclude_ciphers = MD5, DES, ADH, RC4, PSD, SRP, 3DES, eNULL, aNULL
smtpd_tls_exclude_ciphers = MD5, DES, ADH, RC4, PSD, SRP, 3DES, eNULL, aNULL
smtpd_tls_mandatory_ciphers = high
smtpd_tls_ciphers = high
smtpd_tls_mandatory_protocols = TLSv1.2, TLSv1.1, !TLSv1, !SSLv2, !SSLv3
smtpd_tls_protocols = TLSv1.2, TLSv1.1, !TLSv1, !SSLv2, !SSLv3
smtpd_tls_dh1024_param_file = /usr/local/etc/postfix/dh2048.pem
[...]

Oder auch im Dovecot:

#/usr/local/etc/dovecot/conf.d/10-ssl.conf
[...]
ssl = required
ssl_dh_parameters_length = 4096
ssl_protocols = !SSLv3 !SSLv2 !TLSv1
ssl_cipher_list = AES128+EECDH:AES128+EDH
ssl_prefer_server_ciphers = yes
[...]

Selbstverständlich auch im Nginx:

#/usr/local/etc/nginx/nginx.conf
[...]
ssl_stapling on;
ssl_stapling_verify on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp521r1:secp384r1:secp256k1;
ssl_dhparam /usr/local/etc/nginx/ssl/dhparam.pem;
ssl_protocols TLSv1.1 TLSv1.2;
[...]

Und so weiter und so weiter 🙂

DNS über TLS mit Stunnel und BIND9 einrichten: Anleitung für mehr Sicherheit

Ihr erinnert euch an meine Ankündigung über TLS an meinem DNS vor ein paar Tagen? RFC 7858 – DNS over Transport Layer Security

Bei mir ist inzwischen recht oft die Frage nach dem „Wie“ angekommen. Nun ich habe dafür stunnel benutzt. stunnel ist nicht speziell für DNS sondern ist ein Stück Software welches sich vor Dienste schalten lässt die keine oder eine schlechte Implementierung für SSL/TLS haben. Eine komplett stumpfe Konfiguration um zu testen würde zum Beispiel auf einem FreeBSD wie folgt aussehen:

/usr/local/etc/stunnel/conf.d/dnstls.conf

[dns4]
accept = 853
connect = 5.9.24.235:53
cert = /usr/local/etc/stunnel/ssl/dns.crt
key = /usr/local/etc/stunnel/ssl/dns.key
CAfile = /usr/local/etc/stunnel/ssl/ca.crt


[dns6]
accept = :::853 connect = 5.9.24.235:53
cert = /usr/local/etc/stunnel/ssl/dns.crt
key = /usr/local/etc/stunnel/ssl/dns.key
CAfile = /usr/local/etc/stunnel/ssl/ca.crt 

So gestartet lässt sich eine TLS Verbinung zu Port 853 aufbauen und stunnel schiebt dann alles einfach weiter an den Bind auf Port 53. Ob eine SSL/TLS Verbindung aufgebaut werden kann testet man am besten mit openSSL: openssl s_client -connect ns1.kernel-error.de:853 -showcerts Ich werfe weiter unten mal den kompletten Output in den Post…

Um eine komplette DNS Abfrage über TLS zu prüfen nutze ich gerne getdns_query. Dieses ist bereits in den FreeBSD Ports. Ein Test würde wie folgt aussehen: getdns_query @5.9.24.235 -s -a -A -l L www.kernel-error.de AAAA die Option „-l L“ weißt getdns_query dabei an es per TLS zu probieren. Auch hier werde ich den kompletten Output weiter untem im Post zeigen.

Der versprochene openSSL Output

kernel@s-meer-bsd ~> openssl s_client -connect ns1.kernel-error.de:853 -showcerts
CONNECTED(00000003)
depth=2 C = BE, O = GlobalSign nv-sa, OU = Root CA, CN = GlobalSign Root CA
verify return:1
depth=1 C = BE, O = GlobalSign nv-sa, CN = AlphaSSL CA - SHA256 - G2
verify return:1
depth=0 OU = Domain Control Validated, CN = *.kernel-error.de
verify return:1
---
Certificate chain
 0 s:/OU=Domain Control Validated/CN=*.kernel-error.de
   i:/C=BE/O=GlobalSign nv-sa/CN=AlphaSSL CA - SHA256 - G2
-----BEGIN CERTIFICATE-----
MIIIVjCCBz6gAwIBAgIMKHSoWgqp4f0QDMWoMA0GCSqGSIb3DQEBCwUAMEwxCzAJ
BgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMSIwIAYDVQQDExlB
bHBoYVNTTCBDQSAtIFNIQTI1NiAtIEcyMB4XDTE3MDMxMDEwNTI1MloXDTE4MDMx
MTEwNTI1MlowPzEhMB8GA1UECxMYRG9tYWluIENvbnRyb2wgVmFsaWRhdGVkMRow
GAYDVQQDDBEqLmtlcm5lbC1lcnJvci5kZTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
ADCCAgoCggIBAMtVm/TykTvxvwZN0h6H2YeIeu4G+scVCb+kxxa8Jrua7DuLchjm
05wj6zPTe+2opDNNeZ6T5/ISSKczUQO4p+ttxFzl8OGA8FaZe4Qc9FNYdzY35w2d
oMgpTpsO+xTEdLHbXcNvEdFXg/8vyKS5y9Ddp8mSvz/Mt04rj2sjXGWwV00ImDQ1
DHBEuNuvFsnyaXQkDXeC3bA+2EkuVIcFcviQT5At88CDLkP8ygJsD3iDudnVeEJZ
N1AFnjN/qQksjKvT5V75R7GcIhA0a6lC56iBmEykht8YdPy63940hYmO4Ug17p68
7uiPZKUsFkGmYchbkiw5KLTck6VVv9b5Z+lFfIQcfBf5blmaUkQQ8CP3yXXajmfP
3KqJu5c+M3OW9evFiE+z7ihtKVtOHQS86z0ijvSNaCfj9OWQKXhBzBzdEGTogC7n
Iq8YYjveRQ+ExffM+RY3xaqMc1368tUx6ir+0LdGiqgzDC5OcWPqRTNobeTfcETz
VCxqgTfVr4tDNTk1+LmRsWKVDuBtG3p/lJEwCU1z6ZP6xmNTBZc1iOuNOJN+CmYW
ZpKaI3F6JPRK4G2Hu4fa0GWjRHSSZYFkyBl520a8fTMGIY8JlfHfx9HVK2fFJ4yP
NxKligKSydphqEG8cyEU/V3oRlgZ7en1HmrWRrIRiWcmWk3qKl/AZk97AgMBAAGj
ggRDMIIEPzAOBgNVHQ8BAf8EBAMCBaAwgYkGCCsGAQUFBwEBBH0wezBCBggrBgEF
BQcwAoY2aHR0cDovL3NlY3VyZTIuYWxwaGFzc2wuY29tL2NhY2VydC9nc2FscGhh
c2hhMmcycjEuY3J0MDUGCCsGAQUFBzABhilodHRwOi8vb2NzcDIuZ2xvYmFsc2ln
bi5jb20vZ3NhbHBoYXNoYTJnMjBXBgNVHSAEUDBOMEIGCisGAQQBoDIBCgowNDAy
BggrBgEFBQcCARYmaHR0cHM6Ly93d3cuZ2xvYmFsc2lnbi5jb20vcmVwb3NpdG9y
eS8wCAYGZ4EMAQIBMAkGA1UdEwQCMAAwPgYDVR0fBDcwNTAzoDGgL4YtaHR0cDov
L2NybDIuYWxwaGFzc2wuY29tL2dzL2dzYWxwaGFzaGEyZzIuY3JsMC0GA1UdEQQm
MCSCESoua2VybmVsLWVycm9yLmRlgg9rZXJuZWwtZXJyb3IuZGUwHQYDVR0lBBYw
FAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBSL6GOdfjNSVXP7NNrKRfN/
ZEGEJTAfBgNVHSMEGDAWgBT1zdU8CFD5ak86t5faVoPmadJo9zCCAm0GCisGAQQB
1nkCBAIEggJdBIICWQJXAHUAu9nfvB+KcbWTlCOXqpJ7RzhXlQqrUugakJZkNo4e
0YUAAAFat9mThAAABAMARjBEAiBA/XALdgdBZzdvL20DwfeGUAKVhFAueJG6hIWF
eooeSwIgBAMtgDdRxtSkDbKZdkuT9pul6HlZgGSKBLwHjt08rSAAdgDd6x0reg1P
piCLga2BaHB+Lo6dAdVciI09EcTNtuy+zAAAAVq32ZOaAAAEAwBHMEUCIAwdq+Ma
WZ+v8TuKuwIT9oTHT6mlOuov2brZHNa53o5MAiEAq1ZFktpd5XzJQixebUuaCNKW
dZWUF58tKuB4l7xvGOUAdgCkuQmQtBhYFIe7E6LMZ3AKPDWYBPkb37jjd80OyA3c
EAAAAVq32ZZ1AAAEAwBHMEUCIAUVh0ZRcb/+WRb9F+nn/Jmzvgs/bnLQNwEjBUT1
/t2aAiEAmZWAnrB3RnsCbedw8SOvJk6HsZG67T0fdI96M/Pc47kAdgBWFAaaL9fC
7NP14b1Esj7HRna5vJkRXMDvlJhV1onQ3QAAAVq32Za/AAAEAwBHMEUCIQD92ZOc
1xqff1TJ7gsw/ZGtkvzrjIW6uu/Hu7ZxBKkOgQIgRC0TkK19+m8nUN7KDCqyKsZT
DqUrKE01MuPhx1RnIPMAdgDuS723dc5guuFCaR+r4Z5mow9+X7By2IMAxHuJeqj9
ywAAAVq32ZllAAAEAwBHMEUCIQCPAWIduEfXjVVq+qKHEtoy84Nqm+PsibSk8uXq
ziMziQIgJp3NRvIM8bFtzQe/ZQYBnNv2H3MwZmldaIbV5VcbMOQwDQYJKoZIhvcN
AQELBQADggEBAKmQsE/CjF2nRuqaPZht7EFsQpHzihm+VBA48HDN0Uj9JpObHadg
kxNunKd3K+KNsZP4gwg8Z+LfNAU2smK//Ptq7S/y3ECZTniwLMNx4ogekIuQ9i6a
5zgdN3TpWMV/pu2PEguG/FhDIeIEoC5L7qYAKsSq/4VMexUeVfg3IDbdFH0FGlF7
NRAvfY8KfkvkM6c0VhkAuisnYpt+N3RoXOUlQEbv2qRPikiRnLW4hyms0Y73W5v2
GBA6H66lPIqWTzalY9d1kUVY0N+qz/ZgZhdY0LkeTHG4l+XAyKwa241LHGtDHz7m
7c9LBqS3mXSFvfCL9eU2vzDHkU6cMixjf94=
-----END CERTIFICATE-----
 1 s:/C=BE/O=GlobalSign nv-sa/CN=AlphaSSL CA - SHA256 - G2
   i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
-----BEGIN CERTIFICATE-----
MIIETTCCAzWgAwIBAgILBAAAAAABRE7wNjEwDQYJKoZIhvcNAQELBQAwVzELMAkG
A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xNDAyMjAxMDAw
MDBaFw0yNDAyMjAxMDAwMDBaMEwxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
YWxTaWduIG52LXNhMSIwIAYDVQQDExlBbHBoYVNTTCBDQSAtIFNIQTI1NiAtIEcy
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2gHs5OxzYPt+j2q3xhfj
kmQy1KwA2aIPue3ua4qGypJn2XTXXUcCPI9A1p5tFM3D2ik5pw8FCmiiZhoexLKL
dljlq10dj0CzOYvvHoN9ItDjqQAu7FPPYhmFRChMwCfLew7sEGQAEKQFzKByvkFs
MVtI5LHsuSPrVU3QfWJKpbSlpFmFxSWRpv6mCZ8GEG2PgQxkQF5zAJrgLmWYVBAA
cJjI4e00X9icxw3A1iNZRfz+VXqG7pRgIvGu0eZVRvaZxRsIdF+ssGSEj4k4HKGn
kCFPAm694GFn1PhChw8K98kEbSqpL+9Cpd/do1PbmB6B+Zpye1reTz5/olig4het
ZwIDAQABo4IBIzCCAR8wDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8C
AQAwHQYDVR0OBBYEFPXN1TwIUPlqTzq3l9pWg+Zp0mj3MEUGA1UdIAQ+MDwwOgYE
VR0gADAyMDAGCCsGAQUFBwIBFiRodHRwczovL3d3dy5hbHBoYXNzbC5jb20vcmVw
b3NpdG9yeS8wMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5nbG9iYWxzaWdu
Lm5ldC9yb290LmNybDA9BggrBgEFBQcBAQQxMC8wLQYIKwYBBQUHMAGGIWh0dHA6
Ly9vY3NwLmdsb2JhbHNpZ24uY29tL3Jvb3RyMTAfBgNVHSMEGDAWgBRge2YaRQ2X
yolQL30EzTSo//z9SzANBgkqhkiG9w0BAQsFAAOCAQEAYEBoFkfnFo3bXKFWKsv0
XJuwHqJL9csCP/gLofKnQtS3TOvjZoDzJUN4LhsXVgdSGMvRqOzm+3M+pGKMgLTS
xRJzo9P6Aji+Yz2EuJnB8br3n8NA0VgYU8Fi3a8YQn80TsVD1XGwMADH45CuP1eG
l87qDBKOInDjZqdUfy4oy9RU0LMeYmcI+Sfhy+NmuCQbiWqJRGXy2UzSWByMTsCV
odTvZy84IOgu/5ZR8LrYPZJwR2UcnnNytGAMXOLRc3bgr07i5TelRS+KIz6HxzDm
MTh89N1SyvNTBCVXVmaU6Avu5gMUTu79bZRknl7OedSyps9AsUSoPocZXun4IRZZ
Uw==
-----END CERTIFICATE-----
---
Server certificate
subject=/OU=Domain Control Validated/CN=*.kernel-error.de
issuer=/C=BE/O=GlobalSign nv-sa/CN=AlphaSSL CA - SHA256 - G2
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 4014 bytes and written 433 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 4096 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: B1956B432DABE228C78E756329A796FA56C9646BE64326F8F96782BD946CCA82
    Session-ID-ctx: 
    Master-Key: 10329FBAE32471FC56D45E0AA0971CF5EB7977F7569AE4079219D9438E7A0F9DA8EC4150D9A074FC0AD8E63E00849047
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1513937385
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---

Der versprochene getdns_query Output:

kernel@s-meer-bsd ~> getdns_query @5.9.24.235 -s -a -A -l L www.kernel-error.de AAAA
{
  "answer_type": GETDNS_NAMETYPE_DNS,
  "canonical_name": <bindata for www.kernel-error.de.>,
  "just_address_answers":
  [
    {
      "address_data": <bindata for 2a01:4f8:161:3ec::443>,
      "address_type": <bindata of "IPv6">
    },
    {
      "address_data": <bindata for 5.9.24.250>,
      "address_type": <bindata of "IPv4">
    }
  ],
  "replies_full":
  [
     <bindata of 0xd3578500000100010003000703777777...>,
     <bindata of 0xe9288500000100010003000703777777...>
  ],
  "replies_tree":
  [
    {
      "additional":
      [
        {
          "class": GETDNS_RRCLASS_IN,
          "name": <bindata for ns1.kernel-error.de.>,
          "rdata":
          {
            "ipv4_address": <bindata for 5.9.24.235>,
            "rdata_raw": <bindata of 0x050918eb>
          },
          "ttl": 300,
          "type": GETDNS_RRTYPE_A
        },
        {
          "class": GETDNS_RRCLASS_IN,
          "name": <bindata for ns2.kernel-error.org.>,
          "rdata":
          {
            "ipv4_address": <bindata for 176.9.109.53>,
            "rdata_raw": <bindata of 0xb0096d35>
          },
          "ttl": 300,
          "type": GETDNS_RRTYPE_A
        },
        {
          "class": GETDNS_RRCLASS_IN,
          "name": <bindata for ns3.kernel-error.com.>,
          "rdata":
          {
            "ipv4_address": <bindata for 203.137.119.119>,
            "rdata_raw": <bindata of 0xcb897777>
          },
          "ttl": 300,
          "type": GETDNS_RRTYPE_A
        },
        {
          "class": GETDNS_RRCLASS_IN,
          "name": <bindata for ns1.kernel-error.de.>,
          "rdata":
          {
            "ipv6_address": <bindata for 2a01:4f8:161:3ec::53>,
            "rdata_raw": <bindata of 0x2a0104f8016103ec0000000000000053>
          },
          "ttl": 300,
          "type": GETDNS_RRTYPE_AAAA
        },
        {
          "class": GETDNS_RRCLASS_IN,
          "name": <bindata for ns2.kernel-error.org.>,
          "rdata":
          {
            "ipv6_address": <bindata for 2a01:4f8:150:1095::53>,
            "rdata_raw": <bindata of 0x2a0104f8015010950000000000000053>
          },
          "ttl": 300,
          "type": GETDNS_RRTYPE_AAAA
        },
        {
          "class": GETDNS_RRCLASS_IN,
          "name": <bindata for ns3.kernel-error.com.>,
          "rdata":
          {
            "ipv6_address": <bindata for 2001:310:6000:f::1fc7:1>,
            "rdata_raw": <bindata of 0x200103106000000f000000001fc70001>
          },
          "ttl": 300,
          "type": GETDNS_RRTYPE_AAAA
        },
        {
          "do": 0,
          "extended_rcode": 0,
          "rdata":
          {
            "rdata_raw": <bindata of 0x>
          },
          "type": GETDNS_RRTYPE_OPT,
          "udp_payload_size": 4096,
          "version": 0,
          "z": 0
        }
      ],
      "answer":
      [
        {
          "class": GETDNS_RRCLASS_IN,
          "name": <bindata for www.kernel-error.de.>,
          "rdata":
          {
            "ipv6_address": <bindata for 2a01:4f8:161:3ec::443>,
            "rdata_raw": <bindata of 0x2a0104f8016103ec0000000000000443>
          },
          "ttl": 300,
          "type": GETDNS_RRTYPE_AAAA
        }
      ],
      "answer_type": GETDNS_NAMETYPE_DNS,
      "authority":
      [
        {
          "class": GETDNS_RRCLASS_IN,
          "name": <bindata for kernel-error.de.>,
          "rdata":
          {
            "nsdname": <bindata for ns2.kernel-error.org.>,
            "rdata_raw": <bindata for ns2.kernel-error.org.>
          },
          "ttl": 86400,
          "type": GETDNS_RRTYPE_NS
        },
        {
          "class": GETDNS_RRCLASS_IN,
          "name": <bindata for kernel-error.de.>,
          "rdata":
          {
            "nsdname": <bindata for ns1.kernel-error.de.>,
            "rdata_raw": <bindata of 0x036e7331c010>
          },
          "ttl": 86400,
          "type": GETDNS_RRTYPE_NS
        },
        {
          "class": GETDNS_RRCLASS_IN,
          "name": <bindata for kernel-error.de.>,
          "rdata":
          {
            "nsdname": <bindata for ns3.kernel-error.com.>,
            "rdata_raw": <bindata for ns3.kernel-error.com.>
          },
          "ttl": 86400,
          "type": GETDNS_RRTYPE_NS
        }
      ],
      "canonical_name": <bindata for www.kernel-error.de.>,
      "header":
      {
        "aa": 1,
        "ad": 0,
        "ancount": 1,
        "arcount": 7,
        "cd": 0,
        "id": 54103,
        "nscount": 3,
        "opcode": GETDNS_OPCODE_QUERY,
        "qdcount": 1,
        "qr": 1,
        "ra": 0,
        "rcode": GETDNS_RCODE_NOERROR,
        "rd": 1,
        "tc": 0,
        "z": 0
      },
      "question":
      {
        "qclass": GETDNS_RRCLASS_IN,
        "qname": <bindata for www.kernel-error.de.>,
        "qtype": GETDNS_RRTYPE_AAAA
      }
    },
    {
      "additional":
      [
        {
          "class": GETDNS_RRCLASS_IN,
          "name": <bindata for ns1.kernel-error.de.>,
          "rdata":
          {
            "ipv4_address": <bindata for 5.9.24.235>,
            "rdata_raw": <bindata of 0x050918eb>
          },
          "ttl": 300,
          "type": GETDNS_RRTYPE_A
        },
        {
          "class": GETDNS_RRCLASS_IN,
          "name": <bindata for ns2.kernel-error.org.>,
          "rdata":
          {
            "ipv4_address": <bindata for 176.9.109.53>,
            "rdata_raw": <bindata of 0xb0096d35>
          },
          "ttl": 300,
          "type": GETDNS_RRTYPE_A
        },
        {
          "class": GETDNS_RRCLASS_IN,
          "name": <bindata for ns3.kernel-error.com.>,
          "rdata":
          {
            "ipv4_address": <bindata for 203.137.119.119>,
            "rdata_raw": <bindata of 0xcb897777>
          },
          "ttl": 300,
          "type": GETDNS_RRTYPE_A
        },
        {
          "class": GETDNS_RRCLASS_IN,
          "name": <bindata for ns1.kernel-error.de.>,
          "rdata":
          {
            "ipv6_address": <bindata for 2a01:4f8:161:3ec::53>,
            "rdata_raw": <bindata of 0x2a0104f8016103ec0000000000000053>
          },
          "ttl": 300,
          "type": GETDNS_RRTYPE_AAAA
        },
        {
          "class": GETDNS_RRCLASS_IN,
          "name": <bindata for ns2.kernel-error.org.>,
          "rdata":
          {
            "ipv6_address": <bindata for 2a01:4f8:150:1095::53>,
            "rdata_raw": <bindata of 0x2a0104f8015010950000000000000053>
          },
          "ttl": 300,
          "type": GETDNS_RRTYPE_AAAA
        },
        {
          "class": GETDNS_RRCLASS_IN,
          "name": <bindata for ns3.kernel-error.com.>,
          "rdata":
          {
            "ipv6_address": <bindata for 2001:310:6000:f::1fc7:1>,
            "rdata_raw": <bindata of 0x200103106000000f000000001fc70001>
          },
          "ttl": 300,
          "type": GETDNS_RRTYPE_AAAA
        },
        {
          "do": 0,
          "extended_rcode": 0,
          "rdata":
          {
            "rdata_raw": <bindata of 0x>
          },
          "type": GETDNS_RRTYPE_OPT,
          "udp_payload_size": 4096,
          "version": 0,
          "z": 0
        }
      ],
      "answer":
      [
        {
          "class": GETDNS_RRCLASS_IN,
          "name": <bindata for www.kernel-error.de.>,
          "rdata":
          {
            "ipv4_address": <bindata for 5.9.24.250>,
            "rdata_raw": <bindata of 0x050918fa>
          },
          "ttl": 300,
          "type": GETDNS_RRTYPE_A
        }
      ],
      "answer_type": GETDNS_NAMETYPE_DNS,
      "authority":
      [
        {
          "class": GETDNS_RRCLASS_IN,
          "name": <bindata for kernel-error.de.>,
          "rdata":
          {
            "nsdname": <bindata for ns2.kernel-error.org.>,
            "rdata_raw": <bindata for ns2.kernel-error.org.>
          },
          "ttl": 86400,
          "type": GETDNS_RRTYPE_NS
        },
        {
          "class": GETDNS_RRCLASS_IN,
          "name": <bindata for kernel-error.de.>,
          "rdata":
          {
            "nsdname": <bindata for ns1.kernel-error.de.>,
            "rdata_raw": <bindata of 0x036e7331c010>
          },
          "ttl": 86400,
          "type": GETDNS_RRTYPE_NS
        },
        {
          "class": GETDNS_RRCLASS_IN,
          "name": <bindata for kernel-error.de.>,
          "rdata":
          {
            "nsdname": <bindata for ns3.kernel-error.com.>,
            "rdata_raw": <bindata for ns3.kernel-error.com.>
          },
          "ttl": 86400,
          "type": GETDNS_RRTYPE_NS
        }
      ],
      "canonical_name": <bindata for www.kernel-error.de.>,
      "header":
      {
        "aa": 1,
        "ad": 0,
        "ancount": 1,
        "arcount": 7,
        "cd": 0,
        "id": 59688,
        "nscount": 3,
        "opcode": GETDNS_OPCODE_QUERY,
        "qdcount": 1,
        "qr": 1,
        "ra": 0,
        "rcode": GETDNS_RCODE_NOERROR,
        "rd": 1,
        "tc": 0,
        "z": 0
      },
      "question":
      {
        "qclass": GETDNS_RRCLASS_IN,
        "qname": <bindata for www.kernel-error.de.>,
        "qtype": GETDNS_RRTYPE_A
      }
    }
  ],
  "status": GETDNS_RESPSTATUS_GOOD
}

Oh und weil ich gerade dabei war… Ich habe direkt ns2.kernel-error.org mit einem gültigen Zertifikat ausgestattet.

Fragen? Dann fragen 🙂

© 2026 -=Kernel-Error=-RSS

Theme von Anders NorénHoch ↑