diff options
author | Harald Musum <musum@verizonmedia.com> | 2019-11-14 14:25:42 +0100 |
---|---|---|
committer | Harald Musum <musum@verizonmedia.com> | 2019-11-14 14:25:42 +0100 |
commit | e7df005495cdc3cf17623339b2c33ca832b6aeb7 (patch) | |
tree | ddbb02e59b5cca9242639537ee79b91345150481 /zookeeper-server | |
parent | bf057fb22f9c917d616031a0cd32597b315bb803 (diff) |
Write TLS config to zookeeper config file based on Vespa config
Diffstat (limited to 'zookeeper-server')
2 files changed, 143 insertions, 33 deletions
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 9cb87efa3c0..459df59fa1b 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 @@ -5,6 +5,8 @@ import com.google.inject.Inject; import com.yahoo.cloud.config.ZookeeperServerConfig; import com.yahoo.component.AbstractComponent; import com.yahoo.log.LogLevel; +import com.yahoo.security.tls.TlsContext; + import static com.yahoo.vespa.defaults.Defaults.getDefaults; import java.io.File; @@ -12,6 +14,7 @@ import java.io.FileWriter; import java.io.IOException; import java.util.List; import java.util.Set; +import java.util.TreeSet; import java.util.stream.Collectors; /** @@ -76,6 +79,41 @@ 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)); + sb.append(createTlsQuorumConfig(config)); + return sb.toString(); + } + + private String createTlsQuorumConfig(ZookeeperServerConfig config) { + StringBuilder sb = new StringBuilder(); + + // Common config + sb.append("ssl.quorum.hostnameVerification=false\n"); + sb.append("ssl.quorum.clientAuth=NEED\n"); + sb.append("ssl.quorum.ciphersuites=").append(String.join(",", new TreeSet<>(TlsContext.ALLOWED_CIPHER_SUITES))).append("\n"); + sb.append("ssl.quorum.enabledProtocols=").append(String.join(",", new TreeSet<>(TlsContext.ALLOWED_PROTOCOLS))).append("\n"); + sb.append("ssl.quorum.protocol=TLSv1.2\n"); + + String tlsSetting = config.tlsForQuorumCommunication().name(); + switch (tlsSetting) { + case "OFF": + sb.append("sslQuorum=false\n"); + sb.append("portUnification=false\n"); + break; + case "PORT_UNIFICATION": + sb.append("sslQuorum=false\n"); + sb.append("portUnification=true\n"); + break; + case "TLS_WITH_PORT_UNIFICATION": + sb.append("sslQuorum=true\n"); + sb.append("portUnification=true\n"); + break; + case "TLS_ONLY": + sb.append("sslQuorum=true\n"); + sb.append("portUnification=false\n"); + break; + default: throw new IllegalArgumentException("Unknown value of config setting tlsForQuorumCommunication: " + tlsSetting); + } + return sb.toString(); } 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 19690bff963..eea5189fc5a 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 @@ -26,11 +26,7 @@ public class VespaZooKeeperServerImplTest { public void config_is_written_correctly_when_one_server() throws IOException { File cfgFile = folder.newFile(); File idFile = folder.newFile(); - ZookeeperServerConfig.Builder builder = new ZookeeperServerConfig.Builder(); - builder.zooKeeperConfigFile(cfgFile.getAbsolutePath()); - builder.myidFile(idFile.getAbsolutePath()); - builder.server(newServer(0, "foo", 123, 321)); - builder.myid(0); + ZookeeperServerConfig.Builder builder = createConfigBuilderForSingleHost(cfgFile, idFile); createServer(builder); validateConfigFileSingleHost(cfgFile); validateIdFile(idFile, ""); @@ -52,6 +48,45 @@ public class VespaZooKeeperServerImplTest { validateIdFile(idFile, "1\n"); } + @Test + public void config_is_written_correctly_with_tls_for_quorum_communication_port_unification() throws IOException { + File cfgFile = folder.newFile(); + File idFile = folder.newFile(); + ZookeeperServerConfig.Builder builder = createConfigBuilderForSingleHost(cfgFile, idFile); + builder.tlsForQuorumCommunication(ZookeeperServerConfig.TlsForQuorumCommunication.Enum.PORT_UNIFICATION); + createServer(builder); + validateConfigFilePortUnification(cfgFile); + } + + @Test + public void config_is_written_correctly_with_tls_for_quorum_communication_tls_with_port_unification() throws IOException { + File cfgFile = folder.newFile(); + File idFile = folder.newFile(); + ZookeeperServerConfig.Builder builder = createConfigBuilderForSingleHost(cfgFile, idFile); + builder.tlsForQuorumCommunication(ZookeeperServerConfig.TlsForQuorumCommunication.Enum.TLS_WITH_PORT_UNIFICATION); + createServer(builder); + validateConfigFileTlsWithPortUnification(cfgFile); + } + + @Test + public void config_is_written_correctly_with_tls_for_quorum_communication_tls_only() throws IOException { + File cfgFile = folder.newFile(); + File idFile = folder.newFile(); + ZookeeperServerConfig.Builder builder = createConfigBuilderForSingleHost(cfgFile, idFile); + builder.tlsForQuorumCommunication(ZookeeperServerConfig.TlsForQuorumCommunication.Enum.TLS_ONLY); + createServer(builder); + validateConfigFileTlsOnly(cfgFile); + } + + 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)); + builder.myid(0); + return builder; + } + private void createServer(ZookeeperServerConfig.Builder builder) { new VespaZooKeeperServerImpl(new ZookeeperServerConfig(builder), false); } @@ -99,41 +134,78 @@ public class VespaZooKeeperServerImplTest { assertThat(actual, is(expected)); } + private String commonConfig() { + return "tickTime=2000\n" + + "initLimit=20\n" + + "syncLimit=15\n" + + "maxClientCnxns=0\n" + + "snapCount=50000\n" + + "dataDir=" + getDefaults().underVespaHome("var/zookeeper") + "\n" + + "clientPort=2181\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" + + "admin.enableServer=false\n" + + "serverCnxnFactory=org.apache.zookeeper.server.NettyServerCnxnFactory\n"; + } + private void validateConfigFileSingleHost(File cfgFile) throws IOException { String expected = - "tickTime=2000\n" + - "initLimit=20\n" + - "syncLimit=15\n" + - "maxClientCnxns=0\n" + - "snapCount=50000\n" + - "dataDir=" + getDefaults().underVespaHome("var/zookeeper") + "\n" + - "clientPort=2181\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" + - "admin.enableServer=false\n" + - "serverCnxnFactory=org.apache.zookeeper.server.NettyServerCnxnFactory\n" + - "server.0=foo:321:123\n"; + commonConfig() + + "server.0=foo:321:123\n" + + commonTlsConfig() + + "sslQuorum=false\n" + + "portUnification=false\n"; validateConfigFile(cfgFile, expected); } + private String commonTlsConfig() { + 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=TLSv1.2\n"; + } + private void validateConfigFileMultipleHosts(File cfgFile) throws IOException { String expected = - "tickTime=2000\n" + - "initLimit=20\n" + - "syncLimit=15\n" + - "maxClientCnxns=0\n" + - "snapCount=50000\n" + - "dataDir=" + getDefaults().underVespaHome("var/zookeeper") + "\n" + - "clientPort=2181\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" + - "admin.enableServer=false\n" + - "serverCnxnFactory=org.apache.zookeeper.server.NettyServerCnxnFactory\n" + - "server.0=foo:321:123\n" + - "server.1=bar:432:234\n" + - "server.2=baz:543:345\n"; + commonConfig() + + "server.0=foo:321:123\n" + + "server.1=bar:432:234\n" + + "server.2=baz:543:345\n" + + commonTlsConfig() + + "sslQuorum=false\n" + + "portUnification=false\n"; + validateConfigFile(cfgFile, expected); + } + + private void validateConfigFilePortUnification(File cfgFile) throws IOException { + String expected = + commonConfig() + + "server.0=foo:321:123\n" + + commonTlsConfig() + + "sslQuorum=false\n" + + "portUnification=true\n"; + validateConfigFile(cfgFile, expected); + } + + private void validateConfigFileTlsWithPortUnification(File cfgFile) throws IOException { + String expected = + commonConfig() + + "server.0=foo:321:123\n" + + commonTlsConfig() + + "sslQuorum=true\n" + + "portUnification=true\n"; + validateConfigFile(cfgFile, expected); + } + + private void validateConfigFileTlsOnly(File cfgFile) throws IOException { + String expected = + commonConfig() + + "server.0=foo:321:123\n" + + commonTlsConfig() + + "sslQuorum=true\n" + + "portUnification=false\n"; validateConfigFile(cfgFile, expected); } |