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 {