Table of Contents |
---|
Status
Current state: DISCUSS ACCEPTED
Voting thread: https://www.mail-archive.com/dev@kafka.apache.org/msg104580.html
Discussion thread: https://www.mail-archive.com/dev@kafka.apache.org/msg101011.html
JIRA:
Jira | ||||||
---|---|---|---|---|---|---|
|
PR: https://github.com/apache/kafka/pull/8338
Please keep the discussion on the mailing list rather than commenting on the wiki (wiki discussions get unwieldy fast).
...
However, Kafka configures the SSLEngine for Client and Server both modes. Hence according to existing code it would be useful to make SslEngineBuilder pluggable. That will provide us a way to configure SSLContext object in a flexible way and at the same time will allow creation of SSLEngine with Client/Server mode.
...
Default value will be as mentioned below.
Code Block |
---|
public static final String SSL_ENGINE_FACTORY_CLASS_CONFIG = "ssl.engine.factory.class"; public static final String DEFAULT_SSL_ENGINE_FACTORY_CLASS = "org.apache.kafka.common.security.ssl.DefaultSslEngineFactory.class.getCanonicalName(); public static final String SSL_ENGINE_FACTORY_CLASS_DOC = "The class of type org.apache.kafka.common.security.auth.SslEngineFactory to provide SSLEngine objects. Default value is " + DEFAULT_SSL_ENGINE_FACTORY_CLASS; |
Interface for SslEngineFactory
...
Code Block |
---|
package org.apache.kafka.common.security.sslauth; import org.apache.kafka.common.network.ModeConfigurable; import javax.net.ssl.SSLEngine; import java.io.Closeable; import java.security.KeyStore; import java.util.Map; import java.util.Set; public/** * Plugin interface SslEngineFactory { /** * Create a new SSLEngine object. * * @param mode Whether to use client or server mode. for allowing creation of SSLEngine object in a custom way. * Example: You want to use custom way to load your key material and trust material needed for SSLContext. * However, keep in mind that this is complementary to the existing Java Security Provider's mechanism and not a competing * solution. */ public interface SslEngineFactory extends Configurable, Closeable { /** * Create a new SSLEngine object to be used by the client. * * @param peerHost The peer host to use. This is used in client mode if endpoint validation is enabled. * @param peerPort The peer port to use. This is a hint and not used for validation. * @param endpointIdentification Endpoint identification algorithm for client mode. * @return The new SSLEngine. */ SSLEngine createSslEnginecreateClientSslEngine(Mode mode, String peerHost, int peerPort, String endpointIdentification); /** * ReturnsCreate truea ifnew SSLEngine needsobject to be rebuiltused by the server. * * @param nextConfigs peerHost The configuration we want peer host to use. This is used in client mode if endpoint validation is enabled. * @param peerPort The peer port to use. This is a hint and not used for validation. * @return The new SSLEngine. */ SSLEngine createServerSslEngine(String peerHost, int peerPort); /** * TrueReturns onlytrue if SSLEngine needs to be rebuilt. This method will be called when reconfiguration is triggered on * {@link org.apache.kafka.common.security.ssl.SslFactory}. Based on the <i>nextConfigs</i>, this method will * decide whether underlying SSLEngine object needs shouldto be rebuilt. If this method returns true, the * {@link org.apache.kafka.common.security.ssl.SslFactory} will re-create instance of this object and run other * checks before deciding to use the new object for the <i>new incoming connection</i> requests.The existing connections * are not impacted by this and will not see any changes done as boolean shouldBeRebuilt(Map<String, Object> nextConfigs); /**part of reconfiguration. * * <pre> * Example: If the implementation depends on the file based key material it can check if the file is updated * compared to the previous/last-loaded timestamp and return true. * </pre> * * @param nextConfigs The configuration we want to use. * Returns @return True only if the namesunderlying ofSSLEngine configsobject thatshould may be reconfiguredrebuilt. */ Set<String>boolean reconfigurableConfigs(shouldBeRebuilt(Map<String, Object> nextConfigs); /** * Returns existing configuration the names of configs that may be reconfigured. */ Map<String, Object> configsSet<String> reconfigurableConfigs(); /** * Returns keystore. * @return */ KeyStore keystore(); /** * Returns truststore. * @return */ KeyStore truststore(); } |
...
The configuration of Map will be passed to the implementation class via the constructorconfigure() method. See below example,
Code Block |
---|
public DefaultSslEngineFactory implements SslEngineFactory { ... ... /* Default empty argument constructor */ /* implement configure() method */ @Override public void configure(Map<String, ?> configs) { ... } ... ... } |
These configuration will be passed from SslFactory to the implementation of the SslEngineFactory interface via reflection like below
Code Block |
---|
public class SslFactory implement Reconfigurable { ... ... private SslEngineFactory instantiateSslEngineFactory(Map<String, Object> configs) { @SuppressWarnings("unchecked") Class<? extends SslEngineFactory> sslEngineFactoryClass.getDeclaredConstructor(Map.class).newInstance(configs); = (Class<? extends SslEngineFactory>) configs.get(SslConfigs.SSL_ENGINE_FACTORY_CLASS_CONFIG); SslEngineFactory sslEngineFactory = Utils.newInstance(sslEngineFactoryClass); sslEngineFactory.configure(configs); this.sslEngineFactoryConfig = configs; return sslEngineFactory; } ... } |
Support for reconfiguration of custom configs
...
This is because currently SslFactory does certain validations which we want to keep separate and mandate those checks across any possible implementation of pluggable ssl context class. Also, once we start writing the reconfigurable classes we realize that we need two classes - 1) SslContextFactory SslEngineFactory implementation and 2) Container of the factory implementation. We believe that keeping SslFactory as Reconfigurable object and help reconfigure the underlying SslContextFactory SslEngineFactory will simplify the implementations of SslContextFactorySslEngineFactory.
Also, we rejected to make SslContextFactory SslEngineFactory extend the Reconfigurable interface due to following reason,
...