-
Notifications
You must be signed in to change notification settings - Fork 24.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add nio http transport to security plugin (#32018)
This is related to #27260. It adds the SecurityNioHttpServerTransport to the security plugin. It randomly uses the nio http transport in security integration tests.
- Loading branch information
1 parent
3679d00
commit 305bfea
Showing
23 changed files
with
750 additions
and
156 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
93 changes: 93 additions & 0 deletions
93
...gin/security/src/main/java/org/elasticsearch/xpack/security/transport/SSLEngineUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
package org.elasticsearch.xpack.security.transport; | ||
|
||
import io.netty.channel.Channel; | ||
import io.netty.handler.ssl.SslHandler; | ||
import org.apache.logging.log4j.Logger; | ||
import org.apache.logging.log4j.message.ParameterizedMessage; | ||
import org.apache.logging.log4j.util.Supplier; | ||
import org.elasticsearch.common.util.concurrent.ThreadContext; | ||
import org.elasticsearch.http.HttpChannel; | ||
import org.elasticsearch.http.netty4.Netty4HttpChannel; | ||
import org.elasticsearch.http.nio.NioHttpChannel; | ||
import org.elasticsearch.nio.SocketChannelContext; | ||
import org.elasticsearch.transport.TcpChannel; | ||
import org.elasticsearch.transport.netty4.Netty4TcpChannel; | ||
import org.elasticsearch.transport.nio.NioTcpChannel; | ||
import org.elasticsearch.xpack.security.authc.pki.PkiRealm; | ||
import org.elasticsearch.xpack.security.transport.nio.SSLChannelContext; | ||
|
||
import javax.net.ssl.SSLEngine; | ||
import javax.net.ssl.SSLPeerUnverifiedException; | ||
import java.security.cert.Certificate; | ||
import java.security.cert.X509Certificate; | ||
|
||
public class SSLEngineUtils { | ||
|
||
private SSLEngineUtils() {} | ||
|
||
public static void extractClientCertificates(Logger logger, ThreadContext threadContext, HttpChannel httpChannel) { | ||
SSLEngine sslEngine = getSSLEngine(httpChannel); | ||
extract(logger, threadContext, sslEngine, httpChannel); | ||
} | ||
|
||
public static void extractClientCertificates(Logger logger, ThreadContext threadContext, TcpChannel tcpChannel) { | ||
SSLEngine sslEngine = getSSLEngine(tcpChannel); | ||
extract(logger, threadContext, sslEngine, tcpChannel); | ||
} | ||
|
||
public static SSLEngine getSSLEngine(HttpChannel httpChannel) { | ||
if (httpChannel instanceof Netty4HttpChannel) { | ||
Channel nettyChannel = ((Netty4HttpChannel) httpChannel).getNettyChannel(); | ||
SslHandler handler = nettyChannel.pipeline().get(SslHandler.class); | ||
assert handler != null : "Must have SslHandler"; | ||
return handler.engine(); | ||
} else if (httpChannel instanceof NioHttpChannel) { | ||
SocketChannelContext context = ((NioHttpChannel) httpChannel).getContext(); | ||
assert context instanceof SSLChannelContext : "Must be SSLChannelContext.class, found: " + context.getClass(); | ||
return ((SSLChannelContext) context).getSSLEngine(); | ||
} else { | ||
throw new AssertionError("Unknown channel class type: " + httpChannel.getClass()); | ||
} | ||
} | ||
|
||
public static SSLEngine getSSLEngine(TcpChannel tcpChannel) { | ||
if (tcpChannel instanceof Netty4TcpChannel) { | ||
Channel nettyChannel = ((Netty4TcpChannel) tcpChannel).getNettyChannel(); | ||
SslHandler handler = nettyChannel.pipeline().get(SslHandler.class); | ||
assert handler != null : "Must have SslHandler"; | ||
return handler.engine(); | ||
} else if (tcpChannel instanceof NioTcpChannel) { | ||
SocketChannelContext context = ((NioTcpChannel) tcpChannel).getContext(); | ||
assert context instanceof SSLChannelContext : "Must be SSLChannelContext.class, found: " + context.getClass(); | ||
return ((SSLChannelContext) context).getSSLEngine(); | ||
} else { | ||
throw new AssertionError("Unknown channel class type: " + tcpChannel.getClass()); | ||
} | ||
} | ||
|
||
private static void extract(Logger logger, ThreadContext threadContext, SSLEngine sslEngine, Object channel) { | ||
try { | ||
Certificate[] certs = sslEngine.getSession().getPeerCertificates(); | ||
if (certs instanceof X509Certificate[]) { | ||
threadContext.putTransient(PkiRealm.PKI_CERT_HEADER_NAME, certs); | ||
} | ||
} catch (SSLPeerUnverifiedException e) { | ||
// this happens when client authentication is optional and the client does not provide credentials. If client | ||
// authentication was required then this connection should be closed before ever getting into this class | ||
assert sslEngine.getNeedClientAuth() == false; | ||
assert sslEngine.getWantClientAuth(); | ||
if (logger.isTraceEnabled()) { | ||
logger.trace( | ||
(Supplier<?>) () -> new ParameterizedMessage( | ||
"SSL Peer did not present a certificate on channel [{}]", channel), e); | ||
} else if (logger.isDebugEnabled()) { | ||
logger.debug("SSL Peer did not present a certificate on channel [{}]", channel); | ||
} | ||
} | ||
} | ||
} |
64 changes: 64 additions & 0 deletions
64
...rc/main/java/org/elasticsearch/xpack/security/transport/SecurityHttpExceptionHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
package org.elasticsearch.xpack.security.transport; | ||
|
||
import org.apache.logging.log4j.Logger; | ||
import org.apache.logging.log4j.message.ParameterizedMessage; | ||
import org.elasticsearch.common.component.Lifecycle; | ||
import org.elasticsearch.common.network.CloseableChannel; | ||
import org.elasticsearch.http.HttpChannel; | ||
|
||
import java.util.function.BiConsumer; | ||
|
||
import static org.elasticsearch.xpack.core.security.transport.SSLExceptionHelper.isCloseDuringHandshakeException; | ||
import static org.elasticsearch.xpack.core.security.transport.SSLExceptionHelper.isNotSslRecordException; | ||
import static org.elasticsearch.xpack.core.security.transport.SSLExceptionHelper.isReceivedCertificateUnknownException; | ||
|
||
public final class SecurityHttpExceptionHandler implements BiConsumer<HttpChannel, Exception> { | ||
|
||
private final Lifecycle lifecycle; | ||
private final Logger logger; | ||
private final BiConsumer<HttpChannel, Exception> fallback; | ||
|
||
public SecurityHttpExceptionHandler(Logger logger, Lifecycle lifecycle, BiConsumer<HttpChannel, Exception> fallback) { | ||
this.lifecycle = lifecycle; | ||
this.logger = logger; | ||
this.fallback = fallback; | ||
} | ||
|
||
public void accept(HttpChannel channel, Exception e) { | ||
if (!lifecycle.started()) { | ||
return; | ||
} | ||
|
||
if (isNotSslRecordException(e)) { | ||
if (logger.isTraceEnabled()) { | ||
logger.trace(new ParameterizedMessage("received plaintext http traffic on a https channel, closing connection {}", | ||
channel), e); | ||
} else { | ||
logger.warn("received plaintext http traffic on a https channel, closing connection {}", channel); | ||
} | ||
CloseableChannel.closeChannel(channel); | ||
} else if (isCloseDuringHandshakeException(e)) { | ||
if (logger.isTraceEnabled()) { | ||
logger.trace(new ParameterizedMessage("connection {} closed during ssl handshake", channel), e); | ||
} else { | ||
logger.warn("connection {} closed during ssl handshake", channel); | ||
} | ||
CloseableChannel.closeChannel(channel); | ||
} else if (isReceivedCertificateUnknownException(e)) { | ||
if (logger.isTraceEnabled()) { | ||
logger.trace(new ParameterizedMessage("http client did not trust server's certificate, closing connection {}", | ||
channel), e); | ||
} else { | ||
logger.warn("http client did not trust this server's certificate, closing connection {}", channel); | ||
} | ||
CloseableChannel.closeChannel(channel); | ||
} else { | ||
fallback.accept(channel, e); | ||
} | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
...curity/src/main/java/org/elasticsearch/xpack/security/transport/SecurityHttpSettings.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
package org.elasticsearch.xpack.security.transport; | ||
|
||
import org.elasticsearch.common.settings.Settings; | ||
|
||
import static org.elasticsearch.http.HttpTransportSettings.SETTING_HTTP_COMPRESSION; | ||
import static org.elasticsearch.xpack.core.XPackSettings.HTTP_SSL_ENABLED; | ||
|
||
public final class SecurityHttpSettings { | ||
|
||
private SecurityHttpSettings() {} | ||
|
||
public static void overrideSettings(Settings.Builder settingsBuilder, Settings settings) { | ||
if (HTTP_SSL_ENABLED.get(settings) && SETTING_HTTP_COMPRESSION.exists(settings) == false) { | ||
settingsBuilder.put(SETTING_HTTP_COMPRESSION.getKey(), false); | ||
} | ||
} | ||
} |
Oops, something went wrong.