Reduce spamming of logs on common SSL exceptions (elastic/x-pack-elasticsearch#1083)

This commit reduces spamming of the logs when a common SSL exception is encountered such as a
client not trusting the server's certificate or a plaintext request sent to a channel that expects
TLS traffic.

relates elastic/x-pack-elasticsearch#1062

Original commit: elastic/x-pack-elasticsearch@94959e79f6
This commit is contained in:
Jay Modi 2017-04-24 07:51:24 -04:00 committed by GitHub
parent f063af9ee3
commit 1c1837fddd
3 changed files with 57 additions and 9 deletions

View File

@ -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());
}
}

View File

@ -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 {

View File

@ -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;