Skip to content

Commit e5795f5

Browse files
authored
Backport SSL context names (#30953) to 6.x (#32223)
Historically we have loaded SSL objects (such as SSLContext, SSLIOSessionStrategy) by passing in the SSL settings, constructing a new SSL configuration from those settings and then looking for a cached object that matches those settings. The primary issue with this approach is that it requires a fully configured Settings object to be available any time the SSL context needs to be loaded. If the Settings include SecureSettings (such as passwords for keys or keystores) then this is not true, and the cached SSL object cannot be loaded at runtime. This commit introduces an alternative approach of naming every cached ssl configuration, so that it is possible to load the SSL context for a named configuration (such as "xpack.http.ssl"). This means that the calling code does not need to have ongoing access to the secure settings that were used to load the configuration. This change also allows monitoring exporters to use SSL passwords from secure settings, however an exporter that uses a secure SSL setting (e.g. truststore.secure_password) may not have its SSL settings updated dynamically (this is prevented by a settings validator). Exporters without secure settings can continue to be defined and updated dynamically. Backport of: - c662565 - edbea73 - 6f2b7dc
1 parent a2c0107 commit e5795f5

File tree

34 files changed

+868
-422
lines changed

34 files changed

+868
-422
lines changed

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/transport/netty4/SecurityNetty4Transport.java

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@
2727
import org.elasticsearch.xpack.core.ssl.SSLService;
2828

2929
import javax.net.ssl.SSLEngine;
30-
3130
import java.net.InetSocketAddress;
3231
import java.net.SocketAddress;
3332
import java.util.Collections;
3433
import java.util.HashMap;
3534
import java.util.Map;
35+
import java.util.Set;
3636

3737
import static org.elasticsearch.xpack.core.security.SecurityField.setting;
3838

@@ -57,29 +57,31 @@ public SecurityNetty4Transport(
5757
super(settings, threadPool, networkService, bigArrays, namedWriteableRegistry, circuitBreakerService);
5858
this.sslService = sslService;
5959
this.sslEnabled = XPackSettings.TRANSPORT_SSL_ENABLED.get(settings);
60-
final Settings transportSSLSettings = settings.getByPrefix(setting("transport.ssl."));
6160
if (sslEnabled) {
62-
this.sslConfiguration = sslService.sslConfiguration(transportSSLSettings, Settings.EMPTY);
63-
Map<String, Settings> profileSettingsMap = settings.getGroups("transport.profiles.", true);
64-
Map<String, SSLConfiguration> profileConfiguration = new HashMap<>(profileSettingsMap.size() + 1);
65-
for (Map.Entry<String, Settings> entry : profileSettingsMap.entrySet()) {
66-
Settings profileSettings = entry.getValue();
67-
final Settings profileSslSettings = profileSslSettings(profileSettings);
68-
SSLConfiguration configuration = sslService.sslConfiguration(profileSslSettings, transportSSLSettings);
69-
profileConfiguration.put(entry.getKey(), configuration);
70-
}
71-
72-
if (profileConfiguration.containsKey(TcpTransport.DEFAULT_PROFILE) == false) {
73-
profileConfiguration.put(TcpTransport.DEFAULT_PROFILE, sslConfiguration);
74-
}
75-
61+
this.sslConfiguration = sslService.getSSLConfiguration(setting("transport.ssl."));
62+
Map<String, SSLConfiguration> profileConfiguration = getTransportProfileConfigurations(settings, sslService, sslConfiguration);
7663
this.profileConfiguration = Collections.unmodifiableMap(profileConfiguration);
7764
} else {
7865
this.profileConfiguration = Collections.emptyMap();
7966
this.sslConfiguration = null;
8067
}
8168
}
8269

70+
public static Map<String, SSLConfiguration> getTransportProfileConfigurations(Settings settings, SSLService sslService,
71+
SSLConfiguration defaultConfiguration) {
72+
Set<String> profileNames = settings.getGroups("transport.profiles.", true).keySet();
73+
Map<String, SSLConfiguration> profileConfiguration = new HashMap<>(profileNames.size() + 1);
74+
for (String profileName : profileNames) {
75+
SSLConfiguration configuration = sslService.getSSLConfiguration("transport.profiles." + profileName + "." + setting("ssl"));
76+
profileConfiguration.put(profileName, configuration);
77+
}
78+
79+
if (profileConfiguration.containsKey(TcpTransport.DEFAULT_PROFILE) == false) {
80+
profileConfiguration.put(TcpTransport.DEFAULT_PROFILE, defaultConfiguration);
81+
}
82+
return profileConfiguration;
83+
}
84+
8385
@Override
8486
protected void doStart() {
8587
super.doStart();
@@ -208,8 +210,4 @@ public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress,
208210
super.connect(ctx, remoteAddress, localAddress, promise);
209211
}
210212
}
211-
212-
public static Settings profileSslSettings(Settings profileSettings) {
213-
return profileSettings.getByPrefix(setting("ssl."));
214-
}
215213
}

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ssl/SSLConfigurationSettings.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import java.util.Locale;
2323
import java.util.Optional;
2424
import java.util.function.Function;
25+
import java.util.stream.Collectors;
26+
import java.util.stream.Stream;
2527

