mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-18 02:44:49 +00:00
SSL/TLS: Add options to configure session cache size and timeout
The default settings for the SSL session cache is unbounded with a timeout of 24 hours. This can lead to memory issues when clients do not resume connections. This adds a default limit of 1000 sessions in the cache in addition to exposing settings to control these values. Closes elastic/elasticsearch#602 Original commit: elastic/x-pack-elasticsearch@9cdc7b613c
This commit is contained in:
parent
9fed91b795
commit
e8a17d9ccd
@ -8,8 +8,10 @@ package org.elasticsearch.shield.ssl;
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.common.component.AbstractComponent;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.primitives.Ints;
|
||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.common.util.concurrent.ConcurrentCollections;
|
||||
import org.elasticsearch.shield.ShieldSettingsException;
|
||||
|
||||
@ -27,6 +29,7 @@ public class SSLService extends AbstractComponent {
|
||||
|
||||
static final String[] DEFAULT_CIPHERS = new String[]{ "TLS_RSA_WITH_AES_128_CBC_SHA256", "TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA" };
|
||||
static final String[] DEFAULT_SUPPORTED_PROTOCOLS = new String[] {"TLSv1", "TLSv1.1", "TLSv1.2"};
|
||||
static final TimeValue DEFAULT_SESSION_CACHE_TIMEOUT = TimeValue.timeValueHours(24);
|
||||
|
||||
private Map<String, SSLContext> sslContexts = ConcurrentCollections.newConcurrentMap();
|
||||
|
||||
@ -99,15 +102,17 @@ public class SSLService extends AbstractComponent {
|
||||
String key = keyStorePath + trustStorePath + sslProtocol;
|
||||
SSLContext sslContext = sslContexts.get(key);
|
||||
if (sslContext == null) {
|
||||
logger.debug("using keyStore[{}], keyAlgorithm[{}], trustStore[{}], truststoreAlgorithm[{}], TLS protocol[{}]",
|
||||
keyStorePath, keyStoreAlgorithm, trustStorePath, trustStoreAlgorithm, sslProtocol);
|
||||
int sessionCacheSize = settings.getAsInt("session.cache_size", componentSettings.getAsInt("session.cache_size", 1000));
|
||||
TimeValue sessionCacheTimeout = settings.getAsTime("session.cache_timeout", componentSettings.getAsTime("session.cache_timeout", DEFAULT_SESSION_CACHE_TIMEOUT));
|
||||
logger.debug("using keystore[{}], key_algorithm[{}], truststore[{}], truststore_algorithm[{}], tls_protocol[{}], session_cache_size[{}], session_cache_timeout[{}]",
|
||||
keyStorePath, keyStoreAlgorithm, trustStorePath, trustStoreAlgorithm, sslProtocol, sessionCacheSize, sessionCacheTimeout);
|
||||
|
||||
TrustManagerFactory trustFactory = getTrustFactory(trustStorePath, trustStorePassword, trustStoreAlgorithm);
|
||||
KeyManagerFactory keyManagerFactory = createKeyManagerFactory(keyStorePath, keyStorePassword, keyStoreAlgorithm, keyPassword);
|
||||
sslContext = createSslContext(keyManagerFactory, trustFactory, sslProtocol);
|
||||
sslContext = createSslContext(keyManagerFactory, trustFactory, sslProtocol, sessionCacheSize, sessionCacheTimeout);
|
||||
sslContexts.put(key, sslContext);
|
||||
} else {
|
||||
logger.trace("found keystore[{}], trustStore[{}], TLS protocol[{}] in SSL context cache, reusing", keyStorePath, trustStorePath, sslProtocol);
|
||||
logger.trace("found keystore[{}], truststore[{}], tls_protocol[{}] in SSL context cache, reusing", keyStorePath, trustStorePath, sslProtocol);
|
||||
}
|
||||
|
||||
return sslContext;
|
||||
@ -144,11 +149,13 @@ public class SSLService extends AbstractComponent {
|
||||
}
|
||||
}
|
||||
|
||||
private SSLContext createSslContext(KeyManagerFactory keyManagerFactory, TrustManagerFactory trustFactory, String sslProtocol) {
|
||||
private SSLContext createSslContext(KeyManagerFactory keyManagerFactory, TrustManagerFactory trustFactory, String sslProtocol, int sessionCacheSize, TimeValue sessionCacheTimeout) {
|
||||
// Initialize sslContext
|
||||
try {
|
||||
SSLContext sslContext = SSLContext.getInstance(sslProtocol);
|
||||
sslContext.init(keyManagerFactory.getKeyManagers(), trustFactory.getTrustManagers(), null);
|
||||
sslContext.getServerSessionContext().setSessionCacheSize(sessionCacheSize);
|
||||
sslContext.getServerSessionContext().setSessionTimeout(Ints.checkedCast(sessionCacheTimeout.seconds()));
|
||||
return sslContext;
|
||||
} catch (Exception e) {
|
||||
throw new ElasticsearchSSLException("failed to initialize the SSLContext", e);
|
||||
|
@ -6,12 +6,14 @@
|
||||
package org.elasticsearch.shield.ssl;
|
||||
|
||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLEngine;
|
||||
import javax.net.ssl.SSLSessionContext;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
@ -100,4 +102,28 @@ public class SSLServiceTests extends ElasticsearchTestCase {
|
||||
SSLEngine engine = sslService.createSSLEngine();
|
||||
assertThat(Arrays.asList(engine.getEnabledProtocols()), not(hasItem("SSLv3")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThatSSLSessionCacheHasDefaultLimits() throws Exception {
|
||||
SSLService sslService = new SSLService(settingsBuilder()
|
||||
.put("shield.ssl.keystore.path", testnodeStore)
|
||||
.put("shield.ssl.keystore.password", "testnode")
|
||||
.build());
|
||||
SSLSessionContext context = sslService.getSslContext().getServerSessionContext();
|
||||
assertThat(context.getSessionCacheSize(), equalTo(1000));
|
||||
assertThat(context.getSessionTimeout(), equalTo((int) TimeValue.timeValueHours(24).seconds()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThatSettingSSLSessionCacheLimitsWorks() throws Exception {
|
||||
SSLService sslService = new SSLService(settingsBuilder()
|
||||
.put("shield.ssl.keystore.path", testnodeStore)
|
||||
.put("shield.ssl.keystore.password", "testnode")
|
||||
.put("shield.ssl.session.cache_size", "300")
|
||||
.put("shield.ssl.session.cache_timeout", "600s")
|
||||
.build());
|
||||
SSLSessionContext context = sslService.getSslContext().getServerSessionContext();
|
||||
assertThat(context.getSessionCacheSize(), equalTo(300));
|
||||
assertThat(context.getSessionTimeout(), equalTo(600));
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user