From 8dfd194e88197552c6dcb9c0806c024868c61dba Mon Sep 17 00:00:00 2001 From: Bjørn Christian Seime Date: Thu, 11 Mar 2021 13:51:42 +0100 Subject: Add shared ZK client config generator for zkfacade and vespa-zkcli --- zookeeper-client-common/OWNERS | 1 + zookeeper-client-common/README.md | 3 ++ zookeeper-client-common/pom.xml | 47 +++++++++++++++++ .../zookeeper/client/VespaSslContextProvider.java | 25 +++++++++ .../zookeeper/client/ZkClientConfigBuilder.java | 60 ++++++++++++++++++++++ 5 files changed, 136 insertions(+) create mode 100644 zookeeper-client-common/OWNERS create mode 100644 zookeeper-client-common/README.md create mode 100644 zookeeper-client-common/pom.xml create mode 100644 zookeeper-client-common/src/main/java/com/yahoo/vespa/zookeeper/client/VespaSslContextProvider.java create mode 100644 zookeeper-client-common/src/main/java/com/yahoo/vespa/zookeeper/client/ZkClientConfigBuilder.java (limited to 'zookeeper-client-common') diff --git a/zookeeper-client-common/OWNERS b/zookeeper-client-common/OWNERS new file mode 100644 index 00000000000..569bf1cc3a1 --- /dev/null +++ b/zookeeper-client-common/OWNERS @@ -0,0 +1 @@ +bjorncs diff --git a/zookeeper-client-common/README.md b/zookeeper-client-common/README.md new file mode 100644 index 00000000000..51c757a8af2 --- /dev/null +++ b/zookeeper-client-common/README.md @@ -0,0 +1,3 @@ +# zookeeper-client-common + +Shared client configuration logic for ZooKeeper clients diff --git a/zookeeper-client-common/pom.xml b/zookeeper-client-common/pom.xml new file mode 100644 index 00000000000..fd799e13fca --- /dev/null +++ b/zookeeper-client-common/pom.xml @@ -0,0 +1,47 @@ + + + + 4.0.0 + + com.yahoo.vespa + parent + 7-SNAPSHOT + ../parent/pom.xml + + zookeeper-client-common + jar + 7-SNAPSHOT + + + + + com.yahoo.vespa + security-utils + ${project.version} + provided + + + org.apache.zookeeper + zookeeper + ${zookeeper.client.version} + provided + + + + + + junit + junit + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + diff --git a/zookeeper-client-common/src/main/java/com/yahoo/vespa/zookeeper/client/VespaSslContextProvider.java b/zookeeper-client-common/src/main/java/com/yahoo/vespa/zookeeper/client/VespaSslContextProvider.java new file mode 100644 index 00000000000..209e08db6cc --- /dev/null +++ b/zookeeper-client-common/src/main/java/com/yahoo/vespa/zookeeper/client/VespaSslContextProvider.java @@ -0,0 +1,25 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.zookeeper.client; + +import com.yahoo.security.tls.TlsContext; +import com.yahoo.security.tls.TransportSecurityUtils; + +import javax.net.ssl.SSLContext; +import java.util.function.Supplier; + +/** + * Provider for Vespa {@link SSLContext} instance to Zookeeper + misc utility methods for providing Vespa TLS specific ZK configuration. + * + * @author bjorncs + */ +public class VespaSslContextProvider implements Supplier { + + private static final SSLContext sslContext = TransportSecurityUtils.getSystemTlsContext().map(TlsContext::context).orElse(null); + + @Override + public SSLContext get() { + if (sslContext == null) throw new IllegalStateException("Vespa TLS is not enabled"); + return sslContext; + } + +} diff --git a/zookeeper-client-common/src/main/java/com/yahoo/vespa/zookeeper/client/ZkClientConfigBuilder.java b/zookeeper-client-common/src/main/java/com/yahoo/vespa/zookeeper/client/ZkClientConfigBuilder.java new file mode 100644 index 00000000000..62191880b8f --- /dev/null +++ b/zookeeper-client-common/src/main/java/com/yahoo/vespa/zookeeper/client/ZkClientConfigBuilder.java @@ -0,0 +1,60 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.zookeeper.client; + +import com.yahoo.security.tls.MixedMode; +import com.yahoo.security.tls.TlsContext; +import com.yahoo.security.tls.TransportSecurityUtils; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * Builder for ZK client configuration + * + * @author bjorncs + */ +public class ZkClientConfigBuilder { + + public static final String CLIENT_SECURE_PROPERTY = "zookeeper.client.secure"; + public static final String SSL_CONTEXT_SUPPLIER_CLASS_PROPERTY = "zookeeper.ssl.context.supplier.class"; + public static final String SSL_ENABLED_PROTOCOLS_PROPERTY = "zookeeper.ssl.enabledProtocols"; + public static final String SSL_ENABLED_CIPHERSUITES_PROPERTY = "zookeeper.ssl.ciphersuites"; + public static final String SSL_CLIENTAUTH_PROPERTY = "zookeeper.ssl.clientAuth"; + + private static final TlsContext tlsContext = getTlsContext().orElse(null); + + public ZkClientConfigBuilder() {} + + public String toConfigString() { + StringBuilder builder = new StringBuilder(); + Map properties = toConfigProperties(); + properties.forEach((key, value) -> builder.append(key).append('=').append(value).append('\n')); + return builder.toString(); + } + + public Map toConfigProperties() { + Map builder = new HashMap<>(); + builder.put(CLIENT_SECURE_PROPERTY, Boolean.toString(tlsContext != null)); + if (tlsContext != null) { + builder.put(SSL_CONTEXT_SUPPLIER_CLASS_PROPERTY, VespaSslContextProvider.class.getName()); + String protocolsConfigValue = Arrays.stream(tlsContext.parameters().getProtocols()).sorted().collect(Collectors.joining(",")); + builder.put(SSL_ENABLED_PROTOCOLS_PROPERTY, protocolsConfigValue); + String ciphersConfigValue = Arrays.stream(tlsContext.parameters().getCipherSuites()).sorted().collect(Collectors.joining(",")); + builder.put(SSL_ENABLED_CIPHERSUITES_PROPERTY, ciphersConfigValue); + builder.put(SSL_CLIENTAUTH_PROPERTY, "NEED"); + } + return Map.copyOf(builder); + } + + private static Optional getTlsContext() { + // TODO(bjorncs) Remove handling of temporary feature flag + boolean temporaryFeatureFlag = Optional.ofNullable(System.getenv("VESPA_USE_TLS_FOR_ZOOKEEPER_CLIENT")).map(Boolean::parseBoolean).orElse(false); + if (!temporaryFeatureFlag) return Optional.empty(); + + if (TransportSecurityUtils.getInsecureMixedMode() == MixedMode.PLAINTEXT_CLIENT_MIXED_SERVER) return Optional.empty(); + return TransportSecurityUtils.getSystemTlsContext(); + } +} -- cgit v1.2.3