Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Note also that ZooKeeper will associate multiple identities with any session that successfully authenticates multiple ways (e.g. both client certificate and SASL).  The X.509 identity is the full Distinguished Name from the client's certificate, and this can be changed (i.e. use just a part of the DN) only by implementing and using a custom ZooKeeper authentication provider that overrides the method protected String getClientId(X509Certificate clientCert). A client that accesses an ACL-protected Znode is authorized if it has at least 1 of the identities present in any authorizing ACL.

...

There is an additional CLI tool that supports bootstrapping information into ZooKeeper besides ConfigCommand: kafka-acls.{bat,sh} (kafka.admin.AclCommand).  Accessing a ZooKeeper instance via this CLI tool will also be required, and passing TLS configuration to it in a secured way will also be necessary.

...

Every config can be prefixed with "authorizer." for the case when kafka.security.authorizer.AclAuthorizer connects via TLS to a ZooKeeper quorum separate from the one that Kafka is using – this specific use case will be identified in the configuration by explicitly setting authorizer.zookeeper.ssl.client.secureenable=true.  In this case the configs prefixed with "authorizer." are not "overrides" like the other authorizer ZooKeeper connectivity configs such as connection/session timeouts and max inflight requests; ZooKeeper TLS connectivity values for the authorizer are not "merged" with Kafka's ZooKeeper TLS configs (if any) because semantically the two sets of configs are for different ZooKeeper quorums and there is no guarantee that they would be applicable across the two quorums; any configs that need to be identical across the two ZooKeeper quorums will have to be repeated with and without the prefix.  The same defaults described below will apply to the prefixed configs.

Config KeyDocumentation

zookeeper.ssl.client.secureenable

Optional Boolean, default=false

Set client to use TLS when connecting to ZooKeeper. When true, <code>zookeeper.clientCnxnSocket</code> must be set (typically to <code>org.apache.zookeeper.ClientCnxnSocketNetty</code>); other values to set may include <include list of all other properties below>
zookeeper.clientCnxnSocketTypically set to <code>org.apache.zookeeper.ClientCnxnSocketNetty</code> when using TLS connectivity to ZooKeeper
zookeeper.ssl.keyStorekeystore.locationKeystore location when using a client-side certificate with TLS connectivity to ZooKeeper. Note ZooKeeper's use of camel-case <code>keyStore</code>, which differs from Kafka.

zookeeper.ssl.keyStorekeystore.password

Optional Password

Keystore password when using a client-side certificate with TLS connectivity to ZooKeeper. Note ZooKeeper's use of camel-case <code>keyStore</code>, which differs from Kafka.
zookeeper.ssl.keyStorekeystore.typeKeystore type when using a client-side certificate with TLS connectivity to ZooKeeper. Note ZooKeeper's use of camel-case <code>keyStore</code>, which differs from Kafka. The default value of <code>null</code> means the type will be auto-detected based on the filename extension of the keystore.
zookeeper.ssl.trustStoretruststore.locationTruststore location when using TLS connectivity to ZooKeeper. Note ZooKeeper's use of camel-case <code>trustStore</code>, which differs from Kafka.
zookeeper.ssl.trustStoretruststore.password

Optional Password

Truststore password when using TLS connectivity to ZooKeeper. Note ZooKeeper's use of camel-case <code>trustStore</code>, which differs from Kafka.
zookeeper.ssl.trustStoretruststore.typeTruststore type when using TLS connectivity to ZooKeeper. Note ZooKeeper's use of camel-case <code>trustStore</code>, which differs from Kafka. The default value of <code>null</code> means the type will be auto-detected based on the filename extension of the truststore.

zookeeper.ssl.protocol

Optional String, default=TLSv1.2

Specifies the protocol to be used in ZooKeeper TLS negotiation
zookeeper.ssl.enabledProtocolsenabled.protocolsSpecifies the enabled protocol(s) in ZooKeeper TLS negotiation (csv). Note ZooKeeper's use of camel-case <code>enabledProtocols</code>, which differs from Kafka. The default value of <code>null</code> means the enabled protocol will be the value of the <code>zookeeper.ssl.protocol</code> configuration property.
zookeeper.ssl.ciphersuitescipher.suitesSpecifies the enabled cipher suites to be used in ZooKeeper TLS negotiation (csv). The default value of <code>null</code> means the list of enabled cipher suites is determined by the Java runtime being used.
zookeeper.ssl.context.supplier.classSpecifies the class to be used for creating SSL context in ZooKeeper TLS communication

