diff options
author | Harald Musum <musum@verizonmedia.com> | 2019-11-28 13:33:42 +0100 |
---|---|---|
committer | Harald Musum <musum@verizonmedia.com> | 2019-11-28 13:33:42 +0100 |
commit | 8d1e6ca113bababb30400b8783aa0481635e6f83 (patch) | |
tree | 9d99fb7ad5b9c6e702c488f547d0970b95e10188 /zookeeper-server | |
parent | 39fdcd063826eb1b488b4b6a4c22d3d98839f914 (diff) |
Write zookeeper tls client server communication config
Diffstat (limited to 'zookeeper-server')
3 files changed, 101 insertions, 18 deletions
diff --git a/zookeeper-server/OWNERS b/zookeeper-server/OWNERS new file mode 100644 index 00000000000..338ed581212 --- /dev/null +++ b/zookeeper-server/OWNERS @@ -0,0 +1 @@ +hmusum diff --git a/zookeeper-server/zookeeper-server-3.5/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImpl.java b/zookeeper-server/zookeeper-server-3.5/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImpl.java index 17edfb22d56..dc501090018 100644 --- a/zookeeper-server/zookeeper-server-3.5/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImpl.java +++ b/zookeeper-server/zookeeper-server-3.5/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImpl.java @@ -109,7 +109,9 @@ public class VespaZooKeeperServerImpl extends AbstractComponent implements Runna sb.append("serverCnxnFactory=org.apache.zookeeper.server.NettyServerCnxnFactory").append("\n"); ensureThisServerIsRepresented(config.myid(), config.server()); config.server().forEach(server -> addServerToCfg(sb, server)); + // TODO: Refactor TLS config generation in the tow methods below, lots of common code sb.append(createTlsQuorumConfig(config, transportSecurityOptions)); + sb.append(createTlsClientServerConfig(config, transportSecurityOptions)); return sb.toString(); } @@ -169,6 +171,53 @@ public class VespaZooKeeperServerImpl extends AbstractComponent implements Runna return sb.toString(); } + private String createTlsClientServerConfig(ZookeeperServerConfig config, Optional<TransportSecurityOptions> transportSecurityOptions) { + String tlsSetting = getEnvironmentVariable("VESPA_TLS_FOR_ZOOKEEPER_CLIENT_SERVER_COMMUNICATION") + .orElse(config.tlsForClientServerCommunication().name()); + if (transportSecurityOptions.isEmpty() && !tlsSetting.equals("OFF")) + throw new RuntimeException("Could not retrieve transport security options"); + + StringBuilder sb = new StringBuilder(); + + // Create a SSLContext instance and determine the allowed ciphers/versions supported by the JVM's default provider. + SSLContext sslContext = new SslContextBuilder().build(); + Set<String> allowedCiphers = new TreeSet<>(TlsContext.getAllowedCipherSuites(sslContext)); + Set<String> allowedProtocols = new TreeSet<>(TlsContext.getAllowedProtocols(sslContext)); + + // Common config + sb.append("ssl.hostnameVerification=false\n"); + sb.append("ssl.clientAuth=NEED\n"); + sb.append("ssl.ciphersuites=").append(String.join(",", allowedCiphers)).append("\n"); + sb.append("ssl.enabledProtocols=").append(String.join(",", allowedProtocols)).append("\n"); + sb.append("ssl.protocol=").append(sslContext.getProtocol()).append("\n"); + + boolean portUnification; + switch (tlsSetting) { + case "OFF": + case "TLS_ONLY": + portUnification = false; + break; + case "PORT_UNIFICATION": + case "TLS_WITH_PORT_UNIFICATION": + portUnification = true; + break; + default: throw new IllegalArgumentException("Unknown value of config setting tlsForClientServerCommunication: " + tlsSetting); + } + sb.append("client.portUnification=").append(portUnification).append("\n"); + + transportSecurityOptions.ifPresent(options -> { + sb.append("ssl.keyStore.location=").append(jksKeyStoreFilePath).append("\n"); + sb.append("ssl.keyStore.type=JKS\n"); + + Path caCertificatesFile = options.getCaCertificatesFile().orElseThrow(() -> new RuntimeException("Could not find ca certificates file")); + sb.append("ssl.trustStore.location=").append(caCertificatesFile).append("\n"); + sb.append("ssl.trustStore.type=PEM\n"); + }); + + return sb.toString(); + } + + private void writeMyIdFile(ZookeeperServerConfig config) throws IOException { if (config.server().size() > 1) { try (FileWriter writer = new FileWriter(getDefaults().underVespaHome(config.myidFile()))) { diff --git a/zookeeper-server/zookeeper-server-3.5/src/test/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImplTest.java b/zookeeper-server/zookeeper-server-3.5/src/test/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImplTest.java index f7467a2dbfe..19166047fb1 100644 --- a/zookeeper-server/zookeeper-server-3.5/src/test/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImplTest.java +++ b/zookeeper-server/zookeeper-server-3.5/src/test/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImplTest.java @@ -22,9 +22,8 @@ import java.security.KeyPair; import java.security.cert.X509Certificate; import java.util.Optional; -import static com.yahoo.cloud.config.ZookeeperServerConfig.TlsForQuorumCommunication.Enum.PORT_UNIFICATION; -import static com.yahoo.cloud.config.ZookeeperServerConfig.TlsForQuorumCommunication.Enum.TLS_ONLY; -import static com.yahoo.cloud.config.ZookeeperServerConfig.TlsForQuorumCommunication.Enum.TLS_WITH_PORT_UNIFICATION; +import static com.yahoo.cloud.config.ZookeeperServerConfig.TlsForQuorumCommunication; +import static com.yahoo.cloud.config.ZookeeperServerConfig.TlsForClientServerCommunication; import static com.yahoo.security.KeyAlgorithm.EC; import static com.yahoo.security.SignatureAlgorithm.SHA256_WITH_ECDSA; import static java.time.Instant.EPOCH; @@ -78,7 +77,8 @@ public class VespaZooKeeperServerImplTest { @Test public void config_is_written_correctly_with_tls_for_quorum_communication_port_unification() throws IOException { ZookeeperServerConfig.Builder builder = createConfigBuilderForSingleHost(cfgFile, idFile, jksKeyStoreFile); - builder.tlsForQuorumCommunication(PORT_UNIFICATION); + builder.tlsForQuorumCommunication(TlsForQuorumCommunication.PORT_UNIFICATION); + builder.tlsForClientServerCommunication(TlsForClientServerCommunication.Enum.PORT_UNIFICATION); Optional<TransportSecurityOptions> transportSecurityOptions = createTransportSecurityOptions(); createServer(builder, transportSecurityOptions); validateConfigFilePortUnification(cfgFile, jksKeyStoreFile, transportSecurityOptions.get().getCaCertificatesFile().get().toFile()); @@ -88,7 +88,8 @@ public class VespaZooKeeperServerImplTest { @Test public void config_is_written_correctly_with_tls_for_quorum_communication_tls_with_port_unification() throws IOException { ZookeeperServerConfig.Builder builder = createConfigBuilderForSingleHost(cfgFile, idFile, jksKeyStoreFile); - builder.tlsForQuorumCommunication(TLS_WITH_PORT_UNIFICATION); + builder.tlsForQuorumCommunication(TlsForQuorumCommunication.TLS_WITH_PORT_UNIFICATION); + builder.tlsForClientServerCommunication(TlsForClientServerCommunication.Enum.TLS_WITH_PORT_UNIFICATION); Optional<TransportSecurityOptions> transportSecurityOptions = createTransportSecurityOptions(); createServer(builder, transportSecurityOptions); validateConfigFileTlsWithPortUnification(cfgFile, jksKeyStoreFile, transportSecurityOptions.get().getCaCertificatesFile().get().toFile()); @@ -98,7 +99,8 @@ public class VespaZooKeeperServerImplTest { @Test public void config_is_written_correctly_with_tls_for_quorum_communication_tls_only() throws IOException { ZookeeperServerConfig.Builder builder = createConfigBuilderForSingleHost(cfgFile, idFile, jksKeyStoreFile); - builder.tlsForQuorumCommunication(TLS_ONLY); + builder.tlsForQuorumCommunication(TlsForQuorumCommunication.TLS_ONLY); + builder.tlsForClientServerCommunication(TlsForClientServerCommunication.Enum.TLS_ONLY); Optional<TransportSecurityOptions> transportSecurityOptions = createTransportSecurityOptions(); createServer(builder, transportSecurityOptions); validateConfigFileTlsOnly(cfgFile, jksKeyStoreFile, transportSecurityOptions.get().getCaCertificatesFile().get().toFile()); @@ -181,7 +183,7 @@ public class VespaZooKeeperServerImplTest { "serverCnxnFactory=org.apache.zookeeper.server.NettyServerCnxnFactory\n"; } - private String keyStoreAndTrustStoreConfig(File jksKeyStoreFilePath, File caCertificatesFilePath) { + private String quorumKeyStoreAndTrustStoreConfig(File jksKeyStoreFilePath, File caCertificatesFilePath) { StringBuilder sb = new StringBuilder(); sb.append("ssl.quorum.keyStore.location=").append(jksKeyStoreFilePath.getAbsolutePath()).append("\n"); @@ -191,17 +193,29 @@ public class VespaZooKeeperServerImplTest { 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) throws IOException { String expected = commonConfig() + "server.0=foo:321:123\n" + - commonTlsConfig() + + commonTlsQuorumConfig() + "sslQuorum=false\n" + - "portUnification=false\n"; + "portUnification=false\n" + + commonTlsClientServerConfig() + + "client.portUnification=false\n"; validateConfigFile(cfgFile, expected); } - private String commonTlsConfig() { + 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_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" + @@ -209,15 +223,25 @@ public class VespaZooKeeperServerImplTest { "ssl.quorum.protocol=TLSv1.2\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_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.protocol=TLSv1.2\n"; + } + private void validateConfigFileMultipleHosts(File cfgFile) throws IOException { String expected = commonConfig() + "server.0=foo:321:123\n" + "server.1=bar:432:234\n" + "server.2=baz:543:345\n" + - commonTlsConfig() + + commonTlsQuorumConfig() + "sslQuorum=false\n" + - "portUnification=false\n"; + "portUnification=false\n" + + commonTlsClientServerConfig() + + "client.portUnification=false\n"; validateConfigFile(cfgFile, expected); } @@ -225,10 +249,13 @@ public class VespaZooKeeperServerImplTest { String expected = commonConfig() + "server.0=foo:321:123\n" + - commonTlsConfig() + + commonTlsQuorumConfig() + "sslQuorum=false\n" + "portUnification=true\n" + - keyStoreAndTrustStoreConfig(jksKeyStoreFile, caCertificatesFile); + quorumKeyStoreAndTrustStoreConfig(jksKeyStoreFile, caCertificatesFile) + + commonTlsClientServerConfig() + + "client.portUnification=true\n" + + clientServerKeyStoreAndTrustStoreConfig(jksKeyStoreFile, caCertificatesFile); validateConfigFile(cfgFile, expected); } @@ -236,10 +263,13 @@ public class VespaZooKeeperServerImplTest { String expected = commonConfig() + "server.0=foo:321:123\n" + - commonTlsConfig() + + commonTlsQuorumConfig() + "sslQuorum=true\n" + "portUnification=true\n" + - keyStoreAndTrustStoreConfig(jksKeyStoreFile, caCertificatesFile); + quorumKeyStoreAndTrustStoreConfig(jksKeyStoreFile, caCertificatesFile) + + commonTlsClientServerConfig() + + "client.portUnification=true\n" + + clientServerKeyStoreAndTrustStoreConfig(jksKeyStoreFile, caCertificatesFile); validateConfigFile(cfgFile, expected); } @@ -247,10 +277,13 @@ public class VespaZooKeeperServerImplTest { String expected = commonConfig() + "server.0=foo:321:123\n" + - commonTlsConfig() + + commonTlsQuorumConfig() + "sslQuorum=true\n" + "portUnification=false\n" + - keyStoreAndTrustStoreConfig(jksKeyStoreFile, caCertificatesFile); + quorumKeyStoreAndTrustStoreConfig(jksKeyStoreFile, caCertificatesFile) + + commonTlsClientServerConfig() + + "client.portUnification=false\n" + + clientServerKeyStoreAndTrustStoreConfig(jksKeyStoreFile, caCertificatesFile); validateConfigFile(cfgFile, expected); } |