Secrets, PKI & CertificatesVII · TLS for OperatorsTLS
Protocol versions, cipher suites and configuration policy in 2026
What you'll learn
- State the version floor the current BCP 195 documents require and which RFC changed it
- Choose TLS 1.2 cipher suites, curves and key sizes that match RFC 9325
- Distinguish a client-side refusal to offer a version from a server-side policy result
- Assess session resumption, ticket key rotation and 0-RTT against their documented risks
Prerequisites
Verified against OpenSSL 3.5.x teaching target; 3.0+ minimum · OpenSSH 10.x teaching target; 8.2+ minimum for certificate workflows · OpenBao 2.6.x · Smallstep step-ca 0.30.x · Certbot / Pebble Certbot current release; Pebble 2.10.x ACME test server · Kubernetes (cross-course target) 1.36.x · PostgreSQL 17.x · 2026-08-26
Most TLS configuration in production was copied from a guide, and most of those guides were written against a version of BCP 195 that has since been amended. Getting this right is not about maximum strictness. It is about knowing which document says what, so that a policy can be defended in a review and revisited when the documents move again, which they did in July 2026.
What BCP 195 requires now
BCP 195 is not one RFC. It is RFC 8996, which deprecates TLS 1.0 and TLS 1.1, RFC 9325, which gives the detailed recommendations, and since July 2026 RFC 9852, which amends RFC 9325’s version guidance. Any hardening document that names only the first two is out of date.
RFC 9325 requires that implementations must not negotiate SSL 2, SSL 3, TLS 1.0 or TLS 1.1, and RFC 8996 states the prohibition for TLS 1.0 and TLS 1.1 in normative detail, including that a party receiving a hello with a prohibited protocol version must respond with a protocol version alert and close the connection.
RFC 9852 then changed the balance between the two surviving versions. RFC 9325 had said that TLS 1.2 must be supported and TLS 1.3 should be. RFC 9852 states that any new protocol using TLS must specify TLS 1.3 as its default, that TLS 1.2 may be specified as an additional non-default option where deployment considerations demand, and it is explicit that these changes apply to TLS and not to DTLS.
flowchart TD
A["what are you configuring?"] -- "a new protocol or service" --> B["TLS 1.3 MUST be the default\nRFC 9852"]
A -- "an existing estate" --> C{"any client that\ncannot speak TLS 1.3?"}
C -- "none found" --> D["set the floor at TLS 1.3"]
C -- "yes, and named" --> E["permit TLS 1.2 as well\nand prefer TLS 1.3"]
E --> F["record the endpoint,\nthe owner and a removal date"]
B --> D
G["TLS 1.0 and TLS 1.1"] --> H["MUST NOT be negotiated\nRFC 8996"]
The decision the diagram forces is the useful one. TLS 1.2 is permitted, but only as a named exception with an owner attached. An estate where TLS 1.2 is enabled everywhere because nobody checked is not the same as one where it is enabled on four endpoints that have a replacement date, even though the configuration files look identical.
Suites, curves and key sizes worth configuring
For TLS 1.3, RFC 9325 defers entirely and points at the TLS 1.3
specification. RFC 9846 states that a compliant application must
implement TLS_AES_128_GCM_SHA256 and should implement
TLS_AES_256_GCM_SHA384 and TLS_CHACHA20_POLY1305_SHA256. A
current OpenSSL build enables exactly those three by default:
openssl ciphers -s -tls1_3
TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256
For TLS 1.2, RFC 9325 names four recommended suites:
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 and
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384. It also retires the old
mandatory-to-implement suite, saying implementations should not
support TLS_RSA_WITH_AES_128_CBC_SHA.
The prohibitions are worth reading as a set, because several catch configurations that look modern:
- Must not negotiate. NULL encryption, RC4, and anything offering less than 112 bits of security including export-grade suites.
- Should not negotiate. Anything below 128 bits of security, which RFC 9325 explicitly applies to 3DES on the grounds that its effective strength is 112 bits rather than the nominal 168.
- Should not negotiate. Static RSA key transport, the
TLS_RSA_WITH_*family, because it provides no forward secrecy. - Should not negotiate. Non-ephemeral finite-field or elliptic curve Diffie-Hellman, which are subject to invalid curve attacks.
- Should not negotiate. Ephemeral finite-field Diffie-Hellman,
the
TLS_DHE_*family, on grounds of construction fragility. This surprises people: forward secrecy is required, but the vehicle is ECDHE and not DHE.
Key sizes and curves are equally specific. RFC 9325 requires DH key lengths of at least 2048 bits where MODP groups are used, forbids curves of less than 224 bits, and requires servers authenticating with RSA to use certificates with at least a 2048-bit modulus, with SHA-256 recommended and SHA-1 or MD5 forbidden. Clients and servers should support NIST P-256 and X25519.
A configuration that carries this policy is short:
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_session_timeout 1d;
ssl_session_tickets off;
Proving the floor, and one error that misleads
A configuration file is a claim. The evidence is a negotiated connection. The natural instinct is to attempt a handshake at a version you believe is refused and treat the failure as proof. That instinct produces a genuinely misleading result on a modern toolchain.
Asking OpenSSL 3.5 to connect using TLS 1.1 returns this:
error:0A0000BF:SSL routines:tls_setup_handshake:no protocols available
Read the function name. tls_setup_handshake runs before anything
is sent. The build refused to offer TLS 1.1 at its default security
level, so no ClientHello left the machine and the server expressed no
opinion whatsoever. Pasting that string into a hardening ticket as
evidence that the server rejects TLS 1.1 is a false attestation, and
it will survive until someone tests from a client that can still
offer the version.
Resumption, tickets and 0-RTT
Resumption is where a version policy quietly leaks. RFC 9325 requires that resumption information must be authenticated and encrypted, that the cipher protecting a ticket must be at least as strong as the main TLS cipher suite, that ticket encryption keys must be changed regularly with once a week given as the example, that old ticket encryption keys must be destroyed at the end of their validity period, and that ticket validity must be limited to a reasonable duration such as half the ticket key validity.
It also records a privacy consequence that rarely reaches a design document: session resumption introduces potential privacy issues where the server is able to track the client, in some cases indefinitely.
0-RTT deserves a flat answer. RFC 9325 states that applications must avoid the feature unless an explicit specification exists for the application protocol in question, and it points to RFC 8470 for HTTP and to the QUIC specification for QUIC. RFC 9846 restated the security properties carefully: there are no guarantees of non-replay between connections, and forward secrecy for 0-RTT data depends on server behaviour that the client cannot observe, so absent out-of-band knowledge the client should assume the data is not forward secret. Enabling 0-RTT to save a round trip on a request that changes state is how a duplicated payment happens.
Where post-quantum key exchange fits
Hybrid post-quantum key agreement stopped being a draft topic. RFC 10024, published in August 2026 on the standards track, defines three hybrid mechanisms for TLS 1.3 that combine ML-KEM with an elliptic curve exchange: X25519MLKEM768, SecP256r1MLKEM768 and SecP384r1MLKEM1024. Only X25519MLKEM768, code point 4588, carries a Recommended marking of yes in the registry. RFC 9954 describes the general hybrid construction and is informational.
The operational point is where this is not available. These are TLS 1.3 constructions. RFC 9851 places TLS 1.2 in feature freeze and RFC 9852 records that the working group will not support it, so no post-quantum key exchange is coming to TLS 1.2. Any endpoint pinned to TLS 1.2 is excluded from this migration by construction, which turns your list of TLS 1.2 exceptions into a dated replacement plan rather than an indefinite tolerance.
Production discipline
- Cite the document, not the guide. Write the RFC and section next to each setting in your baseline, so a future reviewer can tell a deliberate choice from an inherited one.
- Prove the floor with a client that can make the offer. Record the negotiated version and suite from a real connection, and never accept a local client refusal as a server-side result.
- Rotate ticket encryption keys on a schedule you can evidence, or turn tickets off. An unrotated ticket key is a single secret that can undo the forward secrecy of everything that resumed under it.
- Keep 0-RTT off unless the application protocol specification permits it. The replay exposure is real, it is not something TLS resolves for you, and it lands on whichever request is least idempotent.
- Maintain the TLS 1.2 exception list as a dated plan. Feature freeze means those endpoints will never receive post-quantum key exchange.
Cross-course references
- Linux for Production Sysadmins - Part XXIX (Hardening) covers the fleet-wide baselines where a version floor is usually expressed once and then inherited by every service on the host.
- Kubernetes for Production Sysadmins - Part CXIV (TLS) covers ingress-level termination, where the version and suite policy is set by a controller configuration rather than a per-service file.
- Observability for Production Sysadmins - Part LXIV (TLSMonitoring) covers exporting the negotiated version and suite per endpoint, which converts a policy statement into a queryable fact.
Quiz
Knowledge check · 4 questions
Q1. Which document changed the BCP 195 position so that TLS 1.3 must be the default for new protocols using TLS?
Q2. An OpenSSL client returning no protocols available when asked to connect with TLS 1.1 proves that the server refuses TLS 1.1.
Q3. Explain why RFC 9325 requires session ticket encryption keys to be rotated and destroyed, even though every handshake used an ephemeral key exchange.
Q4. Review the proposed baseline and decide what to change before it is adopted.
A platform team proposes a fleet TLS baseline for 2027. It enables TLS 1.2 and TLS 1.3 everywhere, keeps a DHE suite for compatibility with two appliances, enables 0-RTT to improve API latency, leaves session tickets on with keys generated at process start and never rotated, and cites a single hardening blog post as its source.
Passing score: 75%. Answers are checked in this browser.