skip to content

Show how you configure MirrorMaker 2 so it uses SASL_SSL (SCRAM) to the source cluster and mTLS to the target cluster. What property prefixes make this possible?

level: middleimportance: should knowfreq 35%

answer

  1. clusters=src,dst then <alias>. prefixes
  2. Source: src.security.protocol=SASL_SSL + sasl.jaas.config SCRAM
  3. Target: dst.security.protocol=SSL + keystore = mTLS
  4. truststore=verify broker; keystore=my client cert
  5. producer./consumer./admin. sub-prefixes for overrides

basics

~10 s

Use the cluster-alias prefixes in MM2's config: set source.security.protocol=SASL_SSL with source.sasl.* for SCRAM, and target.security.protocol=SSL with target.ssl.keystore.* for the client cert. Each cluster's connection is configured independently under its alias.

solid answer

~30 s

MM2's config keys are namespaced by cluster **alias**. You list clusters with `clusters=src,dst` and give each its bootstrap (`src.bootstrap.servers`, `dst.bootstrap.servers`). Security is then set per alias: for the source, `src.security.protocol=SASL_SSL`, `src.sasl.mechanism=SCRAM-SHA-512`, `src.sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required username=... password=...;`, plus a truststore so it can verify the broker. For the target, `dst.security.protocol=SSL`, `dst.ssl.truststore.location/password`, and `dst.ssl.keystore.location/password/key.password` for the client cert that drives mTLS. Because the two sides are wholly independent prefixes, mixing mechanisms is natural. You can further qualify with `src.producer.*`/`src.consumer.*`/`src.admin.*` if a particular client type needs overrides. The internal Connect topics inherit the relevant cluster's settings.

go deeper

for a junior

Know MM2 config keys are prefixed by cluster alias and security is set per alias.

for a middle

Write the source SASL_SSL/SCRAM and target SSL/mTLS blocks and explain truststore vs keystore.

for a senior

Layer producer/consumer/admin overrides, externalize secrets, and keep hostname verification on.

for a principal

Standardize the prefix + secrets-provider conventions across all replication flows and map them to Strimzi/Connect deployment forms.

## MM2's configuration model MM2 can run in three ways — the dedicated `connect-mirror-maker.sh` with a properties file, as connectors on an existing Connect cluster, or via Strimzi `KafkaMirrorMaker2` CRDs. The properties-file form is the clearest for understanding the prefixes. Every cluster gets an **alias**. You declare them and then prefix all per-cluster settings with `<alias>.`: ```properties clusters = src, dst src.bootstrap.servers = b1.src:9094,b2.src:9094 dst.bootstrap.servers = b1.dst:9093,b2.dst:9093 # which direction(s) to replicate src->dst.enabled = true src->dst.topics = orders.* ``` ## Securing the source with SASL_SSL + SCRAM ```properties src.security.protocol = SASL_SSL src.sasl.mechanism = SCRAM-SHA-512 src.sasl.jaas.config = org.apache.kafka.common.security.scram.ScramLoginModule required \ username="mm2" password="${SRC_PW}"; src.ssl.truststore.location = /etc/mm2/src.truststore.jks src.ssl.truststore.password = ${SRC_TS_PW} ``` `SASL_SSL` = SASL authentication over a TLS-encrypted channel. The truststore lets MM2 verify the **source brokers'** certs (server-side TLS); SCRAM provides the **client identity** via salted username/password. ## Securing the target with mTLS (SSL) ```properties dst.security.protocol = SSL dst.ssl.truststore.location = /etc/mm2/dst.truststore.jks dst.ssl.truststore.password = ${DST_TS_PW} dst.ssl.keystore.location = /etc/mm2/dst.keystore.jks dst.ssl.keystore.password = ${DST_KS_PW} dst.ssl.key.password = ${DST_KEY_PW} ``` Here the **keystore** holds MM2's own certificate + private key, which the target brokers verify — that's what makes it *mutual* TLS. The target broker derives MM2's principal from that cert's DN (subject to `ssl.principal.mapping.rules`). ## Prefix layering Within a cluster you can target a specific client role: - `<alias>.producer.*` — the producer MM2 uses when that cluster is a *target*. - `<alias>.consumer.*` — the consumer when it's a *source*. - `<alias>.admin.*` — the admin client (topic creation, configs). Most security settings can stay at `<alias>.*` and all three inherit them; use the finer prefixes only for overrides. ## Why independent prefixes matter Real cross-cluster topologies are heterogeneous: an on-prem source using Kerberos/SCRAM and a cloud target using mTLS, or vice versa. Because `src.*` and `dst.*` are completely separate namespaces, MM2 happily speaks a different protocol to each side. This is the mechanism that makes 'SASL on one side, mTLS on the other' trivial. ## Edge cases - **Secrets in config:** inline passwords in `jaas.config` end up in the properties file; prefer externalized config providers (`config.providers` with `FileConfigProvider`/Vault) so secrets aren't plaintext on disk. - **Hostname verification:** keep `<alias>.ssl.endpoint.identification.algorithm=https`; advertised broker hostnames must be in the cert SAN. - **Connect internal topics:** they live on the backing cluster and inherit its `<alias>.*` security, but the worker config (`config.storage.*`, etc.) may need its own security block if you run MM2 on a standalone Connect cluster. - **Strimzi form:** the same concepts map to `spec.clusters[].authentication` and `.tls.trustedCertificates`/`KafkaUser` secrets.

  • Which store provides MM2's own identity for mTLS — truststore or keystore?
    The keystore. It holds MM2's certificate and private key that the broker verifies. The truststore only holds the CA certs MM2 uses to verify the broker's certificate.
  • How do you avoid plaintext SCRAM passwords in the MM2 properties file?
    Use Connect's externalized config providers (config.providers with FileConfigProvider, DirectoryConfigProvider, or a Vault/secrets provider) and reference ${provider:path:key} in sasl.jaas.config instead of literal passwords.

saying these in an interview costs you the question

  • Putting one global security.protocol and assuming both clusters share it
  • Swapping truststore and keystore roles
  • Disabling ssl.endpoint.identification.algorithm to make certs 'work'
  • Leaving SCRAM passwords inline in the properties file with no config provider

context