diff --git a/plugin/src/main/java/org/elasticsearch/xpack/security/transport/SSLExceptionHelper.java b/plugin/src/main/java/org/elasticsearch/xpack/security/transport/SSLExceptionHelper.java index 697d1e78c3e..81d552f7ce5 100644 --- a/plugin/src/main/java/org/elasticsearch/xpack/security/transport/SSLExceptionHelper.java +++ b/plugin/src/main/java/org/elasticsearch/xpack/security/transport/SSLExceptionHelper.java @@ -6,6 +6,7 @@ package org.elasticsearch.xpack.security.transport; +import io.netty.handler.codec.DecoderException; import io.netty.handler.ssl.NotSslRecordException; import javax.net.ssl.SSLException; @@ -24,4 +25,10 @@ public class SSLExceptionHelper { && e.getCause() == null && "Received close_notify during handshake".equals(e.getMessage()); } + + public static boolean isReceivedCertificateUnknownException(Throwable e) { + return e instanceof DecoderException + && e.getCause() instanceof SSLException + && "Received fatal alert: certificate_unknown".equals(e.getCause().getMessage()); + } } diff --git a/plugin/src/main/java/org/elasticsearch/xpack/security/transport/netty4/SecurityNetty4HttpServerTransport.java b/plugin/src/main/java/org/elasticsearch/xpack/security/transport/netty4/SecurityNetty4HttpServerTransport.java index 24e89cac4c6..2cbb8245f75 100644 --- a/plugin/src/main/java/org/elasticsearch/xpack/security/transport/netty4/SecurityNetty4HttpServerTransport.java +++ b/plugin/src/main/java/org/elasticsearch/xpack/security/transport/netty4/SecurityNetty4HttpServerTransport.java @@ -10,13 +10,11 @@ import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.ssl.SslHandler; import org.apache.logging.log4j.message.ParameterizedMessage; -import org.apache.logging.log4j.util.Supplier; import org.elasticsearch.common.network.NetworkService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.BigArrays; import org.elasticsearch.common.xcontent.NamedXContentRegistry; import org.elasticsearch.http.netty4.Netty4HttpServerTransport; -import org.elasticsearch.rest.RestController; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.netty4.Netty4Utils; import org.elasticsearch.xpack.ssl.SSLService; @@ -28,6 +26,7 @@ import static org.elasticsearch.http.HttpTransportSettings.SETTING_HTTP_COMPRESS import static org.elasticsearch.xpack.security.transport.SSLExceptionHelper.isCloseDuringHandshakeException; import static org.elasticsearch.xpack.security.transport.SSLExceptionHelper.isNotSslRecordException; import static org.elasticsearch.xpack.XPackSettings.HTTP_SSL_ENABLED; +import static org.elasticsearch.xpack.security.transport.SSLExceptionHelper.isReceivedCertificateUnknownException; public class SecurityNetty4HttpServerTransport extends Netty4HttpServerTransport { @@ -53,20 +52,25 @@ public class SecurityNetty4HttpServerTransport extends Netty4HttpServerTransport if (isNotSslRecordException(cause)) { if (logger.isTraceEnabled()) { - logger.trace( - (Supplier) () -> new ParameterizedMessage( - "received plaintext http traffic on a https channel, closing connection {}", - ctx.channel()), - cause); + logger.trace(new ParameterizedMessage("received plaintext http traffic on a https channel, closing connection {}", + ctx.channel()), cause); } else { logger.warn("received plaintext http traffic on a https channel, closing connection {}", ctx.channel()); } ctx.channel().close(); } else if (isCloseDuringHandshakeException(cause)) { if (logger.isTraceEnabled()) { - logger.trace((Supplier) () -> new ParameterizedMessage("connection {} closed during handshake", ctx.channel()), cause); + logger.trace(new ParameterizedMessage("connection {} closed during ssl handshake", ctx.channel()), cause); } else { - logger.warn("connection {} closed during handshake", ctx.channel()); + logger.warn("connection {} closed during ssl handshake", ctx.channel()); + } + ctx.channel().close(); + } else if (isReceivedCertificateUnknownException(cause)) { + if (logger.isTraceEnabled()) { + logger.trace(new ParameterizedMessage("http client did not trust server's certificate, closing connection {}", + ctx.channel()), cause); + } else { + logger.warn("http client did not trust this server's certificate, closing connection {}", ctx.channel()); } ctx.channel().close(); } else { diff --git a/plugin/src/main/java/org/elasticsearch/xpack/security/transport/netty4/SecurityNetty4Transport.java b/plugin/src/main/java/org/elasticsearch/xpack/security/transport/netty4/SecurityNetty4Transport.java index a22e1a6fb99..2dfded181ea 100644 --- a/plugin/src/main/java/org/elasticsearch/xpack/security/transport/netty4/SecurityNetty4Transport.java +++ b/plugin/src/main/java/org/elasticsearch/xpack/security/transport/netty4/SecurityNetty4Transport.java @@ -11,6 +11,7 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelOutboundHandlerAdapter; import io.netty.channel.ChannelPromise; import io.netty.handler.ssl.SslHandler; +import org.apache.logging.log4j.message.ParameterizedMessage; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.inject.internal.Nullable; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; @@ -29,6 +30,9 @@ import java.net.InetSocketAddress; import java.net.SocketAddress; import static org.elasticsearch.xpack.security.Security.setting; +import static org.elasticsearch.xpack.security.transport.SSLExceptionHelper.isCloseDuringHandshakeException; +import static org.elasticsearch.xpack.security.transport.SSLExceptionHelper.isNotSslRecordException; +import static org.elasticsearch.xpack.security.transport.SSLExceptionHelper.isReceivedCertificateUnknownException; /** @@ -68,6 +72,39 @@ public class SecurityNetty4Transport extends Netty4Transport { return new SecurityClientChannelInitializer(); } + @Override + protected void onException(Channel channel, Exception e) { + if (!lifecycle.started()) { + // just close and ignore - we are already stopped and just need to make sure we release all resources + disconnectFromNodeChannel(channel, e); + } else if (isNotSslRecordException(e)) { + if (logger.isTraceEnabled()) { + logger.trace( + new ParameterizedMessage("received plaintext traffic on an encrypted channel, closing connection {}", channel), e); + } else { + logger.warn("received plaintext traffic on an encrypted channel, closing connection {}", channel); + } + disconnectFromNodeChannel(channel, e); + } else if (isCloseDuringHandshakeException(e)) { + if (logger.isTraceEnabled()) { + logger.trace(new ParameterizedMessage("connection {} closed during ssl handshake", channel), e); + } else { + logger.warn("connection {} closed during handshake", channel); + } + disconnectFromNodeChannel(channel, e); + } else if (isReceivedCertificateUnknownException(e)) { + if (logger.isTraceEnabled()) { + logger.trace(new ParameterizedMessage("client did not trust server's certificate, closing connection {}", channel), e); + } else { + logger.warn("client did not trust this server's certificate, closing connection {}", channel); + } + disconnectFromNodeChannel(channel, e); + } else { + super.onException(channel, e); + } + + } + class SecurityServerChannelInitializer extends ServerChannelInitializer { private final Settings securityProfileSettings;