TLS 1.3 bringt bei Nginx vor allem weniger Latenz, klarere Kryptografie und ein sauberes Sicherheitsniveau. In der Praxis entscheidet aber nicht ein einzelner Schalter, sondern das Zusammenspiel aus Nginx-Build, OpenSSL-Version, Zertifikaten und den richtigen Direktiven. Ich zeige hier, wie ich ein modernes Setup aufbaue, welche Einstellungen wirklich zählen und wie du typische Fehler schnell erkennst.
Die wichtigsten Punkte auf einen Blick
- Für TLS 1.3 brauchst du in Nginx eine passende OpenSSL-Bibliothek; ohne OpenSSL 1.1.1 oder neuer wird es eng.
- ssl_protocols aktiviert TLS 1.3, aber die TLS-1.3-Cipher-Suites werden separat über OpenSSL konfiguriert.
- ssl_ciphers ist vor allem für TLS 1.2 und älter relevant, nicht der zentrale Hebel für TLS 1.3.
- ssl_early_data ist nur für sehr bewusst gewählte Endpunkte sinnvoll, weil Replay-Risiken bleiben.
- HTTP/3 baut auf TLS 1.3 auf, ist aber ein zusätzlicher Schritt und nicht automatisch Pflicht.
- Mit
nginx -t,nginx -Vundopenssl s_client -tls1_3prüfst du das Setup deutlich schneller als nur im Browser.
Was TLS 1.3 in Nginx praktisch verändert
TLS 1.3 ist für den Alltag vor allem aus zwei Gründen interessant: Der Verbindungsaufbau ist schlanker, und viele alte kryptografische Altlasten sind aus dem Spiel. Für Websites mit vielen kurzen Verbindungen spürt man das eher als bei langen Downloads, weil sich die Zeit bis zum ersten nutzbaren Request verkürzt. Dazu kommt, dass TLS 1.3 die Sicherheitsoberfläche reduziert, weil veraltete Verhandlungswege und schwache Cipher-Konstrukte nicht mehr im Mittelpunkt stehen.
Ich trenne das gern in drei Effekte auf:
| Bereich | Was sich ändert | Praktische Folge |
|---|---|---|
| Handshake | Weniger Round-Trips und ein kompakterer Ablauf | Schnellerer Verbindungsaufbau, besonders bei Mobilfunk und hoher Latenz |
| Kryptografie | Nur moderne Verfahren bleiben relevant | Weniger Fehlkonfigurationen, weniger Altlasten im Cipher-Management |
| Wiederaufnahme | Session Resumption und optional 0-RTT | Mehr Performance, aber bei 0-RTT auch mehr Vorsicht nötig |
Wichtig ist der Punkt, der oft übersehen wird: TLS 1.3 ist keine rein kosmetische Versionserhöhung. Wenn du das sauber einsetzt, änderst du nicht nur die Leistung, sondern auch deine Betriebsentscheidungen rund um Sessions, Early Data und die erlaubten Protokolle. Genau deshalb lohnt sich der Blick auf die Voraussetzungen, bevor man an der eigentlichen Konfiguration schraubt.
Welche Voraussetzungen auf Server und Build erfüllt sein müssen
Bei Nginx entscheidet nicht allein das Paket, sondern die tatsächlich gelinkte SSL-Bibliothek. Für TLS 1.3 braucht Nginx OpenSSL 1.1.1 oder neuer; die Nginx-Dokumentation nennt TLSv1.3 außerdem als Standard in ssl_protocols seit Version 1.23.4. Wenn du ein älteres Image, ein altes Distribution-Paket oder ein selbst gebautes Binary verwendest, solltest du das deshalb immer zuerst prüfen.
Meine kurze Prüfliste sieht so aus:
-
nginx -Vausführen und auf die verwendete OpenSSL-Version achten. -
openssl versionoderopenssl version -aprüfen, um die Laufzeitbibliothek zu sehen. - Sicherstellen, dass Zertifikat und Full Chain sauber ausgeliefert werden.
- Bei mehreren Virtual Hosts SNI und Default-Server-Logik mitdenken.
- Falls HTTP/3 geplant ist, die Build-Kette gesondert prüfen, weil dort neuere SSL-Stacks sinnvoll oder nötig sind.
Für QUIC und HTTP/3 ist die Lage noch strenger: Die Nginx-Dokumentation empfiehlt für den Build mit QUIC Support OpenSSL 3.5.1 oder höher, alternativ werden auch BoringSSL, LibreSSL oder QuicTLS genannt. Das ist kein Muss für normales TLS 1.3 auf HTTPS, aber relevant, sobald du dich an HTTP/3 wagst. Wenn diese Basis stimmt, kannst du die Konfiguration deutlich gezielter aufsetzen.

