From 02b31925778bd85d0002257ea893cc08e10042e1 Mon Sep 17 00:00:00 2001 From: Bjørn Christian Seime Date: Fri, 12 Mar 2021 15:10:57 +0100 Subject: Use SSLContext supplier for ZK server configuration Remove use of keystore/truststore from disk. Only configure client secure port if TLS is enabled. --- .../com/yahoo/vespa/zookeeper/Configurator.java | 131 +++++------------ .../vespa/zookeeper/VespaSslContextProvider.java | 26 +--- .../com/yahoo/vespa/zookeeper/ZooKeeperRunner.java | 2 +- .../yahoo/vespa/zookeeper/ConfiguratorTest.java | 162 +++++++-------------- 4 files changed, 90 insertions(+), 231 deletions(-) (limited to 'zookeeper-server') diff --git a/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/Configurator.java b/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/Configurator.java index ebf5032a4a7..aff4bb950f6 100644 --- a/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/Configurator.java +++ b/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/Configurator.java @@ -3,22 +3,14 @@ package com.yahoo.vespa.zookeeper; import com.yahoo.cloud.config.ZookeeperServerConfig; -import com.yahoo.security.KeyStoreBuilder; -import com.yahoo.security.KeyStoreType; -import com.yahoo.security.KeyStoreUtils; -import com.yahoo.security.KeyUtils; -import com.yahoo.security.X509CertificateUtils; -import com.yahoo.security.tls.TransportSecurityOptions; -import com.yahoo.text.Utf8; +import com.yahoo.security.tls.TlsContext; import com.yahoo.vespa.defaults.Defaults; import java.io.FileWriter; import java.io.IOException; -import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.security.PrivateKey; -import java.security.cert.X509Certificate; +import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.logging.Level; @@ -34,39 +26,35 @@ public class Configurator { private final ZookeeperServerConfig zookeeperServerConfig; private final Path configFilePath; - private final Path jksKeyStoreFilePath; public Configurator(ZookeeperServerConfig zookeeperServerConfig) { log.log(Level.FINE, zookeeperServerConfig.toString()); this.zookeeperServerConfig = zookeeperServerConfig; this.configFilePath = makeAbsolutePath(zookeeperServerConfig.zooKeeperConfigFile()); - this.jksKeyStoreFilePath = makeAbsolutePath(zookeeperServerConfig.jksKeyStoreFile()); System.setProperty(ZOOKEEPER_JMX_LOG4J_DISABLE, "true"); System.setProperty("zookeeper.snapshot.trust.empty", Boolean.valueOf(zookeeperServerConfig.trustEmptySnapshot()).toString()); System.setProperty(ZOOKEEPER_JUTE_MAX_BUFFER, Integer.valueOf(zookeeperServerConfig.juteMaxBuffer()).toString()); } - void writeConfigToDisk(Optional transportSecurityOptions) { + void writeConfigToDisk(Optional tlsContext) { configFilePath.toFile().getParentFile().mkdirs(); try { - writeZooKeeperConfigFile(zookeeperServerConfig, transportSecurityOptions); + writeZooKeeperConfigFile(zookeeperServerConfig, tlsContext); writeMyIdFile(zookeeperServerConfig); - transportSecurityOptions.ifPresent(this::writeJksKeystore); } catch (IOException e) { throw new RuntimeException("Error writing zookeeper config", e); } } private void writeZooKeeperConfigFile(ZookeeperServerConfig config, - Optional transportSecurityOptions) throws IOException { + Optional tlsContext) throws IOException { try (FileWriter writer = new FileWriter(configFilePath.toFile())) { - writer.write(transformConfigToString(config, transportSecurityOptions)); + writer.write(transformConfigToString(config, tlsContext)); } } - private String transformConfigToString(ZookeeperServerConfig config, - Optional transportSecurityOptions) { + private String transformConfigToString(ZookeeperServerConfig config, Optional tlsContext) { StringBuilder sb = new StringBuilder(); sb.append("tickTime=").append(config.tickTime()).append("\n"); sb.append("initLimit=").append(config.initLimit()).append("\n"); @@ -74,7 +62,6 @@ public class Configurator { sb.append("maxClientCnxns=").append(config.maxClientConnections()).append("\n"); sb.append("snapCount=").append(config.snapshotCount()).append("\n"); sb.append("dataDir=").append(getDefaults().underVespaHome(config.dataDir())).append("\n"); - sb.append("secureClientPort=").append(config.secureClientPort()).append("\n"); sb.append("autopurge.purgeInterval=").append(config.autopurge().purgeInterval()).append("\n"); sb.append("autopurge.snapRetainCount=").append(config.autopurge().snapRetainCount()).append("\n"); // See http://zookeeper.apache.org/doc/r3.5.5/zookeeperAdmin.html#sc_zkCommands @@ -90,8 +77,8 @@ public class Configurator { sb.append("metricsProvider.className=org.apache.zookeeper.metrics.impl.NullMetricsProvider\n"); ensureThisServerIsRepresented(config.myid(), config.server()); config.server().forEach(server -> addServerToCfg(sb, server, config.clientPort())); - sb.append(new TlsQuorumConfig(jksKeyStoreFilePath).createConfig(config, transportSecurityOptions)); - sb.append(new TlsClientServerConfig(jksKeyStoreFilePath).createConfig(config, transportSecurityOptions)); + sb.append(new TlsQuorumConfig().createConfig(config, tlsContext)); + sb.append(new TlsClientServerConfig().createConfig(config, tlsContext)); return sb.toString(); } @@ -101,25 +88,6 @@ public class Configurator { } } - private void writeJksKeystore(TransportSecurityOptions options) { - Path privateKeyFile = options.getPrivateKeyFile().orElseThrow(() -> new RuntimeException("Could not find private key file")); - Path certificatesFile = options.getCertificatesFile().orElseThrow(() -> new RuntimeException("Could not find certificates file")); - - PrivateKey privateKey; - List certificates; - try { - privateKey = KeyUtils.fromPemEncodedPrivateKey(Utf8.toString(Files.readAllBytes(privateKeyFile))); - certificates = X509CertificateUtils.certificateListFromPem(Utf8.toString(Files.readAllBytes(certificatesFile))); - } catch (IOException e) { - throw new RuntimeException(e); - } - KeyStoreBuilder keyStoreBuilder = KeyStoreBuilder - .withType(KeyStoreType.JKS) - .withKeyEntry("foo", privateKey, certificates); - - KeyStoreUtils.writeKeyStoreToFile(keyStoreBuilder.build(), jksKeyStoreFilePath); - } - private void ensureThisServerIsRepresented(int myid, List servers) { boolean found = false; for (ZookeeperServerConfig.Server server : servers) { @@ -172,59 +140,41 @@ public class Configurator { } private interface TlsConfig { + String createConfig(ZookeeperServerConfig config, Optional tlsContext); + default Optional getEnvironmentVariable(String variableName) { return Optional.ofNullable(System.getenv().get(variableName)) .filter(var -> !var.isEmpty()); } - default void validateOptions(Optional transportSecurityOptions, String tlsSetting) { - if (transportSecurityOptions.isEmpty() && !tlsSetting.equals("OFF")) + default void validateOptions(Optional tlsContext, String tlsSetting) { + if (tlsContext.isEmpty() && !tlsSetting.equals("OFF")) throw new RuntimeException("Could not retrieve transport security options"); } String configFieldPrefix(); - Path jksKeyStoreFilePath(); - - default String createCommonKeyStoreTrustStoreOptions(Optional transportSecurityOptions) { - StringBuilder sb = new StringBuilder(); - transportSecurityOptions.ifPresent(options -> { - sb.append(configFieldPrefix()).append(".keyStore.location=").append(jksKeyStoreFilePath()).append("\n"); - sb.append(configFieldPrefix()).append(".keyStore.type=JKS\n"); - - Path caCertificatesFile = options.getCaCertificatesFile().orElseThrow(() -> new RuntimeException("Could not find ca certificates file")); - sb.append(configFieldPrefix()).append(".trustStore.location=").append(caCertificatesFile).append("\n"); - sb.append(configFieldPrefix()).append(".trustStore.type=PEM\n"); + default void appendTlsConfig(StringBuilder builder, ZookeeperServerConfig config, Optional tlsContext) { + tlsContext.ifPresent(ctx -> { + builder.append(configFieldPrefix()).append(".context.supplier.class=").append(VespaSslContextProvider.class.getName()).append("\n"); + String enabledCiphers = Arrays.stream(ctx.parameters().getCipherSuites()).sorted().collect(Collectors.joining(",")); + builder.append(configFieldPrefix()).append(".ciphersuites=").append(enabledCiphers).append("\n"); + String enabledProtocols = Arrays.stream(ctx.parameters().getProtocols()).sorted().collect(Collectors.joining(",")); + builder.append(configFieldPrefix()).append(".enabledProtocols=").append(enabledProtocols).append("\n"); + builder.append(configFieldPrefix()).append(".clientAuth=NEED\n"); }); - return sb.toString(); } - - default String createCommonConfig() { - StringBuilder sb = new StringBuilder(); - sb.append(configFieldPrefix()).append(".hostnameVerification=false\n"); - sb.append(configFieldPrefix()).append(".clientAuth=NEED\n"); - sb.append(configFieldPrefix()).append(".ciphersuites=").append(VespaSslContextProvider.enabledTlsCiphersConfigValue()).append("\n"); - sb.append(configFieldPrefix()).append(".enabledProtocols=").append(VespaSslContextProvider.enabledTlsProtocolConfigValue()).append("\n"); - sb.append(configFieldPrefix()).append(".protocol=").append(VespaSslContextProvider.sslContextVersion()).append("\n"); - return sb.toString(); - } - } static class TlsClientServerConfig implements TlsConfig { - private final Path jksKeyStoreFilePath; - - TlsClientServerConfig(Path jksKeyStoreFilePath) { - this.jksKeyStoreFilePath = jksKeyStoreFilePath; - } - - String createConfig(ZookeeperServerConfig config, Optional transportSecurityOptions) { + @Override + public String createConfig(ZookeeperServerConfig config, Optional tlsContext) { String tlsSetting = getEnvironmentVariable("VESPA_TLS_FOR_ZOOKEEPER_CLIENT_SERVER_COMMUNICATION") .orElse(config.tlsForClientServerCommunication().name()); - validateOptions(transportSecurityOptions, tlsSetting); + validateOptions(tlsContext, tlsSetting); - StringBuilder sb = new StringBuilder(createCommonConfig()); + StringBuilder sb = new StringBuilder(); boolean portUnification; switch (tlsSetting) { case "OFF": @@ -239,7 +189,9 @@ public class Configurator { throw new IllegalArgumentException("Unknown value of config setting tlsForClientServerCommunication: " + tlsSetting); } sb.append("client.portUnification=").append(portUnification).append("\n"); - sb.append(createCommonKeyStoreTrustStoreOptions(transportSecurityOptions)); + // TODO This should override "clientPort" if TLS enabled without port unification); + tlsContext.ifPresent(ctx -> sb.append("secureClientPort=").append(config.secureClientPort()).append("\n")); + appendTlsConfig(sb, config, tlsContext); return sb.toString(); } @@ -248,28 +200,17 @@ public class Configurator { public String configFieldPrefix() { return "ssl"; } - - @Override - public Path jksKeyStoreFilePath() { - return jksKeyStoreFilePath; - } - } static class TlsQuorumConfig implements TlsConfig { - private final Path jksKeyStoreFilePath; - - TlsQuorumConfig(Path jksKeyStoreFilePath) { - this.jksKeyStoreFilePath = jksKeyStoreFilePath; - } - - String createConfig(ZookeeperServerConfig config, Optional transportSecurityOptions) { + @Override + public String createConfig(ZookeeperServerConfig config, Optional tlsContext) { String tlsSetting = getEnvironmentVariable("VESPA_TLS_FOR_ZOOKEEPER_QUORUM_COMMUNICATION") .orElse(config.tlsForQuorumCommunication().name()); - validateOptions(transportSecurityOptions, tlsSetting); + validateOptions(tlsContext, tlsSetting); - StringBuilder sb = new StringBuilder(createCommonConfig()); + StringBuilder sb = new StringBuilder(); boolean sslQuorum; boolean portUnification; switch (tlsSetting) { @@ -293,7 +234,7 @@ public class Configurator { } sb.append("sslQuorum=").append(sslQuorum).append("\n"); sb.append("portUnification=").append(portUnification).append("\n"); - sb.append(createCommonKeyStoreTrustStoreOptions(transportSecurityOptions)); + appendTlsConfig(sb, config, tlsContext); return sb.toString(); } @@ -302,12 +243,6 @@ public class Configurator { public String configFieldPrefix() { return "ssl.quorum"; } - - @Override - public Path jksKeyStoreFilePath() { - return jksKeyStoreFilePath; - } - } } diff --git a/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/VespaSslContextProvider.java b/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/VespaSslContextProvider.java index dc254ade071..b65cb9faf53 100644 --- a/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/VespaSslContextProvider.java +++ b/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/VespaSslContextProvider.java @@ -5,39 +5,21 @@ import com.yahoo.security.tls.TlsContext; import com.yahoo.security.tls.TransportSecurityUtils; import javax.net.ssl.SSLContext; -import java.util.Collection; -import java.util.List; import java.util.function.Supplier; -import java.util.stream.Collectors; /** - * Provider for Vespa {@link SSLContext} instance to Zookeeper + misc utility methods for providing Vespa TLS specific ZK configuration. + * Provider for Vespa {@link SSLContext} instance to Zookeeper. * * @author bjorncs */ public class VespaSslContextProvider implements Supplier { - private static final TlsContext tlsContext = TransportSecurityUtils.getSystemTlsContext().orElse(null); + private static final SSLContext sslContext = TransportSecurityUtils.getSystemTlsContext().map(TlsContext::context).orElse(null); @Override public SSLContext get() { - if (!tlsEnabled()) throw new IllegalStateException("Vespa TLS is not enabled"); - return tlsContext.context(); + if (sslContext == null) throw new IllegalStateException("Vespa TLS is not enabled"); + return sslContext; } - public static boolean tlsEnabled() { return tlsContext != null; } - - public static String enabledTlsProtocolConfigValue() { - // Fallback to all allowed protocols if we cannot determine which are actually supported by runtime - Collection enabledProtocols = tlsEnabled() ? List.of(tlsContext.parameters().getProtocols()) : TlsContext.ALLOWED_PROTOCOLS; - return enabledProtocols.stream().sorted().collect(Collectors.joining(",")); - } - - public static String enabledTlsCiphersConfigValue() { - // Fallback to all allowed ciphers if we cannot determine which are actually supported by runtime - Collection enabledCiphers = tlsEnabled() ? List.of(tlsContext.parameters().getCipherSuites()) : TlsContext.ALLOWED_CIPHER_SUITES; - return enabledCiphers.stream().sorted().collect(Collectors.joining(",")); - } - - public static String sslContextVersion() { return tlsEnabled() ? tlsContext.context().getProtocol() : TlsContext.SSL_CONTEXT_VERSION; } } diff --git a/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/ZooKeeperRunner.java b/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/ZooKeeperRunner.java index 812c974f9f8..adbc7a369b3 100644 --- a/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/ZooKeeperRunner.java +++ b/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/ZooKeeperRunner.java @@ -39,7 +39,7 @@ public class ZooKeeperRunner implements Runnable { public ZooKeeperRunner(ZookeeperServerConfig zookeeperServerConfig, VespaZooKeeperServer server) { this.zookeeperServerConfig = zookeeperServerConfig; this.server = server; - new Configurator(zookeeperServerConfig).writeConfigToDisk(TransportSecurityUtils.getOptions()); + new Configurator(zookeeperServerConfig).writeConfigToDisk(TransportSecurityUtils.getSystemTlsContext()); executorService = Executors.newSingleThreadExecutor(new DaemonThreadFactory("zookeeper server")); executorService.submit(this); } diff --git a/zookeeper-server/zookeeper-server-common/src/test/java/com/yahoo/vespa/zookeeper/ConfiguratorTest.java b/zookeeper-server/zookeeper-server-common/src/test/java/com/yahoo/vespa/zookeeper/ConfiguratorTest.java index a7994531b93..aee44c90cbf 100644 --- a/zookeeper-server/zookeeper-server-common/src/test/java/com/yahoo/vespa/zookeeper/ConfiguratorTest.java +++ b/zookeeper-server/zookeeper-server-common/src/test/java/com/yahoo/vespa/zookeeper/ConfiguratorTest.java @@ -4,8 +4,12 @@ package com.yahoo.vespa.zookeeper; import com.yahoo.cloud.config.ZookeeperServerConfig; import com.yahoo.security.KeyUtils; import com.yahoo.security.X509CertificateBuilder; -import com.yahoo.security.X509CertificateUtils; -import com.yahoo.security.tls.TransportSecurityOptions; +import com.yahoo.security.tls.AuthorizationMode; +import com.yahoo.security.tls.DefaultTlsContext; +import com.yahoo.security.tls.HostnameVerification; +import com.yahoo.security.tls.PeerAuthentication; +import com.yahoo.security.tls.TlsContext; +import com.yahoo.security.tls.policy.AuthorizedPeers; import com.yahoo.yolean.Exceptions; import org.junit.Before; import org.junit.Rule; @@ -15,13 +19,13 @@ import org.junit.rules.TemporaryFolder; import javax.security.auth.x500.X500Principal; import java.io.File; import java.io.IOException; -import java.io.UncheckedIOException; import java.math.BigInteger; import java.nio.file.Files; -import java.nio.file.Path; import java.security.KeyPair; import java.security.cert.X509Certificate; +import java.util.List; import java.util.Optional; +import java.util.Set; import static com.yahoo.cloud.config.ZookeeperServerConfig.TlsForClientServerCommunication; import static com.yahoo.cloud.config.ZookeeperServerConfig.TlsForQuorumCommunication; @@ -32,7 +36,6 @@ import static com.yahoo.vespa.zookeeper.Configurator.ZOOKEEPER_JUTE_MAX_BUFFER; import static java.time.Instant.EPOCH; import static java.time.temporal.ChronoUnit.DAYS; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; /** * Tests the zookeeper server. @@ -41,7 +44,6 @@ public class ConfiguratorTest { private File cfgFile; private File idFile; - private File jksKeyStoreFile; @Rule public TemporaryFolder folder = new TemporaryFolder(); @@ -50,12 +52,11 @@ public class ConfiguratorTest { public void setup() throws IOException { cfgFile = folder.newFile(); idFile = folder.newFile(); - jksKeyStoreFile = folder.newFile(); } @Test public void config_is_written_correctly_when_one_server() { - ZookeeperServerConfig.Builder builder = createConfigBuilderForSingleHost(cfgFile, idFile, jksKeyStoreFile); + ZookeeperServerConfig.Builder builder = createConfigBuilderForSingleHost(cfgFile, idFile); new Configurator(builder.build()).writeConfigToDisk(Optional.empty()); validateConfigFileSingleHost(cfgFile); validateIdFile(idFile, "0\n"); @@ -77,35 +78,32 @@ public class ConfiguratorTest { @Test public void config_is_written_correctly_with_tls_for_quorum_communication_port_unification() { - ZookeeperServerConfig.Builder builder = createConfigBuilderForSingleHost(cfgFile, idFile, jksKeyStoreFile); + ZookeeperServerConfig.Builder builder = createConfigBuilderForSingleHost(cfgFile, idFile); builder.tlsForQuorumCommunication(TlsForQuorumCommunication.PORT_UNIFICATION); builder.tlsForClientServerCommunication(TlsForClientServerCommunication.PORT_UNIFICATION); - Optional transportSecurityOptions = createTransportSecurityOptions(); - new Configurator(builder.build()).writeConfigToDisk(transportSecurityOptions); - validateConfigFilePortUnification(cfgFile, jksKeyStoreFile, transportSecurityOptions.get().getCaCertificatesFile().get().toFile()); - validateThatJksKeyStoreFileExists(jksKeyStoreFile); + TlsContext tlsContext = createTlsContext(); + new Configurator(builder.build()).writeConfigToDisk(Optional.of(tlsContext)); + validateConfigFilePortUnification(cfgFile); } @Test public void config_is_written_correctly_with_tls_for_quorum_communication_tls_with_port_unification() { - ZookeeperServerConfig.Builder builder = createConfigBuilderForSingleHost(cfgFile, idFile, jksKeyStoreFile); + ZookeeperServerConfig.Builder builder = createConfigBuilderForSingleHost(cfgFile, idFile); builder.tlsForQuorumCommunication(TlsForQuorumCommunication.TLS_WITH_PORT_UNIFICATION); builder.tlsForClientServerCommunication(TlsForClientServerCommunication.TLS_WITH_PORT_UNIFICATION); - Optional transportSecurityOptions = createTransportSecurityOptions(); - new Configurator(builder.build()).writeConfigToDisk(transportSecurityOptions); - validateConfigFileTlsWithPortUnification(cfgFile, jksKeyStoreFile, transportSecurityOptions.get().getCaCertificatesFile().get().toFile()); - validateThatJksKeyStoreFileExists(jksKeyStoreFile); + TlsContext tlsContext = createTlsContext(); + new Configurator(builder.build()).writeConfigToDisk(Optional.of(tlsContext)); + validateConfigFileTlsWithPortUnification(cfgFile); } @Test public void config_is_written_correctly_with_tls_for_quorum_communication_tls_only() { - ZookeeperServerConfig.Builder builder = createConfigBuilderForSingleHost(cfgFile, idFile, jksKeyStoreFile); + ZookeeperServerConfig.Builder builder = createConfigBuilderForSingleHost(cfgFile, idFile); builder.tlsForQuorumCommunication(TlsForQuorumCommunication.TLS_ONLY); builder.tlsForClientServerCommunication(TlsForClientServerCommunication.TLS_ONLY); - Optional transportSecurityOptions = createTransportSecurityOptions(); - new Configurator(builder.build()).writeConfigToDisk(transportSecurityOptions); - validateConfigFileTlsOnly(cfgFile, jksKeyStoreFile, transportSecurityOptions.get().getCaCertificatesFile().get().toFile()); - validateThatJksKeyStoreFileExists(jksKeyStoreFile); + TlsContext tlsContext = createTlsContext(); + new Configurator(builder.build()).writeConfigToDisk(Optional.of(tlsContext)); + validateConfigFileTlsOnly(cfgFile); } @Test(expected = RuntimeException.class) @@ -138,13 +136,12 @@ public class ConfiguratorTest { assertEquals("" + max_buffer, System.getProperty(ZOOKEEPER_JUTE_MAX_BUFFER)); } - private ZookeeperServerConfig.Builder createConfigBuilderForSingleHost(File cfgFile, File idFile, File jksKeyStoreFile) { + private ZookeeperServerConfig.Builder createConfigBuilderForSingleHost(File cfgFile, File idFile) { ZookeeperServerConfig.Builder builder = new ZookeeperServerConfig.Builder(); builder.zooKeeperConfigFile(cfgFile.getAbsolutePath()); builder.myidFile(idFile.getAbsolutePath()); builder.server(newServer(0, "foo", 123, 321, false)); builder.myid(0); - builder.jksKeyStoreFile(jksKeyStoreFile.getAbsolutePath()); return builder; } @@ -170,7 +167,6 @@ public class ConfiguratorTest { "maxClientCnxns=0\n" + "snapCount=50000\n" + "dataDir=" + getDefaults().underVespaHome("var/zookeeper") + "\n" + - "secureClientPort=2184\n" + "autopurge.purgeInterval=1\n" + "autopurge.snapRetainCount=15\n" + "4lw.commands.whitelist=conf,cons,crst,dirs,dump,envi,mntr,ruok,srst,srvr,stat,wchs\n" + @@ -183,58 +179,31 @@ public class ConfiguratorTest { "metricsProvider.className=org.apache.zookeeper.metrics.impl.NullMetricsProvider\n"; } - private String quorumKeyStoreAndTrustStoreConfig(File jksKeyStoreFilePath, File caCertificatesFilePath) { - StringBuilder sb = new StringBuilder(); - - sb.append("ssl.quorum.keyStore.location=").append(jksKeyStoreFilePath.getAbsolutePath()).append("\n"); - sb.append("ssl.quorum.keyStore.type=JKS\n"); - sb.append("ssl.quorum.trustStore.location=").append(caCertificatesFilePath.getAbsolutePath()).append("\n"); - sb.append("ssl.quorum.trustStore.type=PEM\n"); - return sb.toString(); - } - - private String clientServerKeyStoreAndTrustStoreConfig(File jksKeyStoreFilePath, File caCertificatesFilePath) { - StringBuilder sb = new StringBuilder(); - - sb.append("ssl.keyStore.location=").append(jksKeyStoreFilePath.getAbsolutePath()).append("\n"); - sb.append("ssl.keyStore.type=JKS\n"); - sb.append("ssl.trustStore.location=").append(caCertificatesFilePath.getAbsolutePath()).append("\n"); - sb.append("ssl.trustStore.type=PEM\n"); - return sb.toString(); - } - private void validateConfigFileSingleHost(File cfgFile) { String expected = commonConfig() + "server.0=foo:321:123;2181\n" + - commonTlsQuorumConfig() + "sslQuorum=false\n" + "portUnification=false\n" + - commonTlsClientServerConfig() + "client.portUnification=false\n"; validateConfigFile(cfgFile, expected); } - private String commonTlsQuorumConfig() { - return "ssl.quorum.hostnameVerification=false\n" + - "ssl.quorum.clientAuth=NEED\n" + - "ssl.quorum.ciphersuites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256," + - "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384," + - "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256," + - "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256\n" + - "ssl.quorum.enabledProtocols=TLSv1.2\n" + - "ssl.quorum.protocol=TLS\n"; + private String tlsQuorumConfig() { + return "ssl.quorum.context.supplier.class=com.yahoo.vespa.zookeeper.VespaSslContextProvider\n" + + "ssl.quorum.ciphersuites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256," + + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\n" + + "ssl.quorum.enabledProtocols=TLSv1.2\n" + + "ssl.quorum.clientAuth=NEED\n"; } - private String commonTlsClientServerConfig() { - return "ssl.hostnameVerification=false\n" + - "ssl.clientAuth=NEED\n" + - "ssl.ciphersuites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256," + - "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384," + - "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256," + - "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256\n" + - "ssl.enabledProtocols=TLSv1.2\n" + - "ssl.protocol=TLS\n"; + private String tlsClientServerConfig() { + return "secureClientPort=2184\n" + + "ssl.context.supplier.class=com.yahoo.vespa.zookeeper.VespaSslContextProvider\n" + + "ssl.ciphersuites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256," + + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\n" + + "ssl.enabledProtocols=TLSv1.2\n" + + "ssl.clientAuth=NEED\n"; } private void validateConfigFileMultipleHosts(File cfgFile) { @@ -243,53 +212,45 @@ public class ConfiguratorTest { "server.0=foo:321:123;2181\n" + "server.1=bar:432:234;2181\n" + "server.2=baz:543:345:observer;2181\n" + - commonTlsQuorumConfig() + "sslQuorum=false\n" + "portUnification=false\n" + - commonTlsClientServerConfig() + "client.portUnification=false\n"; validateConfigFile(cfgFile, expected); } - private void validateConfigFilePortUnification(File cfgFile, File jksKeyStoreFile, File caCertificatesFile) { + private void validateConfigFilePortUnification(File cfgFile) { String expected = commonConfig() + "server.0=foo:321:123;2181\n" + - commonTlsQuorumConfig() + "sslQuorum=false\n" + "portUnification=true\n" + - quorumKeyStoreAndTrustStoreConfig(jksKeyStoreFile, caCertificatesFile) + - commonTlsClientServerConfig() + + tlsQuorumConfig() + "client.portUnification=true\n" + - clientServerKeyStoreAndTrustStoreConfig(jksKeyStoreFile, caCertificatesFile); + tlsClientServerConfig(); validateConfigFile(cfgFile, expected); } - private void validateConfigFileTlsWithPortUnification(File cfgFile, File jksKeyStoreFile, File caCertificatesFile) { + private void validateConfigFileTlsWithPortUnification(File cfgFile) { String expected = commonConfig() + "server.0=foo:321:123;2181\n" + - commonTlsQuorumConfig() + "sslQuorum=true\n" + "portUnification=true\n" + - quorumKeyStoreAndTrustStoreConfig(jksKeyStoreFile, caCertificatesFile) + - commonTlsClientServerConfig() + + tlsQuorumConfig() + "client.portUnification=true\n" + - clientServerKeyStoreAndTrustStoreConfig(jksKeyStoreFile, caCertificatesFile); + tlsClientServerConfig(); validateConfigFile(cfgFile, expected); } - private void validateConfigFileTlsOnly(File cfgFile, File jksKeyStoreFile, File caCertificatesFile) { + private void validateConfigFileTlsOnly(File cfgFile) { String expected = commonConfig() + "server.0=foo:321:123;2181\n" + - commonTlsQuorumConfig() + "sslQuorum=true\n" + "portUnification=false\n" + - quorumKeyStoreAndTrustStoreConfig(jksKeyStoreFile, caCertificatesFile) + - commonTlsClientServerConfig() + + tlsQuorumConfig() + "client.portUnification=false\n" + - clientServerKeyStoreAndTrustStoreConfig(jksKeyStoreFile, caCertificatesFile); + tlsClientServerConfig(); validateConfigFile(cfgFile, expected); } @@ -298,33 +259,14 @@ public class ConfiguratorTest { assertEquals(expected, actual); } - private void validateThatJksKeyStoreFileExists(File cfgFile) { - assertTrue(cfgFile.exists() && cfgFile.canRead()); - } - - private Optional createTransportSecurityOptions() { - try { - KeyPair keyPair = KeyUtils.generateKeypair(EC); - Path privateKeyFile = folder.newFile().toPath(); - Files.writeString(privateKeyFile, KeyUtils.toPem(keyPair.getPrivate())); - - X509Certificate certificate = X509CertificateBuilder - .fromKeypair(keyPair, new X500Principal("CN=dummy"), EPOCH, EPOCH.plus(1, DAYS), SHA256_WITH_ECDSA, BigInteger.ONE) - .build(); - Path certificateChainFile = folder.newFile().toPath(); - String certificatePem = X509CertificateUtils.toPem(certificate); - Files.writeString(certificateChainFile, certificatePem); - - Path caCertificatesFile = folder.newFile().toPath(); - Files.writeString(caCertificatesFile, certificatePem); - - return Optional.of(new TransportSecurityOptions.Builder() - .withCertificates(certificateChainFile, privateKeyFile) - .withCaCertificates(caCertificatesFile) - .build()); - } catch (IOException e) { - throw new UncheckedIOException(e); - } + private TlsContext createTlsContext() { + KeyPair keyPair = KeyUtils.generateKeypair(EC); + X509Certificate certificate = X509CertificateBuilder + .fromKeypair(keyPair, new X500Principal("CN=dummy"), EPOCH, EPOCH.plus(1, DAYS), SHA256_WITH_ECDSA, BigInteger.ONE) + .build(); + return new DefaultTlsContext( + List.of(certificate), keyPair.getPrivate(), List.of(certificate), new AuthorizedPeers(Set.of()), + AuthorizationMode.ENFORCE, PeerAuthentication.NEED, HostnameVerification.DISABLED); } } -- cgit v1.2.3