Skip to content

Commit d3f5c39

Browse files
committed
ZOOKEEPER-4990: accept ssl.* in client config
1 parent 321f84d commit d3f5c39

File tree

3 files changed

+90
-1
lines changed

3 files changed

+90
-1
lines changed

zookeeper-docs/src/main/resources/markdown/zookeeperCLI.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,21 @@ bin/zkCli.sh -waitforconnection -timeout 3000 -server remoteIP:2181
2929
# connect with a custom client configuration properties file
3030
bin/zkCli.sh -client-configuration /path/to/client.properties
3131
```
32+
33+
When connecting to a TLS-only server, provide a client configuration file with
34+
the SSL settings. The `zookeeper.ssl.*` keys are preferred; `ssl.*` keys from a
35+
server `zoo.cfg` are also accepted.
36+
37+
```bash
38+
# client.properties (TLS example)
39+
zookeeper.clientCnxnSocket=org.apache.zookeeper.ClientCnxnSocketNetty
40+
zookeeper.client.secure=true
41+
zookeeper.ssl.trustStore.location=/path/to/client-truststore.jks
42+
zookeeper.ssl.trustStore.password=changeit
43+
zookeeper.ssl.keyStore.location=/path/to/client-keystore.jks
44+
zookeeper.ssl.keyStore.password=changeit
45+
```
46+
3247
## help
3348
Showing helps about ZooKeeper commands
3449

@@ -570,4 +585,4 @@ Gives all authentication information added into the current session.
570585
[zkshell: 3] whoami
571586
Auth scheme: User
572587
ip: 127.0.0.1
573-
digest: user1
588+
digest: user1

zookeeper-server/src/main/java/org/apache/zookeeper/client/ZKClientConfig.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.io.File;
2222
import java.nio.file.Path;
2323
import org.apache.yetus.audience.InterfaceAudience;
24+
import org.apache.zookeeper.common.ClientX509Util;
2425
import org.apache.zookeeper.common.ConfigException;
2526
import org.apache.zookeeper.common.ZKConfig;
2627

@@ -59,6 +60,7 @@ public class ZKClientConfig extends ZKConfig {
5960
* Feature is disabled by default.
6061
*/
6162
public static final long ZOOKEEPER_REQUEST_TIMEOUT_DEFAULT = 0;
63+
private static final String ZOOKEEPER_PREFIX = "zookeeper.";
6264
public static final String ZK_SASL_CLIENT_ALLOW_REVERSE_DNS = "zookeeper.sasl.client.allowReverseDnsLookup";
6365
public static final boolean ZK_SASL_CLIENT_ALLOW_REVERSE_DNS_DEFAULT = false;
6466
/**
@@ -107,6 +109,12 @@ public ZKClientConfig(Path configPath) throws ConfigException {
107109
super(configPath);
108110
}
109111

112+
@Override
113+
public void addConfiguration(Path configPath) throws ConfigException {
114+
super.addConfiguration(configPath);
115+
applyServerSslConfiguration();
116+
}
117+
110118
/**
111119
* Initialize all the ZooKeeper client properties which are configurable as
112120
* java system property
@@ -139,6 +147,43 @@ protected void handleBackwardCompatibility() {
139147
setProperty(DNS_SRV_REFRESH_INTERVAL_SECONDS, System.getProperty(DNS_SRV_REFRESH_INTERVAL_SECONDS));
140148
}
141149

150+
private void applyServerSslConfiguration() {
151+
try (ClientX509Util clientX509Util = new ClientX509Util()) {
152+
copyServerSslProperty(clientX509Util.getSslProtocolProperty());
153+
copyServerSslProperty(clientX509Util.getSslEnabledProtocolsProperty());
154+
copyServerSslProperty(clientX509Util.getSslCipherSuitesProperty());
155+
copyServerSslProperty(clientX509Util.getSslKeystoreLocationProperty());
156+
copyServerSslProperty(clientX509Util.getSslKeystorePasswdProperty());
157+
copyServerSslProperty(clientX509Util.getSslKeystorePasswdPathProperty());
158+
copyServerSslProperty(clientX509Util.getSslKeystoreTypeProperty());
159+
copyServerSslProperty(clientX509Util.getSslTruststoreLocationProperty());
160+
copyServerSslProperty(clientX509Util.getSslTruststorePasswdProperty());
161+
copyServerSslProperty(clientX509Util.getSslTruststorePasswdPathProperty());
162+
copyServerSslProperty(clientX509Util.getSslTruststoreTypeProperty());
163+
copyServerSslProperty(clientX509Util.getSslContextSupplierClassProperty());
164+
copyServerSslProperty(clientX509Util.getSslHostnameVerificationEnabledProperty());
165+
copyServerSslProperty(clientX509Util.getSslCrlEnabledProperty());
166+
copyServerSslProperty(clientX509Util.getSslOcspEnabledProperty());
167+
copyServerSslProperty(clientX509Util.getSslClientAuthProperty());
168+
copyServerSslProperty(clientX509Util.getSslHandshakeDetectionTimeoutMillisProperty());
169+
copyServerSslProperty(clientX509Util.getSslAuthProviderProperty());
170+
}
171+
}
172+
173+
private void copyServerSslProperty(String clientProperty) {
174+
if (clientProperty == null || getProperty(clientProperty) != null) {
175+
return;
176+
}
177+
if (!clientProperty.startsWith(ZOOKEEPER_PREFIX)) {
178+
return;
179+
}
180+
String serverProperty = clientProperty.substring(ZOOKEEPER_PREFIX.length());
181+
String serverValue = getProperty(serverProperty);
182+
if (serverValue != null) {
183+
setProperty(clientProperty, serverValue);
184+
}
185+
}
186+
142187
/**
143188
* Returns true if the SASL client is enabled. By default, the client is
144189
* enabled but can be disabled by setting the system property

zookeeper-server/src/test/java/org/apache/zookeeper/client/ZKClientConfigTest.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import java.util.HashMap;
3838
import java.util.Map;
3939
import java.util.Properties;
40+
import org.apache.zookeeper.common.ClientX509Util;
4041
import org.apache.zookeeper.common.ConfigException;
4142
import org.apache.zookeeper.common.ZKConfig;
4243
import org.junit.jupiter.api.Test;
@@ -125,6 +126,34 @@ public void testReadConfigurationFile(@TempDir File testDataDir) throws IOExcept
125126
assertEquals(conf.getProperty("dummyProperty"), "dummyValue");
126127
}
127128

129+
@Test
130+
@Timeout(value = 10)
131+
public void testServerSslPropertyFallback(@TempDir File testDataDir) throws IOException, ConfigException {
132+
File file = File.createTempFile("clientConfigSsl", ".conf", testDataDir);
133+
Properties clientConfProp = new Properties();
134+
clientConfProp.setProperty("ssl.trustStore.location", "/tmp/server-truststore.jks");
135+
clientConfProp.setProperty("ssl.trustStore.password", "server-pass");
136+
clientConfProp.setProperty("ssl.keyStore.location", "/tmp/server-keystore.jks");
137+
clientConfProp.setProperty("ssl.keyStore.password", "server-pass");
138+
clientConfProp.setProperty("zookeeper.ssl.trustStore.location", "/tmp/client-truststore.jks");
139+
OutputStream io = new FileOutputStream(file);
140+
try {
141+
clientConfProp.store(io, "Client Configurations");
142+
} finally {
143+
io.close();
144+
}
145+
146+
ZKClientConfig conf = new ZKClientConfig();
147+
conf.addConfiguration(Paths.get(file.getAbsolutePath()));
148+
149+
try (ClientX509Util clientX509Util = new ClientX509Util()) {
150+
assertEquals("/tmp/client-truststore.jks", conf.getProperty(clientX509Util.getSslTruststoreLocationProperty()));
151+
assertEquals("server-pass", conf.getProperty(clientX509Util.getSslTruststorePasswdProperty()));
152+
assertEquals("/tmp/server-keystore.jks", conf.getProperty(clientX509Util.getSslKeystoreLocationProperty()));
153+
assertEquals("server-pass", conf.getProperty(clientX509Util.getSslKeystorePasswdProperty()));
154+
}
155+
}
156+
128157
@Test
129158
@Timeout(value = 10)
130159
public void testSetConfiguration() {

0 commit comments

Comments
 (0)