How do you control which TLS protocol versions and cipher suites Kafka negotiates, and what are sane defaults?
answer
- ssl.enabled.protocols = TLSv1.2,TLSv1.3
- ban TLS 1.0/1.1, never SSLv3
- ssl.cipher.suites = explicit allow-list
- prefer ECDHE + AES-GCM/ChaCha20 (forward secrecy)
- JDK caps what's available; both sides must share one
basics
~10 sUse ssl.enabled.protocols to allow versions (e.g. TLSv1.2,TLSv1.3) and ssl.protocol for the default context; restrict algorithms with ssl.cipher.suites. Sane defaults: enable only TLSv1.2 and TLSv1.3, disable TLSv1.0/1.1, and rely on strong AEAD ciphers (GCM/ChaCha20).
solid answer
~50 sThree knobs govern the TLS algorithm envelope. ssl.enabled.protocols lists the allowed protocol versions the SSL context will offer/accept — modern default is TLSv1.2,TLSv1.3. ssl.protocol sets the SSLContext's primary protocol (commonly TLSv1.3, which still allows 1.2 if enabled). ssl.cipher.suites optionally pins the exact cipher suites; if unset, the JVM's defaults for the negotiated protocol apply. Best practice: enable only TLSv1.2 and TLSv1.3 (TLS 1.0/1.1 are deprecated and weak), and for 1.2 prefer forward-secret AEAD suites (ECDHE + AES-GCM or ChaCha20-Poly1305). TLS 1.3 simplifies this — its cipher suites are a small fixed set of AEAD ciphers with forward secrecy, and it can't be downgraded to legacy ciphers. These settings exist on both brokers and clients; broker and client must share at least one common protocol and cipher or the handshake fails. The JDK version also caps what's available.
go deeper
Knows ssl.enabled.protocols restricts TLS versions and that 1.2/1.3 are the good ones.
Configures protocol and cipher allow-lists and understands handshake mismatch failures.
Explains forward secrecy, AEAD, TLS 1.3 advantages, and JDK-capped availability.
Sets fleet TLS policy balancing security and client compatibility, and plans the 1.2→1.3 migration.
## What gets negotiated Every TLS connection negotiates two things during the handshake: a **protocol version** (TLS 1.2, 1.3, …) and a **cipher suite** (the bundle of algorithms for key exchange, bulk encryption, and integrity). Kafka exposes both as configuration so you can forbid weak choices. ## The properties - **`ssl.enabled.protocols`** — comma list of allowed versions, e.g. `TLSv1.2,TLSv1.3`. The endpoint will only offer/accept these. This is the primary lever for banning legacy TLS 1.0/1.1. - **`ssl.protocol`** — the name used to construct the `SSLContext` (default historically `TLSv1.2`, often set to `TLSv1.3`). The context can still negotiate any version in `ssl.enabled.protocols`; this mainly sets the 'highest/default' protocol family. - **`ssl.cipher.suites`** — an explicit allow-list of cipher suites. If empty, the JVM's default suites for the negotiated protocol are used. Use it to drop non-forward-secret or CBC suites on TLS 1.2. - **`ssl.provider` / `ssl.secure.random.implementation`** — advanced: choose the security provider / RNG (rarely changed). All of these apply on **both broker and client**. The handshake succeeds only if the two sides share at least one enabled protocol and one mutually acceptable cipher. ## Sane defaults - **Protocols:** enable only `TLSv1.2,TLSv1.3`. TLS 1.0 and 1.1 are deprecated (RFC 8996) and vulnerable to known attacks; do not enable them. SSLv3 is broken (POODLE) and must never be enabled. - **Ciphers on TLS 1.2:** prefer **ECDHE** key exchange (gives forward secrecy) with **AES-GCM** or **ChaCha20-Poly1305** AEAD bulk encryption. Avoid RC4, 3DES, static-RSA key exchange, and CBC-mode suites where possible. - **TLS 1.3:** its only cipher suites are AEAD with forward secrecy (`TLS_AES_128_GCM_SHA256`, `TLS_AES_256_GCM_SHA384`, `TLS_CHACHA20_POLY1305_SHA256`). There's nothing weak to remove, and 1.3 removes downgrade-prone legacy mechanisms — so enabling 1.3 is the simplest hardening win. ## Forward secrecy — why it matters A forward-secret suite (ECDHE/DHE) uses an ephemeral key exchange so that even if the broker's long-term private key is later stolen, past recorded sessions stay undecryptable. Static-RSA suites lack this. Prefer ECDHE everywhere. ## Operational notes - **JDK caps availability.** The set of usable protocols/ciphers is bounded by the JVM. A new TLS 1.3 cipher or curve may need a newer JDK; conversely some legacy ciphers are disabled at the JDK level via `java.security`. - **Pinning ciphers is brittle.** Over-tight `ssl.cipher.suites` lists break when a client/JDK lacks one of them, causing 'no cipher suites in common' handshake failures. Pin a small, well-supported set, not a single suite. - **Mismatch symptoms:** broker enabling only TLS 1.3 while an old client only speaks TLS 1.2 (and you disabled 1.2) → handshake failure. Keep 1.2 enabled until all clients support 1.3. - **Don't conflate with hostname verification or auth** — protocol/cipher selection is about the *strength* of encryption, independent of `ssl.endpoint.identification.algorithm` and mTLS.
- Why prefer ECDHE-based cipher suites over static-RSA ones?ECDHE provides forward secrecy via ephemeral keys: even if the broker's long-term private key is later compromised, previously recorded sessions can't be decrypted. Static-RSA key exchange lacks this.
- What happens if a broker enables only TLSv1.3 but a legacy client supports only TLSv1.2?The handshake fails — there's no common protocol. You must keep TLSv1.2 in ssl.enabled.protocols until all clients support 1.3, or the connection is rejected.
saying these in an interview costs you the question
- Enabling TLSv1.0/1.1 for 'compatibility' — they're deprecated and weak.
- Pinning a single cipher suite, which breaks clients lacking it ('no cipher suites in common').
- Believing you can enable a TLS 1.3 cipher the JDK doesn't support — the JVM caps the available set.
- Confusing cipher/protocol hardening with authentication — it's about encryption strength only.