Design the listener and security configuration for a broker that must serve internal services on a private network and external clients over the internet, with appropriately differentiated hardening.
answer
- two named listeners: INTERNAL/EXTERNAL
- INTERNAL=SSL mTLS, EXTERNAL=SASL_SSL
- advertise reachable addr per audience
- inter.broker on INTERNAL
- firewall + quotas + hostname verify externally
basics
~10 sDefine two named listeners: INTERNAL (private network) and EXTERNAL (internet). Map INTERNAL to SSL/mTLS and EXTERNAL to SASL_SSL via listener.security.protocol.map, advertise each with its reachable address, and point inter.broker.listener.name at INTERNAL.
solid answer
~40 sUse a multi-listener design. Bind two listeners and advertise each on the address its audience can reach: INTERNAL on the private hostname, EXTERNAL on the public DNS name. Map protocols per segment: INTERNAL:SSL (mTLS, since you control both ends and certs) and EXTERNAL:SASL_SSL (TLS plus SASL/SCRAM or OAUTHBEARER, since external identities are users/apps, not certs you issue). Set inter.broker.listener.name=INTERNAL so replication stays on the trusted, lower-latency path. Use listener.name.external.* prefixed configs to scope the external keystore and enabled SASL mechanisms, and require ssl.client.auth=required only on INTERNAL. Add per-listener network controls outside Kafka: firewall/security-group the EXTERNAL port to allowed CIDRs, terminate TLS with a current cipher suite, and apply quotas. This gives strong encryption everywhere, certificate-based identity internally, credential-based identity externally, and isolated replication.
go deeper
Recognize that internal and external clients can use different listeners with different security.
Write the listeners/advertised.listeners/protocol-map config for an internal+external split.
Justify mTLS-internal vs SASL_SSL-external, isolate inter-broker traffic, and add per-listener configs plus network/quotas.
Define the org-wide segmentation standard, certificate/credential lifecycle, authorizer policy, and migration/rollout strategy across the fleet.
**Goal.** One broker (or fleet) must serve two audiences with different trust levels: (a) internal microservices on a private VPC/subnet, and (b) external clients reaching in over the public internet. They need *different* hardening, so a single listener won't do. **Step 1 — Two named listeners.** Names describe roles; the four reserved names aren't enough because both segments need TLS but with different auth, so use custom names: ``` listeners=INTERNAL://0.0.0.0:9092,EXTERNAL://0.0.0.0:9094 ``` Bind to 0.0.0.0 (all local interfaces) — binding is fine on the wildcard. **Step 2 — Correct advertised addresses.** Each audience must receive an address *it* can route to (recall the bootstrap-then-metadata flow): ``` advertised.listeners=INTERNAL://kafka-1.internal:9092,EXTERNAL://kafka.example.com:9094 ``` Internal clients/brokers get the private hostname; external clients get the public DNS/LB name. Never advertise 0.0.0.0 or an internal name to the internet. **Step 3 — Per-segment protocol (the hardening matrix).** ``` listener.security.protocol.map=INTERNAL:SSL,EXTERNAL:SASL_SSL ``` - **INTERNAL → SSL with mTLS.** You own both ends and can issue certs from an internal CA, so mutual TLS gives strong, password-free identity. Set `listener.name.internal.ssl.client.auth=required`. - **EXTERNAL → SASL_SSL.** External principals are apps/users you authenticate with credentials or tokens, not certs you mint. TLS provides encryption; SASL provides identity. Choose **SCRAM-SHA-512** (salted, stored hashed) or **OAUTHBEARER** (OAuth2/OIDC tokens) over PLAIN. PLAIN is acceptable only because it's inside TLS, but SCRAM/OAUTHBEARER are preferred. **Step 4 — Isolate replication.** ``` inter.broker.listener.name=INTERNAL ``` Replication and broker coordination ride the trusted internal path (mTLS), off the internet-facing listener — better security and bandwidth isolation. (Set this OR security.inter.broker.protocol, never both.) **Step 5 — Per-listener configs.** Different keystores, mechanisms, and client-auth per listener via the `listener.name.<name>.*` prefix: ``` listener.name.internal.ssl.keystore.location=/certs/internal.keystore.jks listener.name.internal.ssl.client.auth=required listener.name.external.ssl.keystore.location=/certs/external.keystore.jks listener.name.external.sasl.enabled.mechanisms=SCRAM-SHA-512,OAUTHBEARER ``` **Step 6 — Defense in depth beyond Kafka.** - **Network controls:** firewall / security-group the EXTERNAL port (9094) to allowed source CIDRs; keep the INTERNAL port unreachable from the internet. - **TLS hygiene:** enforce TLS 1.2+/1.3, modern cipher suites (`ssl.enabled.protocols`, `ssl.cipher.suites`), and proper hostname verification (`ssl.endpoint.identification.algorithm=https`) so external clients verify the broker cert. - **AuthZ:** layer ACLs (or an authorizer) so authenticated external principals only touch their own topics/groups; mTLS-internal principals get broader rights. - **Quotas / throttling:** apply client/user quotas on the external listener to blunt abuse. **Why differentiate at all?** Internal traffic on a controlled network can use the cheaper, cert-based mTLS path and looser network rules; external traffic faces the hostile internet and needs credential/token auth plus tight network ACLs and quotas. Same broker, two hardening postures, expressed entirely through named listeners + the protocol map + per-listener configs. **Common pitfalls:** advertising the internal name externally (clients can't reach it); using one listener for both audiences (can't differentiate auth); pointing inter-broker at the external listener (exposes replication and adds internet latency); forgetting hostname verification on external clients (MITM risk); leaving SASL/PLAIN over a non-TLS listener.
- Why prefer mTLS internally but SASL_SSL externally?Internally you control both ends and can issue certs from your own CA, so mutual TLS gives strong, password-free identity cheaply. External principals are apps/users authenticated by credentials or OAuth tokens you don't mint as certs, so SASL (SCRAM/OAUTHBEARER) over TLS fits better.
- What non-Kafka controls complete the external hardening?Firewall/security-group the external port to allowed CIDRs, enforce TLS 1.2+/1.3 with modern ciphers and client-side hostname verification, layer ACLs/authorizer for per-principal topic access, and apply user/client quotas to limit abuse.
- Why route inter.broker.listener.name to INTERNAL?Replication is high-volume and trust-sensitive; keeping it on the internal mTLS listener isolates bandwidth, avoids internet latency, and keeps the replication channel off the public attack surface.
saying these in an interview costs you the question
- Serving both audiences from a single listener (can't differentiate auth/hardening)
- Advertising the internal hostname or 0.0.0.0 to external clients
- Pointing inter.broker.listener.name at the external/internet listener
- Using SASL/PLAIN over a non-TLS listener, or omitting hostname verification on external clients
- Relying on Kafka auth alone without firewalling the external port or applying quotas