zookeeper.ssl.hostnameVerification

Optional Boolean, default=true

Specifies whether to enable hostname verification in the ZooKeeper TLS negotiation process. Disabling it is only recommended for testing purposes.

zookeeper.ssl.crl.enable

Optional Boolean, default=false

Specifies whether to enable Certificate Revocation List in the ZooKeeper TLS protocols

zookeeper.ssl.ocsp.enable

Optional Boolean, default=false

Specifies whether to enable Online Certificate Status Protocol in the ZooKeeper TLS protocols

...

  • New Kafka configurations, both non-prefixed as well as prefixed with "authorizer."
  • A new --zk-tls-config-file parameter for:
    • ZooKeeper Security Migration Tool
    • Config Command CLI (for the special use case of bootstrapping TLS-enabled ZooKeeper)
    • ACL Command CLIs (for the special use case of bootstrapping TLS-enabled ZooKeeper)
  • A new -zk-tls-config-file parameter in the ZooKeeper Shell (again, note the single dash as opposed to the double-dash used above)

ZooKeeper supports Java system properties for configuration, and there are Kafka TLS configuration keys/values that are semantically equivalent to the ZooKeeper configurations in many case as well, so we will define an evaluation algorithm for configuration values as follows:

  1. System properties define an initial value to be used.  For example, if the Java process is started with "-Dzookeeper.ssl.trustStore.location=/the/path" then that will be the starting value for the zookeeper.ssl.truststore.location configuration.  Note that the system properties use the ZooKeeper camelcase convention; this cannot be changed.
  2. Explicit configuration values take precedence over any value defined via a system property.  So if in addition to the above system property the configuration explicitly includes "zookeeper.ssl.truststore.location=/another/path" then that will be the value for the zookeeper.ssl.truststore.location configuration
  3. If no value exists at this point – no system property and no explicit value – then any explicit, equivalent Kafka configuration will be used.  So, for example, if no such system property in (1) or config in (2) existed but the same config file contained "ssl.truststore.location=/the/kafka/path" then that would be the value used.

The list of configs for which the above algorithm will be used is as follows:

Zk System Property"zookeeper." configPotentially "Inherited" Kafka Config
zookeeper.ssl.keyStore.{location, password,type}zookeeper.ssl.keystore.{location,password,type}ssl.keystore.{location,passsord,type}
zookeeper.ssl.trustStore.{location, password,type}zookeeper.ssl.truststore.{location,password,type}ssl.truststore.{location,passsord,type}
zookeeper.ssl.ciphersuiteszookeeper.ssl.cipher.suitesssl.cipher.suites
zookeeper.ssl.protocolzookeeper.ssl.protocolssl.protocol
zookeeper.ssl.enabledProtocolszookeeper.ssl.enabled.protocolsssl.enabled.protocols

Note that inheritance occurs on brokers and on CLI tools.

Note that inheritance of Kafka configs does not occur for AclAuthorizer on the broker when it is explicitly pointed at a separate ZooKeeper quorum, but system properties will be applied in this case anyway (these cannot be disabled).

The proposed changes also include the addition of:

...

The connection between Kafka and Zookeeper is not on a critical path related to performance – brokers don't repeatedly communicate with Zookeeper as they process messages, for example – so introducing TLS encryption here does not require explicit performance testing.

Rejected Alternatives

Direct ZooKeeper Configs

ZooKeeper uses camelCase configs that are inconsistent with Kafka broker configs:

ZooKeeper ConfigKafka Broker Config
zookeeper.ssl.keyStore.locationssl.keystore.location
zookeeper.ssl.keyStore.passwordssl.keystore.password
zookeeper.ssl.keyStore.typessl.keystore.type
zookeeper.ssl.trustStore.locationssl.truststore.location
zookeeper.ssl.trustStore.passwordssl.truststore.password
zookeeper.ssl.trustStore.typessl.truststore.type
zookeeper.ssl.ciphersuitesssl.cipher.suites
zookeeper.ssl.enabledProtocolsssl.enabled.protocols

It would be confusing and prone to mistake to have such a mismatch – especially for people who tend to know very little about ZooKeeper compared to Kafka.

The ZooKeeper config "zookeeper.client.secure" is also confusing – it only refers to whether the client should be configured to communicate with a TLS-encrypted ZK socket and has nothing to do with any other security-related client configuration that might be implied by the term "secure" (e.g. SASL, ACLs).  We therefore use the broker-side config "zookeeper.ssl.client.enable" instead.N/A