Kryptographische Sicherheit entsteht nicht aus beliebigen Kurven, Chiffren und Schlüssellängen1, sondern aus klaren Leitplanken, die der Implementierung im Alltag Grenzen setzen. In OpenSSL heisst dieser Rahmen SecLevel 2. Der Mechanismus wirkt wie ein Sicherheitsgurt für die gesamte TLS-Aushandlung3, indem er Mindestanforderungen an effektive Sicherheitsstärke, Schlüssellängen, Protokollversionen und Signaturalgorithmen durchsetzt, bevor überhaupt über konkrete Cipher-Strings diskutiert wird. Anders formuliert: die Policy entscheidet, ob eine Suite überhaupt in Betracht kommt. Die Suite-Liste entscheidet erst danach über Vorzug und Reihenfolge.
SecLevel operiert auf einer abstrakten Skala. Level 0 erlaubt beinahe alles und dient nur noch zur forensischen Fehlersuche in Museen der IT. Level 1 unterbindet bereits algorithmische Trümmer wie MD54 und mikroskopische Schlüssellängen. Level 2, der verbreitete Distro-Default, setzt auf mindestens 112-Bit-Sicherheitsstärke, unterbindet RC45, SSLv36, zu kurze DH-Gruppen7 und SHA-18 in Signaturen. Höhere Level erhöhen die Schwellen weiter und schliessen zunehmend statische Verfahren aus, bis hin zu sehr grossen RSA-Schlüsseln und nur noch elliptischen Kurven hoher Ordnung. Diese Schwellen wirken global und mit Priorität. Wer sie sauber begreift, versteht, weshalb eine lokale Cipher-Liste allein keine hinreichende Absicherung darstellt.
| Level | Ziel‐Sicherheitsstärke | Kommentar |
|---|---|---|
| 0 | keine Vorgaben | „Alles erlaubt“ (kompatibel mit Altlasten), selbst uralte / gebrochene Algorithmen, wenn sonst aktiviert. Nur für Notfälle. |
| 1 | ≥ 80 bit | Verbietet SSLv2, MD5 (MAC & Signaturen) und alles < 80 bit äquiv. Stärke; RSA/DSA/DH < 1024 bit, ECC < 160 bit verboten. SHA-1-Signaturen sind ab Level 1 nicht mehr zulässig. |
| 2 | ≥ 112 bit | RSA / DSA / DH < 2048 bit, ECC < 224 bit verboten; RC4 verboten; SSLv3 verboten; TLS-Kompression aus. (Hinweis: einige Distros verschärfen Level 2 zusätzlich: TLS < 1.2 wird dort generell gesperrt.)9 |
| 3 | ≥ 128 bit | RSA / DSA / DH < 3072 bit, ECC < 256 bit verboten; Forward Secrecy Pflicht (keine reinen RSA-Key-Exchange-Suiten); TLS < 1.1 verboten; Session-Tickets aus. (Implikation: 3DES fällt meist raus, 2048-RSA-Zertifikate reichen nicht mehr.) |
| 4 | ≥ 192 bit | RSA / DSA / DH < 7680 bit, ECC < 384 bit verboten; SHA-1-MACs verboten; TLS < 1.2 verboten. |
| 5 | ≥ 256 bit | RSA / DSA / DH < 15360 bit, ECC < 512 bit verboten. Nur für Spezialfälle mit sehr hohen Sicherheitsanforderungen. |
In produktiven Umgebungen entscheiden drei weitere Stellschrauben über den Charakter der TLS-Verbindungen. Erstens die Protokollgrenzen, die klären, ob Altlasten wie TLS 1.0 oder 1.1 noch toleriert werden. Zweitens die eigentliche Cipher-Policy für TLS 1.2, denn nur dort existiert die alte Welt der frei kombinierbaren Suiten, in der man PFS10 bewusst einschalten und CBC11 bewusst ausschalten muss. Drittens die TLS-1.3-Ciphersuites12, die strikt getrennt konfiguriert werden und ohnehin nur AEAD13 zulassen, also GCM14 oder Poly130515.
Vor diesem Hintergrund habe ich für meine Systeme eine nüchterne Basis hinterlegt, die bewusst unaufgeregt wirkt und sich dennoch robust verhält. Diese ist konservativ, erklärt die Aushandlung transparent und lässt sich für strengere oder breitere Profile ohne Reibungsverluste anpassen.
openssl_conf = default_conf
[default_conf]
ssl_conf = ssl_sect
[ssl_sect]
system_default = system_default_sect
[system_default_sect]
MinProtocol = TLSv1.2
CipherString = DEFAULT@SECLEVEL=2
Ciphersuites = TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
SignatureAlgorithms = rsa_pss_rsae_sha512:rsa_pss_rsae_sha384:rsa_pss_rsae_sha256
Options = -SessionTicket,ServerPreference,NoRenegotiationDie Struktur des Artefakts orientiert sich an der SSL_CONF-Logik. Über openssl_conf wird die Konfigurationssektion geladen, ssl_conf weist auf die gewünschte Sektion, und system_default aktiviert den systemweiten Default-Block. Der Block selbst enthält fünf Aussagen.
MinProtocol = TLSv1.2erzwingt das untere Ende. TLS 1.0 und 1.1 fallen weg, ohne dass Applikationen ihre lokalen Einstellungen ändern müssten. Das obere Ende bleibt offen, was in der Praxis heisst: wenn beide Seiten TLS 1.3 sprechen, wird es genutzt. Wer das explizit will, ergänztMaxProtocol = TLSv1.3und schliesst damit künftige, potenziell schlecht verstandene Versionen aus, bis eine Revision der Policy stattgefunden hat.CipherString = DEFAULT@SECLEVEL=2nutzt die bewährte Defaultmenge der TLS-1.2-Suiten unter SecLevel 2. Diese Kombination kappt vieles, was ich ohnehin nicht dulde, ohne eine zu eng gestrickte Liste zu pflegen. Der Nachteil liegt auf der Hand. Level 2 lässt, je nach Build, unter TLS 1.2 auch AES-128-GCM zu und schliesst statischen RSA-Schlüsselaustausch nicht grundsätzlich aus. In anderen Worten: PFS ist nicht zwingend, solange ich nicht explizit!kRSAsetze oder nur ECDHE/DHE-Familien zulasse. Genau das ist das klassische Missverständnis von Admin-Konfigurationen, die sich auf SecLevel verlassen und meinen, damit PFS erzwungen zu haben. SecLevel setzt Boden und Decke, nicht die Architektur der Suite.Ciphersuites = TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256trennt die TLS-1.3-Welt sauber ab. TLS 1.3 kennt keine frei kombinierbaren Baukästen, sondern benennt vollständige Suiten. Die Auswahl ist hier bewusst knapp gehalten, weil AES-256-GCM und ChaCha20-Poly1305 das sinnvolle Spektrum abdecken. Systeme mit AES-NI bevorzugen AES-256-GCM, schmalbrüstige CPUs profitieren von ChaCha20. Diese Ordnung ist mitServerPreferencenicht beeinflussbar, da TLS 1.3 die Suite-Präferenz des Servers nicht mehr wie in TLS 1.2 berücksichtigt. Das Flag wirkt nur noch in der alten Welt.SignatureAlgorithmsbschränkt die Signaturalgorithmen auf RSA-PSS16 mit SHA-512, SHA-384 und SHA-256. Die Entscheidung folgt zwei Motiven. PSS ist das robustere RSA-Signaturverfahren, und SHA-1 hat keine Daseinsberechtigung mehr. Die Kehrseite: wer Clients erwartet, die nur ECDSA bewerben oder Server, deren Zertifikatskette rein ECDSA ist, muss diese Signaturalgorithmen zulassenecdsa_secp521r1_sha512:ecdsa_secp384r1_sha384:ed448, sonst scheitert die Aushandlung. Die Zeile ist also spitz und verlangt Kenntnis der Gegenstellen.Options = -SessionTicket,ServerPreference,NoRenegotiationaktiviert die serverseitige Cipher-Reihenfolge. Das ist für TLS 1.2 weiterhin relevant, für TLS 1.3 Bedeutungslosigkeit in Reinkultur.-SessionTicketsowieNoRenegotiationneutralisieren zwei Einfallstore für ungewollte Persistenz alter Sitzungen und komplexe Aushandlungspfadologien.
Die Vorteile dieses Defaults liegen in seiner gelassenen Kompatibilität. SecLevel 2 flankiert die Auswahl mit harten Mindestkriterien. TLS 1.3 wird priorisiert, sobald es möglich ist. TLS 1.2 erhält eine pragmatische Defaultbasis, die ohne exotische Kurven und Suiten funktioniert. RSA-PSS als Signaturwahl setzt ein klares Zeichen zur Hygiene im Signaturraum. Die Konfiguration bleibt kurz genug, um auditierbar zu sein. Wartbarkeit ist ein Sicherheitsfaktor.
Die Nachteile sind ebenso klar umrissen und treffen jedes Artefakt, das auf DEFAULT vertraut. PFS ist nicht erzwungen. AES-128 ist unter TLS 1.2 wahrscheinlich erlaubt, ebenso Camellia oder ARIA in GCM-Varianten, sofern sie im Build enthalten sind. Wer diese Verfahren wirklich vermeiden will, muss das explizit ausdrücken. Zusätzlich fehlen in dieser Fassung bevorzugte Kurvengruppen für ECDHE. Ohne Groups = X448:P-521:P-384 entscheidet der Stack nach eigener Ordnung, was meist akzeptabel ist, manchmal aber messbar Leistung kostet. Schliesslich sind Tickets aktiv und verlängern Sitzungen über Neustarts und Lastverteilung hinweg, was im Einzelfall gewollt ist, in sicherheitskritischen Segmenten aber eher deaktiviert gehört.
Was folgt daraus für einen gehärteten Pfad mit gleichen äusseren Zielen, jedoch schärfer konturierter Innenausstattung? Wer PFS verpflichtend machen will, nimmt die TLS-1.2-Liste in die Hand, trennt strikt TLS-1.2-Cipher von TLS-1.3-Suiten und deaktiviert Tickets. Der Kern und mein gehärteter CISS-Standard sieht so aus:
openssl_conf = default_conf
[default_conf]
ssl_conf = ssl_sect
[ssl_sect]
system_default = system_default_sect
[system_default_sect]
MinProtocol = TLSv1.2
MaxProtocol = TLSv1.3
# TLS 1.2: FS only, AEAD only, no AES128, no static RSA negotiation, no DHE negotiation
CipherString = ECDHE+AES256-GCM:ECDHE+CHACHA20:!AES128:!kRSA:!DHE:!PSK:!SRP:!aNULL:!eNULL:@SECLEVEL=2
# TLS 1.3: only AES-256-GCM and ChaCha20-Poly1305
Ciphersuites = TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
# Preferred ECDHE groups
Groups = X448:P-521:P-384
# Flags: Tickets off, server order, renegotiation off
Options = -SessionTicket,ServerPreference,NoRenegotiation
# Permitted signature algorithms
SignatureAlgorithms = ecdsa_secp521r1_sha512:ecdsa_secp384r1_sha384:ed448:rsa_pss_rsae_sha512:rsa_pss_rsae_sha384:rsa_pss_rsae_sha256Diese Fassung zwingt unter TLS 1.2 auf ECDHE, eliminiert AES128 Cipher und statisches RSA-Key-Exchange, DHE-Key-Exchange, verbietet CBC implizit über die AEAD-Wahl, und hält die Schwelle des SecLevel weiterhin bei 2. TLS 1.3 bleibt auf AES-256-GCM und ChaCha20 begrenzt. Tickets sind in allen Pfaden aus. Diese Konfiguration ist geeignet für Dienste mit kontrollierten Gegenstellen, die keine Altlasten mehr mit sich herumtragen. In Exchange-Freemail-Mischverkehr oder gegenüber eingebetteten Clients kann sie zu scharf schneiden. Clients, die nur
ecdsa_secp256r1_sha256rsa_pkcs1_sha256
sprechen, sind bei mir raus. Das ist aber Intention.
Wer bewusst unter TLS 1.2 neben AES-256 auch ChaCha, ARIA und Camellia zulassen möchte, ohne CBC zu öffnen und ohne PFS zu opfern, greift zur breiteren Positivliste, die nur AEAD-Varianten berücksichtigt und die ECDHE-Pflicht beibehält. Dann sähe die relevante Zeile so aus.
CipherString = ECDHE+AES256-GCM:\
ECDHE+CHACHA20:\
ECDHE+ARIA256-GCM:\
ECDHE+CAMELLIA256-GCM:\
!AES128:!DHE:!kRSA:!PSK:!SRP:!aNULL:!eNULL:@SECLEVEL=2Der Doppelcharakter ist gewollt. Einerseits bleibt die Architektur sauber, denn es existieren nur PFS-Suiten mit AEAD. Andererseits entsteht bewusst mehr Interoperabilität zu Gegenstellen, die ARIA oder Camellia im Katalog haben und diese aus Performancegründen bevorzugen.
Ein Wort zu SignatureAlgorithms. Der PSS-Fokus ist fachlich sauber, kann aber alte Clients, siehe oben, austricksen. macOS- und iOS-Stacks sind unproblematisch, moderne Browser bestehen den Pfad, viele IoT-Stacks sind es nicht. In Umgebungen mit ECDSA-Zertifikaten gehört ECDSA in den Werberaum, und Mischketten, die ECDSA-Leafs mit RSA-Intermediates paaren, verdienen vorab einen Test mit openssl s_client. Die semantische Regel lautet: was nicht beworben wird, kann nicht verhandelt werden. Die praktische Konsequenz lautet: die Zeile entweder an die installierten Zertifikate und an das Gegenstellenprofil anpassen oder testweise entfernen.
Diagnose und Verifikation bleiben simpel, solange man sie regelmässig ausführt. Die erlaubten Suiten unter TLS 1.2 lassen sich mit einem einzigen Befehl inspizieren.
openssl ciphers -s -v -tls1_2 'ECDHE+AES256-GCM:ECDHE+CHACHA20:!DHE:!kRSA:!aNULL:!eNULL:@SECLEVEL=2'Die Verhandlung mit einem Zielhost prüfe ich getrennt nach Protokollversionen. Für TLS 1.3 interessiert allein, ob exakt die beabsichtigten Suiten erscheinen. Für TLS 1.2, ob irgendeine statische RSA-Suite auftaucht. Tut sie das, greift irgendwo eine lokale Applikationskonfiguration in die Library-Defaults ein.
# TLS 1.3, nur die beiden Suiten
openssl s_client -connect host:443 -tls1_3 -ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
# TLS 1.2, PFS-Pflicht und AEAD-Only erzwingen
openssl s_client -connect host:443 -tls1_2 -cipher 'ECDHE+AES256-GCM:ECDHE+CHACHA20:!kRSA'Wer Tickets wirklich aus haben will, prüft die Ausgabe auf das Fehlen von NewSessionTicket-Meldungen oder beobachtet auf Serverseite die Session-Caches. Hier sei nüchtern vermerkt, dass viele Dienste eigene TLS-Schichten und Serverflags pflegen. nginx, Apache, Postfix, Dovecot, OpenLDAP und stunnel können die Library-Defaults respektieren oder übersteuern. Es lohnt sich, die jeweilige Dokumentation auf die Unterstützung von ssl_conf_command und verwandten Mechanismen zu prüfen und die System-Policy mit der Anwendungs-Policy zu vereinheitlichen. Wo das nicht gelingt, gewinnt die Applikation. Dort hilft nur die direkte Applikationskonfiguration.
Ein paar Details verdienen Aufmerksamkeit, weil sie regelmässig im Betrieb auffallen. Diffie-Hellman-Parameter unter SecLevel 2 müssen mindestens 2’048 Bit gross sein. Wer DHE im TLS-1.2-Profil belässt, braucht eine ordentliche Param-Datei. ECDHE mit X25519 und P-256/P-384 genügt in aller Regel und ist effizienter. Mein Fokus liegt auf höchste Sicherheit, deswegen gehe ich hier ebenfalls strikter vor und schliesse DHE17, P-256 und X25519 kategorisch aus. TLS-1.3 berücksichtigt die Serverpräferenz für Suiten nicht mehr, die Reihenfolge in Ciphersuites hat Semantik, beeinflusst die Aushandlung aber nicht wie früher. RSA-PSS setzt eine Kette voraus, die PSS zulässt.
Bleibt die Frage nach dem richtigen Profil. In Core-Diensten, die nur modernisierte Gegenstellen bedienen, läuft das strenge Profil stabil. In gemischten Netzen mit Altlasten und proprietären Stacks zeigt die breitere TLS-1.2-Liste mehr Toleranz, ohne den Kern zu kompromittieren. Entscheidend bleibt, dass SecLevel über allen Listen thront. Wer SecLevel 2 systemweit setzt, hat die grobe Hygiene gratis. Wer darüber hinaus Architekturentscheidungen über PFS, AEAD und Tickets bewusst trifft, erreicht ein technisch sauberes, auditierbares Ergebnis, das sowohl dem Anspruch an Sicherheit als auch dem Anspruch an Betrieb genügt.
Die hier gezeigte Default-Fassung ist kein Dogma. Sie ist ein tragfähiger Startpunkt, den ich je nach Systemrolle und Gegenstellenprofil schärfe oder verbreitere, wobei ich meiner Philosophie treu bleibe und alte Zöpfe und Altlasten konsequent abschneide. Das ist die eigentliche Stärke des SecLevel-Modells. Es zwingt nicht in eine monolithische Wahrheit, sondern in eine klare Grammatik, innerhalb derer man sinnvolle Varianten formulieren kann, die auf den ersten Blick ähnlich aussehen, sich in der konkreten Wirkung jedoch deutlich unterscheiden.
Wer diese Grammatik ernst nimmt, reduziert den Konfigurationsaufwand spürbar. Der Rest ist Disziplin. Kein blindes Vertrauen in default Parameter. Keine unkommentierten Ausnahmen. Keine Tickets im falschen Segment. Und vor jeder grossen Änderung ein kompletter Probehandshake gegen alle relevanten Ziele. Kryptographie ist Mathematik. Betrieb ist Handwerk. Sicherheit entsteht dort, wo beides sauber zusammengeführt wird.
- https://www.keylength.com/en/4/ ↩︎
- https://docs.openssl.org/3.0/man3/SSL_CTX_set_security_level/ ↩︎
- https://www.cloudflare.com/de-de/learning/ssl/what-happens-in-a-tls-handshake/ ↩︎
- https://de.wikipedia.org/wiki/Message-Digest_Algorithm_5 ↩︎
- https://de.wikipedia.org/wiki/RC4 ↩︎
- https://en.wikipedia.org/wiki/Transport_Layer_Security#SSL_1.0,_2.0,_and_3.0 ↩︎
- https://de.wikipedia.org/wiki/Diffie-Hellman-Schl%C3%BCsselaustausch ↩︎
- https://de.wikipedia.org/wiki/Secure_Hash_Algorithm#SHA-1 ↩︎
- https://documentation.ubuntu.com/server/explanation/crypto/openssl/ ↩︎
- https://de.wikipedia.org/wiki/Perfect_Forward_Secrecy ↩︎
- https://de.wikipedia.org/wiki/Cipher_Block_Chaining_Mode ↩︎
- https://datatracker.ietf.org/doc/html/rfc8446 ↩︎
- https://de.wikipedia.org/wiki/Authenticated_Encryption ↩︎
- https://de.wikipedia.org/wiki/Galois/Counter_Mode ↩︎
- https://en.wikipedia.org/wiki/Poly1305 ↩︎
- https://en.wikipedia.org/wiki/PKCS_1 ↩︎
- https://dheatattack.com/ ↩︎