2628
/**
2729
* Bridges SSLConfiguration into the {@link Settings} framework, using {@link Setting} objects.
@@ -221,4 +223,10 @@ public static Collection<Setting<?>> getProfileSettings() {
221223
CLIENT_AUTH_SETTING_PROFILES, VERIFICATION_MODE_SETTING_PROFILES);
222224
}
223225

226+
public List<Setting<SecureString>> getSecureSettingsInUse(Settings settings) {
227+
return Stream.of(this.truststorePassword, this.x509KeyPair.keystorePassword,
228+
this.x509KeyPair.keystoreKeyPassword, this.x509KeyPair.keyPassword)
229+
.filter(s -> s.exists(settings))
230+
.collect(Collectors.toList());
231+
}
224232
}

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ssl/SSLService.java

Lines changed: 115 additions & 126 deletions
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
package org.elasticsearch.xpack.core.security.transport.netty4;
8+
9+
import org.elasticsearch.common.settings.Settings;
10+
import org.elasticsearch.env.Environment;
11+
import org.elasticsearch.env.TestEnvironment;
12+
import org.elasticsearch.test.ESTestCase;
13+
import org.elasticsearch.xpack.core.ssl.SSLConfiguration;
14+
import org.elasticsearch.xpack.core.ssl.SSLService;
15+
import org.elasticsearch.xpack.core.ssl.VerificationMode;
16+
import org.hamcrest.Matchers;
17+
18+
import java.util.Map;
19+
20+
import static org.elasticsearch.xpack.core.security.transport.netty4.SecurityNetty4Transport.getTransportProfileConfigurations;
21+
22+
public class SecurityNetty4TransportTests extends ESTestCase {
23+
24+
public void testGetTransportProfileConfigurations() {
25+
final Settings settings = Settings.builder()
26+
.put("path.home", createTempDir())
27+
.put("xpack.security.transport.ssl.verification_mode", VerificationMode.CERTIFICATE.name())
28+
.put("transport.profiles.full.xpack.security.ssl.verification_mode", VerificationMode.FULL.name())
29+
.put("transport.profiles.cert.xpack.security.ssl.verification_mode", VerificationMode.CERTIFICATE.name())
30+
.put("transport.profiles.none.xpack.security.ssl.verification_mode", VerificationMode.NONE.name())
31+
.build();
32+
final Environment env = TestEnvironment.newEnvironment(settings);
33+
SSLService sslService = new SSLService(settings, env);
34+
final SSLConfiguration defaultConfig = sslService.getSSLConfiguration("xpack.security.transport.ssl");
35+
final Map<String, SSLConfiguration> profileConfigurations = getTransportProfileConfigurations(settings, sslService, defaultConfig);
36+
assertThat(profileConfigurations.size(), Matchers.equalTo(4));
37+
assertThat(profileConfigurations.keySet(), Matchers.containsInAnyOrder("full", "cert", "none", "default"));
38+
assertThat(profileConfigurations.get("full").verificationMode(), Matchers.equalTo(VerificationMode.FULL));
39+
assertThat(profileConfigurations.get("cert").verificationMode(), Matchers.equalTo(VerificationMode.CERTIFICATE));
40+
assertThat(profileConfigurations.get("none").verificationMode(), Matchers.equalTo(VerificationMode.NONE));
41+
assertThat(profileConfigurations.get("default"), Matchers.sameInstance(defaultConfig));
42+
}
43+
}

x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ssl/SSLConfigurationReloaderTests.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ public void testReloadingKeyStoreException() throws Exception {
303303
.build();
304304
Environment env = randomBoolean() ? null : TestEnvironment.newEnvironment(settings);
305305
final SSLService sslService = new SSLService(settings, env);
306-
final SSLConfiguration config = sslService.sslConfiguration(Settings.EMPTY);
306+
final SSLConfiguration config = sslService.getSSLConfiguration("xpack.ssl");
307307
new SSLConfigurationReloader(settings, env, sslService, resourceWatcherService) {
308308
@Override
309309
void reloadSSLContext(SSLConfiguration configuration) {
@@ -344,7 +344,7 @@ public void testReloadingPEMKeyConfigException() throws Exception {
344344
.build();
345345
Environment env = randomBoolean() ? null : TestEnvironment.newEnvironment(settings);
346346
final SSLService sslService = new SSLService(settings, env);
347-
final SSLConfiguration config = sslService.sslConfiguration(Settings.EMPTY);
347+
final SSLConfiguration config = sslService.getSSLConfiguration("xpack.ssl");
348348
new SSLConfigurationReloader(settings, env, sslService, resourceWatcherService) {
349349
@Override
350350
void reloadSSLContext(SSLConfiguration configuration) {
@@ -379,7 +379,7 @@ public void testTrustStoreReloadException() throws Exception {
379379
.build();
380380
Environment env = randomBoolean() ? null : TestEnvironment.newEnvironment(settings);
381381
final SSLService sslService = new SSLService(settings, env);
382-
final SSLConfiguration config = sslService.sslConfiguration(Settings.EMPTY);
382+
final SSLConfiguration config = sslService.getSSLConfiguration("xpack.ssl");
383383
new SSLConfigurationReloader(settings, env, sslService, resourceWatcherService) {
384384
@Override
385385
void reloadSSLContext(SSLConfiguration configuration) {
@@ -411,7 +411,7 @@ public void testPEMTrustReloadException() throws Exception {
411411
.build();
412412
Environment env = randomBoolean() ? null : TestEnvironment.newEnvironment(settings);
413413
final SSLService sslService = new SSLService(settings, env);
414-
final SSLConfiguration config = sslService.sslConfiguration(Settings.EMPTY);
414+
final SSLConfiguration config = sslService.getSSLConfiguration("xpack.ssl");
415415
new SSLConfigurationReloader(settings, env, sslService, resourceWatcherService) {
416416
@Override
417417
void reloadSSLContext(SSLConfiguration configuration) {
@@ -440,7 +440,7 @@ private void validateSSLConfigurationIsReloaded(Settings settings, Environment e
440440

441441
final CountDownLatch reloadLatch = new CountDownLatch(1);
442442
final SSLService sslService = new SSLService(settings, env);
443-
final SSLConfiguration config = sslService.sslConfiguration(Settings.EMPTY);
443+
final SSLConfiguration config = sslService.getSSLConfiguration("xpack.ssl");
444444
new SSLConfigurationReloader(settings, env, sslService, resourceWatcherService) {
445445
@Override
446446
void reloadSSLContext(SSLConfiguration configuration) {

0 commit comments

Comments
 (0)