Browse Source

Add setting for tcp_keepalive for oidc back-channel (#87868)

This PR adds a new setting to enable tcp keepalive probes for the
connections used by the oidc back-channel communication. It defaults to
true as tcp keepalive is generally useful for ES.

Relates: #87773
Yang Wang 3 years ago
parent
commit
36336fe471

+ 5 - 0
docs/changelog/87868.yaml

@@ -0,0 +1,5 @@
+pr: 87868
+summary: Add setting for `tcp_keepalive` for oidc back-channel
+area: Security
+type: enhancement
+issues: []

+ 7 - 0
docs/reference/settings/security-settings.asciidoc

@@ -1858,6 +1858,13 @@ connections allowed per endpoint.
 Defaults to `200`.
 // end::oidc-http-max-endpoint-connections-tag[]
 
+// tag::oidc-http-tcp-keepalive-tag[]
+`http.tcp.keep_alive` {ess-icon}::
+(<<static-cluster-setting,Static>>)
+Whether to enable TCP keepalives on HTTP connections used for back-channel communication
+to the OpenID Connect Provider endpoints. Defaults to `true`.
+// end::oidc-http-tcp-keepalive-tag[]
+
 // tag::oidc-http-connection-pool-ttl-tag[]
 `http.connection_pool_ttl` {ess-icon}::
 (<<static-cluster-setting,Static>>)

+ 7 - 0
x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/oidc/OpenIdConnectRealmSettings.java

@@ -214,6 +214,12 @@ public class OpenIdConnectRealmSettings {
         key -> Setting.intSetting(key, 200, Setting.Property.NodeScope)
     );
 
+    public static final Setting.AffixSetting<Boolean> HTTP_TCP_KEEP_ALIVE = Setting.affixKeySetting(
+        RealmSettings.realmSettingPrefix(TYPE),
+        "http.tcp.keep_alive",
+        key -> Setting.boolSetting(key, true, Setting.Property.NodeScope)
+    );
+
     public static final Setting.AffixSetting<TimeValue> HTTP_CONNECTION_POOL_TTL = Setting.affixKeySetting(
         RealmSettings.realmSettingPrefix(TYPE),
         "http.connection_pool_ttl",
@@ -314,6 +320,7 @@ public class OpenIdConnectRealmSettings {
             HTTP_SOCKET_TIMEOUT,
             HTTP_MAX_CONNECTIONS,
             HTTP_MAX_ENDPOINT_CONNECTIONS,
+            HTTP_TCP_KEEP_ALIVE,
             HTTP_CONNECTION_POOL_TTL,
             HTTP_PROXY_HOST,
             HTTP_PROXY_PORT,

+ 5 - 1
x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/oidc/OpenIdConnectAuthenticator.java

@@ -67,6 +67,7 @@ import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
 import org.apache.http.impl.nio.client.HttpAsyncClients;
 import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager;
 import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
+import org.apache.http.impl.nio.reactor.IOReactorConfig;
 import org.apache.http.message.BasicNameValuePair;
 import org.apache.http.nio.conn.NoopIOSessionStrategy;
 import org.apache.http.nio.conn.SchemeIOSessionStrategy;
@@ -125,6 +126,7 @@ import static org.elasticsearch.xpack.core.security.authc.oidc.OpenIdConnectReal
 import static org.elasticsearch.xpack.core.security.authc.oidc.OpenIdConnectRealmSettings.HTTP_PROXY_PORT;
 import static org.elasticsearch.xpack.core.security.authc.oidc.OpenIdConnectRealmSettings.HTTP_PROXY_SCHEME;
 import static org.elasticsearch.xpack.core.security.authc.oidc.OpenIdConnectRealmSettings.HTTP_SOCKET_TIMEOUT;
+import static org.elasticsearch.xpack.core.security.authc.oidc.OpenIdConnectRealmSettings.HTTP_TCP_KEEP_ALIVE;
 
 /**
  * Handles an OpenID Connect Authentication response as received by the facilitator. In the case of an implicit flow, validates
@@ -691,7 +693,9 @@ public class OpenIdConnectAuthenticator {
         try {
             SpecialPermission.check();
             return AccessController.doPrivileged((PrivilegedExceptionAction<CloseableHttpAsyncClient>) () -> {
-                ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor();
+                ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(
+                    IOReactorConfig.custom().setSoKeepAlive(realmConfig.getSetting(HTTP_TCP_KEEP_ALIVE)).build()
+                );
                 final String sslKey = RealmSettings.realmSslPrefix(realmConfig.identifier());
                 final SslConfiguration sslConfiguration = sslService.getSSLConfiguration(sslKey);
                 final SSLContext clientContext = sslService.sslContext(sslConfiguration);