From af619302fe9f67be76b98be608e559526955ab67 Mon Sep 17 00:00:00 2001 From: Karol Bucek Date: Tue, 26 Jan 2021 13:30:37 +0100 Subject: [PATCH] Feat: log + unwrap generic SSL context exceptions (#405) The unwrapping at the Java level is for exceptions wrapped by Netty. These exceptions as they are are rather useless (unless they're properly logged with a cause's printStackTrace), and since we're pretty much type-less Ruby on the layer above we should rather propagate the cause ... Full exception details will be logged at debug level from the Java side - since we seem to prefer (manual) exception logging at the plugin level. We also make sure to log cause, if any, on the Ruby side which now catches all (expected) Java exceptions. --- CHANGELOG.md | 3 +++ VERSION | 2 +- lib/logstash/inputs/beats.rb | 7 ++++++- .../org/logstash/netty/SslContextBuilder.java | 20 +++++++++++++++++-- 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81e21f0a..f011f669 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 6.0.14 + - Feat: log + unwrap generic SSL context exceptions [#405](https://github.com/logstash-plugins/logstash-input-beats/pull/405) + ## 6.0.13 - [DOC] Update links to use shared attributes diff --git a/VERSION b/VERSION index dd6bb261..eabfd97e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.0.13 +6.0.14 diff --git a/lib/logstash/inputs/beats.rb b/lib/logstash/inputs/beats.rb index 9f491e44..36817798 100644 --- a/lib/logstash/inputs/beats.rb +++ b/lib/logstash/inputs/beats.rb @@ -220,7 +220,7 @@ def new_ssl_handshake_provider(ssl_context_builder) rescue java.lang.IllegalArgumentException => e @logger.error("SSL configuration invalid", error_details(e)) raise LogStash::ConfigurationError, e - rescue java.security.GeneralSecurityException => e + rescue java.lang.Exception => e # java.security.GeneralSecurityException @logger.error("SSL configuration failed", error_details(e, true)) raise e end @@ -254,6 +254,11 @@ def configuration_error(message) def error_details(e, trace = false) error_details = { :exception => e.class, :message => e.message } error_details[:backtrace] = e.backtrace if trace || @logger.debug? + cause = e.cause + if cause && e != cause + error_details[:cause] = { :exception => cause.class, :message => cause.message } + error_details[:cause][:backtrace] = cause.backtrace if trace || @logger.debug? + end error_details end diff --git a/src/main/java/org/logstash/netty/SslContextBuilder.java b/src/main/java/org/logstash/netty/SslContextBuilder.java index 92e64bc1..a65d1952 100644 --- a/src/main/java/org/logstash/netty/SslContextBuilder.java +++ b/src/main/java/org/logstash/netty/SslContextBuilder.java @@ -6,6 +6,7 @@ import org.apache.logging.log4j.Logger; import javax.crypto.Cipher; +import javax.net.ssl.SSLException; import javax.net.ssl.SSLServerSocketFactory; import java.io.File; import java.io.FileInputStream; @@ -141,7 +142,7 @@ public File getSslCertificateFile() { return sslCertificateFile; } - public SslContext buildContext() throws IOException, CertificateException { + public SslContext buildContext() throws Exception { io.netty.handler.ssl.SslContextBuilder builder = io.netty.handler.ssl.SslContextBuilder.forServer(sslCertificateFile, sslKeyFile, passPhrase); if (logger.isDebugEnabled()) { @@ -167,7 +168,22 @@ public SslContext buildContext() throws IOException, CertificateException { builder.clientAuth(ClientAuth.NONE); } builder.protocols(protocols); - return builder.build(); + + try { + return builder.build(); + } catch (SSLException e) { + logger.debug("Failed to initialize SSL", e); + // unwrap generic wrapped exception from Netty's JdkSsl{Client|Server}Context + if ("failed to initialize the server-side SSL context".equals(e.getMessage()) || + "failed to initialize the client-side SSL context".equals(e.getMessage())) { + // Netty catches Exception and simply wraps: throw new SSLException("...", e); + if (e.getCause() instanceof Exception) throw (Exception) e.getCause(); + } + throw e; + } catch (Exception e) { + logger.debug("Failed to initialize SSL", e); + throw e; + } } private X509Certificate[] loadCertificateCollection(String[] certificates) throws IOException, CertificateException {