Skip to content

Commit 680d3b3

Browse files
authored
Add deprecation warnings for ssl config fallback (#36847)
SSL configuration fallback has long been present in security but is a source of confusion due to the behavior. Ultimately, we plan to remove support for fallback in the next major version so this commit provides deprecation warnings for the current line of stable releases.
1 parent 137a5e9 commit 680d3b3

File tree

40 files changed

+492
-270
lines changed

40 files changed

+492
-270
lines changed

docs/reference/settings/security-settings.asciidoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1213,6 +1213,10 @@ through the list of URLs will continue until a successful connection is made.
12131213
[[ssl-tls-settings]]
12141214
==== Default TLS/SSL settings
12151215

1216+
deprecated[6.7.0, fallback to the default TLS/SSL settings is deprecated as it
1217+
leads to ambiguity in what configuration is used. Fully configure each components'
1218+
TLS/SSL settings as the default settings will be removed in 7.0]
1219+
12161220
You can configure the following TLS/SSL settings in
12171221
`elasticsearch.yml`. For more information, see
12181222
{stack-ov}/encrypting-communications.html[Encrypting communications]. These

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

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.util.Collection;
2626
import java.util.Collections;
2727
import java.util.List;
28+
import java.util.Objects;
2829

2930
/**
3031
* This class represents a trust configuration that corresponds to the default trusted certificates of the JDK
@@ -69,16 +70,6 @@ public String toString() {
6970
return "JDK trusted certs";
7071
}
7172

72-
@Override
73-
public boolean equals(Object o) {
74-
return o == this;
75-
}
76-
77-
@Override
78-
public int hashCode() {
79-
return System.identityHashCode(this);
80-
}
81-
8273
/**
8374
* Merges the default trust configuration with the provided {@link TrustConfig}
8475
* @param trustConfig the trust configuration to merge with
@@ -109,4 +100,17 @@ private KeyStore getSystemTrustStore() throws KeyStoreException, CertificateExce
109100
}
110101
return null;
111102
}
103+
104+
@Override
105+
public boolean equals(Object o) {
106+
if (this == o) return true;
107+
if (o == null || getClass() != o.getClass()) return false;
108+
DefaultJDKTrustConfig that = (DefaultJDKTrustConfig) o;
109+
return Objects.equals(trustStorePassword, that.trustStorePassword);
110+
}
111+
112+
@Override
113+
public int hashCode() {
114+
return Objects.hash(trustStorePassword);
115+
}
112116
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,9 @@ private static SecureString getDefaultTrustStorePassword(Settings settings) {
256256
return trustStorePassword;
257257
}
258258
}
259-
return systemTrustStorePassword;
259+
// since we are in a try with resources block, we need to clone the value so it doesn't get
260+
// cleared!
261+
return systemTrustStorePassword.clone();
260262
}
261263
}
262264
return null;

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

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.elasticsearch.common.settings.Setting.Property;
1212
import org.elasticsearch.common.settings.Settings;
1313
import org.elasticsearch.common.util.CollectionUtils;
14+
import org.elasticsearch.xpack.core.XPackSettings;
1415

1516
import javax.net.ssl.TrustManagerFactory;
1617

@@ -57,12 +58,12 @@ public class SSLConfigurationSettings {
5758
private static final String PKCS12_KEYSTORE_TYPE = "PKCS12";
5859

5960
private static final Function<String, Setting<List<String>>> CIPHERS_SETTING_TEMPLATE = key -> Setting.listSetting(key, Collections
60-
.emptyList(), Function.identity(), Property.NodeScope, Property.Filtered);
61+
.emptyList(), Function.identity(), propertiesFromKey(key));
6162
public static final Setting<List<String>> CIPHERS_SETTING_PROFILES = Setting.affixKeySetting("transport.profiles.",
6263
"xpack.security.ssl.cipher_suites", CIPHERS_SETTING_TEMPLATE);
6364

6465
private static final Function<String,Setting<List<String>>> SUPPORTED_PROTOCOLS_TEMPLATE = key -> Setting.listSetting(key,
65-
Collections.emptyList(), Function.identity(), Property.NodeScope, Property.Filtered);
66+
Collections.emptyList(), Function.identity(), propertiesFromKey(key));
6667
public static final Setting<List<String>> SUPPORTED_PROTOCOLS_PROFILES = Setting.affixKeySetting("transport.profiles.",
6768
"xpack.security.ssl.supported_protocols", SUPPORTED_PROTOCOLS_TEMPLATE) ;
6869

@@ -82,7 +83,7 @@ public class SSLConfigurationSettings {
8283
"xpack.security.ssl.keystore.secure_key_password", X509KeyPairSettings.KEYSTORE_KEY_PASSWORD_TEMPLATE);
8384

8485
private static final Function<String, Setting<Optional<String>>> TRUST_STORE_PATH_TEMPLATE = key -> new Setting<>(key, s -> null,
85-
Optional::ofNullable, Property.NodeScope, Property.Filtered);
86+
Optional::ofNullable, propertiesFromKey(key));
8687
public static final Setting<Optional<String>> TRUST_STORE_PATH_PROFILES = Setting.affixKeySetting("transport.profiles.",
8788
"xpack.security.ssl.truststore.path", TRUST_STORE_PATH_TEMPLATE);
8889

@@ -96,7 +97,8 @@ public class SSLConfigurationSettings {
9697

9798
private static final Function<String, Setting<SecureString>> TRUSTSTORE_PASSWORD_TEMPLATE = key ->
9899
SecureSetting.secureString(key, LEGACY_TRUSTSTORE_PASSWORD_TEMPLATE.apply(key.replace("truststore.secure_password",
99-
"truststore.password")));
100+
"truststore.password")),
101+
key.startsWith(XPackSettings.GLOBAL_SSL_PREFIX) ? new Property[] { Property.Deprecated } : new Property[0]);
100102
public static final Setting<SecureString> TRUSTSTORE_PASSWORD_PROFILES = Setting.affixKeySetting("transport.profiles.",
101103
"xpack.security.ssl.truststore.secure_password", TRUSTSTORE_PASSWORD_TEMPLATE);
102104

@@ -105,7 +107,7 @@ public class SSLConfigurationSettings {
105107

106108
private static final Function<String, Setting<String>> TRUST_STORE_ALGORITHM_TEMPLATE = key ->
107109
new Setting<>(key, s -> TrustManagerFactory.getDefaultAlgorithm(),
108-
Function.identity(), Property.NodeScope, Property.Filtered);
110+
Function.identity(), propertiesFromKey(key));
109111
public static final Setting<String> TRUST_STORE_ALGORITHM_PROFILES = Setting.affixKeySetting("transport.profiles.",
110112
"xpack.security.ssl.truststore.algorithm", TRUST_STORE_ALGORITHM_TEMPLATE);
111113

@@ -118,7 +120,7 @@ public class SSLConfigurationSettings {
118120
"xpack.security.ssl.truststore.type", TRUST_STORE_TYPE_TEMPLATE);
119121

120122
private static final Function<String, Setting<Optional<String>>> TRUST_RESTRICTIONS_TEMPLATE = key -> new Setting<>(key, s -> null,
121-
Optional::ofNullable, Property.NodeScope, Property.Filtered);
123+
Optional::ofNullable, propertiesFromKey(key));
122124
public static final Setting<Optional<String>> TRUST_RESTRICTIONS_PROFILES = Setting.affixKeySetting("transport.profiles.",
123125
"xpack.security.ssl.trust_restrictions", TRUST_RESTRICTIONS_TEMPLATE);
124126

@@ -132,19 +134,19 @@ public class SSLConfigurationSettings {
132134
"xpack.security.ssl.certificate", X509KeyPairSettings.CERT_TEMPLATE);
133135

134136
private static final Function<String, Setting<List<String>>> CAPATH_SETTING_TEMPLATE = key -> Setting.listSetting(key, Collections
135-
.emptyList(), Function.identity(), Property.NodeScope, Property.Filtered);
137+
.emptyList(), Function.identity(), propertiesFromKey(key));
136138
public static final Setting<List<String>> CAPATH_SETTING_PROFILES = Setting.affixKeySetting("transport.profiles.",
137139
"xpack.security.ssl.certificate_authorities", CAPATH_SETTING_TEMPLATE);
138140

139141
private static final Function<String, Setting<Optional<SSLClientAuth>>> CLIENT_AUTH_SETTING_TEMPLATE =
140142
key -> new Setting<>(key, (String) null, s -> s == null ? Optional.empty() : Optional.of(SSLClientAuth.parse(s)),
141-
Property.NodeScope, Property.Filtered);
143+
propertiesFromKey(key));
142144
public static final Setting<Optional<SSLClientAuth>> CLIENT_AUTH_SETTING_PROFILES = Setting.affixKeySetting("transport.profiles.",
143145
"xpack.security.ssl.client_authentication", CLIENT_AUTH_SETTING_TEMPLATE);
144146

145147
private static final Function<String, Setting<Optional<VerificationMode>>> VERIFICATION_MODE_SETTING_TEMPLATE =
146148
key -> new Setting<>(key, (String) null, s -> s == null ? Optional.empty() : Optional.of(VerificationMode.parse(s)),
147-
Property.NodeScope, Property.Filtered);
149+
propertiesFromKey(key));
148150
public static final Setting<Optional<VerificationMode>> VERIFICATION_MODE_SETTING_PROFILES = Setting.affixKeySetting(
149151
"transport.profiles.", "xpack.security.ssl.verification_mode", VERIFICATION_MODE_SETTING_TEMPLATE);
150152

@@ -190,6 +192,14 @@ private static String inferKeyStoreType(String path) {
190192
}
191193
}
192194

195+
static Property[] propertiesFromKey(String key) {
196+
if (key.startsWith(XPackSettings.GLOBAL_SSL_PREFIX)) {
197+
return new Property[] { Property.NodeScope, Property.Filtered, Property.Deprecated };
198+
} else {
199+
return new Property[] { Property.NodeScope, Property.Filtered };
200+
}
201+
}
202+
193203
public List<Setting<?>> getAllSettings() {
194204
return allSettings;
195205
}

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

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,21 @@
77

88
import org.apache.http.conn.ssl.NoopHostnameVerifier;
99
import org.apache.http.nio.conn.ssl.SSLIOSessionStrategy;
10+
import org.apache.logging.log4j.LogManager;
11+
import org.apache.logging.log4j.Logger;
1012
import org.apache.lucene.util.SetOnce;
1113
import org.elasticsearch.ElasticsearchException;
1214
import org.elasticsearch.common.CheckedSupplier;
1315
import org.elasticsearch.common.Strings;
1416
import org.elasticsearch.common.component.AbstractComponent;
17+
import org.elasticsearch.common.logging.DeprecationLogger;
1518
import org.elasticsearch.common.settings.Settings;
1619
import org.elasticsearch.env.Environment;
1720
import org.elasticsearch.xpack.core.XPackSettings;
1821
import org.elasticsearch.xpack.core.common.socket.SocketAccess;
1922
import org.elasticsearch.xpack.core.security.SecurityField;
23+
import org.elasticsearch.xpack.core.security.authc.ldap.LdapRealmSettings;
24+
import org.elasticsearch.xpack.core.security.authc.saml.SamlRealmSettings;
2025
import org.elasticsearch.xpack.core.ssl.cert.CertificateInfo;
2126

2227
import javax.net.ssl.HostnameVerifier;
@@ -61,7 +66,8 @@
6166
*/
6267
public class SSLService extends AbstractComponent {
6368

64-
private final Settings settings;
69+
private static final Logger logger = LogManager.getLogger(SSLService.class);
70+
private static final DeprecationLogger deprecationLogger = new DeprecationLogger(logger);
6571

6672
/**
6773
* This is a mapping from "context name" (in general use, the name of a setting key)
@@ -83,6 +89,7 @@ public class SSLService extends AbstractComponent {
8389
private final SSLConfiguration globalSSLConfiguration;
8490
private final SetOnce<SSLConfiguration> transportSSLConfiguration = new SetOnce<>();
8591
private final Environment env;
92+
private final Settings settings;
8693

8794
/**
8895
* Create a new SSLService that parses the settings for the ssl contexts that need to be created, creates them, and then caches them
@@ -119,6 +126,13 @@ Map<SSLConfiguration, SSLContextHolder> loadSSLConfigurations() {
119126
return Collections.emptyMap();
120127
}
121128

129+
@Override
130+
SSLConfiguration sslConfiguration(Settings settings) {
131+
SSLConfiguration sslConfiguration = super.sslConfiguration(settings);
132+
SSLService.this.checkSSLConfigurationForFallback("monitoring.exporters", settings, sslConfiguration);
133+
return sslConfiguration;
134+
}
135+
122136
/**
123137
* Returns the existing {@link SSLContextHolder} for the configuration
124138
* @throws IllegalArgumentException if not found
@@ -405,22 +419,35 @@ Map<SSLConfiguration, SSLContextHolder> loadSSLConfigurations() {
405419

406420
sslSettingsMap.forEach((key, sslSettings) -> {
407421
if (sslSettings.isEmpty()) {
422+
if (shouldCheckForFallbackDeprecation(key)) {
423+
checkSSLConfigurationForFallback(key, sslSettings, new SSLConfiguration(sslSettings, globalSSLConfiguration));
424+
}
408425
storeSslConfiguration(key, globalSSLConfiguration);
409426
} else {
410427
final SSLConfiguration configuration = new SSLConfiguration(sslSettings, globalSSLConfiguration);
428+
if (shouldCheckForFallbackDeprecation(key)) {
429+
checkSSLConfigurationForFallback(key, sslSettings, configuration);
430+
}
411431
storeSslConfiguration(key, configuration);
412432
sslContextHolders.computeIfAbsent(configuration, this::createSslContext);
413433
}
414434
});
415435

416436
final Settings transportSSLSettings = settings.getByPrefix(XPackSettings.TRANSPORT_SSL_PREFIX);
417437
final SSLConfiguration transportSSLConfiguration = new SSLConfiguration(transportSSLSettings, globalSSLConfiguration);
438+
final boolean transportSSLEnabled = XPackSettings.TRANSPORT_SSL_ENABLED.get(settings);
439+
if (transportSSLEnabled) {
440+
checkSSLConfigurationForFallback(XPackSettings.TRANSPORT_SSL_PREFIX, transportSSLSettings, transportSSLConfiguration);
441+
}
418442
this.transportSSLConfiguration.set(transportSSLConfiguration);
419443
storeSslConfiguration(XPackSettings.TRANSPORT_SSL_PREFIX, transportSSLConfiguration);
420444
Map<String, Settings> profileSettings = getTransportProfileSSLSettings(settings);
421445
sslContextHolders.computeIfAbsent(transportSSLConfiguration, this::createSslContext);
422446
profileSettings.forEach((key, profileSetting) -> {
423447
final SSLConfiguration configuration = new SSLConfiguration(profileSetting, transportSSLConfiguration);
448+
if (transportSSLEnabled && key.equals("transport.profiles.default.xpack.security.ssl") == false) {
449+
checkSSLConfigurationForFallback(key, profileSetting, configuration);
450+
}
424451
storeSslConfiguration(key, configuration);
425452
sslContextHolders.computeIfAbsent(configuration, this::createSslContext);
426453
});
@@ -435,6 +462,57 @@ private void storeSslConfiguration(String key, SSLConfiguration configuration) {
435462
sslConfigurations.put(key, configuration);
436463
}
437464

465+
private boolean shouldCheckForFallbackDeprecation(String name) {
466+
if (name.startsWith("xpack.security.authc.realms.")) {
467+
// try to see if this is actually using TLS
468+
Settings realm = settings.getByPrefix(name.substring(0, name.indexOf(".ssl")));
469+
String type = realm.get("type");
470+
// only check the types we know use ssl. custom realms may but we don't want to cause confusion
471+
if (LdapRealmSettings.LDAP_TYPE.equals(type) || LdapRealmSettings.AD_TYPE.equals(type)) {
472+
List<String> urls = realm.getAsList("url");
473+
return urls.isEmpty() == false && urls.stream().anyMatch(s -> s.startsWith("ldaps://"));
474+
} else if (SamlRealmSettings.TYPE.equals(type)) {
475+
final String idpMetadataPath = SamlRealmSettings.IDP_METADATA_PATH.get(realm);
476+
return Strings.hasText(idpMetadataPath) && idpMetadataPath.startsWith("https://");
477+
}
478+
} else if (name.startsWith("xpack.monitoring.exporters.")) {
479+
Settings exporterSettings = settings.getByPrefix(name.substring(0, name.indexOf(".ssl")));
480+
List<String> hosts = exporterSettings.getAsList("host");
481+
return hosts.stream().anyMatch(s -> s.startsWith("https"));
482+
} else if (name.equals(XPackSettings.HTTP_SSL_PREFIX) && XPackSettings.HTTP_SSL_ENABLED.get(settings)) {
483+
return true;
484+
} else if (name.equals("xpack.http.ssl") && XPackSettings.WATCHER_ENABLED.get(settings)) {
485+
return true;
486+
}
487+
return false;
488+
}
489+
490+
private void checkSSLConfigurationForFallback(String name, Settings settings, SSLConfiguration config) {
491+
final SSLConfiguration noFallBackConfig = new SSLConfiguration(settings);
492+
if (config.equals(noFallBackConfig) == false) {
493+
List<String> fallbackReliers = new ArrayList<>();
494+
if (config.keyConfig().equals(noFallBackConfig.keyConfig()) == false) {
495+
fallbackReliers.add("key configuration");
496+
}
497+
if (config.trustConfig().equals(noFallBackConfig.trustConfig()) == false) {
498+
fallbackReliers.add("trust configuration");
499+
}
500+
if (config.cipherSuites().equals(noFallBackConfig.cipherSuites()) == false) {
501+
fallbackReliers.add("enabled cipher suites");
502+
}
503+
if (config.sslClientAuth() != noFallBackConfig.sslClientAuth()) {
504+
fallbackReliers.add("client authentication");
505+
}
506+
if (config.supportedProtocols().equals(noFallBackConfig.supportedProtocols()) == false) {
507+
fallbackReliers.add("supported protocols");
508+
}
509+
if (config.verificationMode() != noFallBackConfig.verificationMode()) {
510+
fallbackReliers.add("certificate verification mode");
511+
}
512+
deprecationLogger.deprecated("SSL configuration [{}] relies upon fallback to another configuration for {}, which is " +
513+
"deprecated.", name, fallbackReliers);
514+
}
515+
}
438516

439517
/**
440518
* Returns information about each certificate that is referenced by any SSL configuration.

0 commit comments

Comments
 (0)