So konfigurierst du die Verbindung sauber
Für einen produktiven Einstieg setze ich zuerst eine solide Basiskonfiguration auf und trenne dann klar zwischen Protokollauswahl und Cipher-Steuerung. Der typische Irrtum ist nämlich, dass ssl_ciphers alles regelt. Das stimmt für TLS 1.2 und älter, bei TLS 1.3 brauchst du dafür zusätzlich OpenSSL-Konfiguration über ssl_conf_command.
server {
listen 443 ssl http2;
server_name example.de;
ssl_certificate /etc/ssl/example.de/fullchain.pem;
ssl_certificate_key /etc/ssl/example.de/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_ecdh_curve auto;
}Wenn du TLS 1.3 bewusst bevorzugen oder eng begrenzen willst, kannst du zusätzlich eine TLS-1.3-Cipher-Suite über OpenSSL vorgeben. Ein Beispiel wäre:
ssl_conf_command Ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256;Der praktische Unterschied ist wichtig: ssl_protocols entscheidet, ob TLS 1.3 überhaupt erlaubt ist. ssl_ciphers wirkt vor allem auf TLS 1.2 und ältere Varianten. Und ssl_conf_command Ciphersuites ist der Hebel, wenn du die TLS-1.3-Cipher-Suiten wirklich steuern willst. ssl_prefer_server_ciphers bleibt für ältere Protokolle relevant, ist aber nicht der zentrale Schalter für TLS 1.3.
Wenn du ein sehr modernes oder internes System betreibst, kannst du auch nur TLS 1.3 zulassen:
ssl_protocols TLSv1.3;Ich würde das nur dann machen, wenn du deine Client-Landschaft kennst. Für öffentliche Angebote ist TLS 1.2 plus TLS 1.3 oft der vernünftigere Zwischenschritt. Damit schließt du moderne Sicherheit nicht aus, ohne ältere, aber noch legitime Clients sofort abzuschneiden. Als Nächstes geht es darum, die Stellschrauben zu sehen, die im Alltag wirklich Wirkung zeigen.
Welche Feineinstellungen wirklich etwas bringen
Wenn die Grundkonfiguration steht, bringen drei Themen in der Praxis am meisten: Session-Wiederaufnahme, Early Data und Zertifikatsprüfung. Genau hier entstehen auch die meisten Fehlentscheidungen, weil man Performance-Gewinn zu schnell gegen Sicherheit aufrechnet, ohne die Anwendungsseite mitzudenken.
| Direktive | Wofür sie taugt | Meine Einordnung |
|---|---|---|
ssl_session_cache shared:SSL:10m; |
Beschleunigt wiederkehrende Verbindungen | Ein guter Startwert; Nginx rechnet grob mit rund 4.000 Sessions pro Megabyte, 10m ist also meist ausreichend |
ssl_session_timeout 10m; |
Steuert, wie lange Session-Daten wiederverwendbar bleiben | 5 bis 10 Minuten sind in vielen Umgebungen ein brauchbarer Bereich |
ssl_early_data off; |
Schaltet TLS 1.3 0-RTT aus | Für die meisten öffentlichen Webanwendungen die sichere Standardwahl |
ssl_stapling on; |
OCSP-Stapling für Serverzertifikate | Sinnvoll, wenn die Zertifikatskette und der Resolver sauber eingerichtet sind |
ssl_ecdh_curve auto; |
Kurvenauswahl für den Key Exchange | Gute Default-Wahl, nur bei strikten Policies bewusst einschränken |
Bei 0-RTT bin ich besonders vorsichtig. Es kann die gefühlte Geschwindigkeit verbessern, aber frühe Daten sind replay-anfällig. Ich würde Early Data nur für eindeutig idempotente Endpunkte erwägen, also etwa für reine Lesezugriffe, nicht für Login, Checkout oder Statusänderungen. Wenn deine Anwendung Early Data überhaupt auswertet, hilft das Nginx-Variable $ssl_early_data dabei, Requests sauber weiterzugeben oder zu blocken.
OCSP-Stapling ist die zweite Stelle, an der viele Setups unnötig wackeln. Damit es stabil läuft, braucht Nginx die Zertifikatskette des Ausstellers über ssl_trusted_certificate und in vielen Fällen auch einen resolver. Wenn die full chain nicht vollständig ist, suchst du sonst lange nach einem Fehler, der eigentlich nur in der Kette steckt. Das ist einer dieser Punkte, an denen eine saubere PKI mehr Wert hat als jede Feinjustierung am Cipher-Set.
Wenn du die Kurven bewusst eingrenzt, prüfe außerdem reale Clients. Gerade bei ECDSA-Zertifikaten muss die verwendete Kurve zum Zertifikat passen, sonst baust du dir mit einer gut gemeinten Härtung unnötige Ausfälle ein. Die richtige Feineinstellung ist also nicht die engste, sondern diejenige, die sicher und kompatibel zugleich bleibt.
Wie du die Konfiguration belastbar testest
Ich verlasse mich bei TLS nie nur auf den Browser. Der Browser zeigt dir am Ende nur das Ergebnis, aber nicht, warum es zustande kam. Für eine technische Prüfung sind drei Dinge deutlich zuverlässiger: die Nginx-Syntaxprüfung, der Blick auf die Build-Optionen und ein direkter TLS-1.3-Handshake von der Kommandozeile.
nginx -t
nginx -V
openssl s_client -connect example.de:443 -tls1_3 -briefMit nginx -t prüfst du die Syntax, mit nginx -V siehst du die Kompilierungsparameter und die angebundene SSL-Bibliothek, und openssl s_client -tls1_3 zeigt dir, ob der Server tatsächlich TLS 1.3 aushandelt. Wenn du zusätzlich eine bestimmte Suite testen willst, kannst du mit -ciphersuites die Auswahl eingrenzen. Das ist besonders nützlich, wenn du vermutest, dass nicht die Protokollversion, sondern nur eine einzelne Suite Probleme macht.
Im Betrieb schaue ich oft auch auf das Log-Feld mit dem ausgehandelten Protokoll. Wenn du $ssl_protocol in den Access-Log aufnimmst, siehst du sehr schnell, ob deine Besucher wirklich TLS 1.3 nutzen oder ob ein Teil des Traffics noch auf TLS 1.2 zurückfällt. Das ist wertvoller als jede theoretische Annahme über den Client-Mix.
Typische Fehlermuster lassen sich gut einordnen:
- Fällt der Handshake auf TLS 1.2 zurück, ist oft die gelinkte OpenSSL-Version zu alt oder
ssl_protocolsnicht korrekt gesetzt. - Greift
ssl_conf_commandnicht, arbeitet dein Nginx-Build vermutlich mit einer zu alten OpenSSL-Kombination. - Wirkt der Test per
s_clientkorrekt, aber der Browser scheitert, liegen die Ursachen häufig bei Zertifikatskette, SNI oder OCSP. - Ist 0-RTT aktiv und dein Backend reagiert unvorhersehbar, solltest du Early Data sofort wieder abschalten.
Wenn diese Prüfungen sauber durchlaufen, bist du technisch auf der sicheren Seite. Dann stellt sich nur noch die Frage, ob du zusätzlich HTTP/3 aktivieren willst oder ob TLS 1.3 auf HTTP/1.1 und HTTP/2 schon genau das liefert, was du brauchst.
Wann HTTP/3 sinnvoll ist und wann nicht
HTTP/3 ist attraktiv, aber es ist nicht dasselbe wie TLS 1.3. Der Sicherheits- und Handshake-Gewinn kommt bereits mit TLS 1.3, auch wenn du weiterhin über HTTP/1.1 oder HTTP/2 arbeitest. HTTP/3 lohnt sich dann, wenn du von QUIC auf Transportebene profitieren willst, etwa bei instabilen Netzen, wechselnden Verbindungen oder sehr latenzsensiblen Anwendungen.
Die Nginx-Dokumentation sagt klar: QUIC und HTTP/3 sind seit Version 1.25.0 verfügbar, und QUIC braucht TLS 1.3. Praktisch bedeutet das: Für einen HTTP/3-Server brauchst du zusätzlich einen UDP-Listener, oft einen zweiten Listener für klassisches HTTPS und eine saubere Planung für Alt-Svc und Verbindungstest. Ich würde HTTP/3 deshalb nie nur deshalb aktivieren, weil es modern klingt. Es sollte einen messbaren Mehrwert liefern.
Ein pragmatischer Einstieg sieht so aus:
- erst TLS 1.3 auf dem bestehenden HTTPS-Stack stabilisieren,
- dann Messwerte zu Latenz und Fehlerraten vergleichen,
- erst danach HTTP/3 in einer kontrollierten Stufe ergänzen.
Für viele Unternehmensseiten reicht das völlig aus. Der größere Nutzen entsteht oft durch korrektes TLS 1.3, saubere Zertifikatskette, Session-Wiederaufnahme und vernünftiges Stapling. HTTP/3 ist dann die nächste Ausbaustufe, nicht der erste Rettungsanker. Genau so würde ich es auch in produktiven Umgebungen staffeln.
Worauf ich in produktiven Umgebungen besonders achte
Wenn ich eine Nginx-Installation auf TLS 1.3 bringe, richte ich mich an ein paar klaren Leitplanken aus:
- Ich prüfe zuerst die echte OpenSSL-Bibliothek, nicht nur die Paketnummer.
- Ich lasse TLS 1.2 meist vorerst an, bis Messdaten zeigen, dass die Client-Landschaft modern genug ist.
- Ich behandle
ssl_ciphersundssl_conf_command Ciphersuitesals getrennte Hebel. - Ich aktiviere 0-RTT nur dort, wo der Anwendungsfall replay-sicher ist.
- Ich lasse OCSP-Stapling und die Zertifikatskette nicht als Nebensache laufen, sondern prüfe sie gezielt.
- Ich messe den tatsächlichen Protokollmix im Log, statt auf Annahmen zu vertrauen.
Wenn ich ein neues System aufsetze, starte ich fast immer mit TLS 1.2 und 1.3 gemeinsam, aktiviere Stapling, halte Early Data aus und prüfe den Effekt auf echte Clients. Erst wenn die Messwerte stabil sind und der Nutzerkreis eindeutig modern ist, lohnt sich die engere Restriktion auf nur TLS 1.3 oder der zusätzliche Schritt zu HTTP/3. Genau diese Reihenfolge reduziert Risiko und spart später viel Debugging-Zeit.