diff --git a/.ci/run.sh b/.ci/run.sh index a0ec21c9..2d9dc683 100755 --- a/.ci/run.sh +++ b/.ci/run.sh @@ -7,4 +7,4 @@ set -ex bundle exec rspec spec bundle exec rake test:integration:setup -bundle exec rspec spec --tag integration +bundle exec rspec spec --tag integration -fd diff --git a/CHANGELOG.md b/CHANGELOG.md index 7977d0c0..60075dcf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 6.0.11 + - Updated jackson databind and Netty dependencies. Additionally, this release removes the dependency on `tcnative` + + `boringssl`, using JVM supplied ciphers instead. This may result in fewer ciphers being available if the JCE + unlimited strength jurisdiction policy is not installed. (This policy is installed by default on versions of the + JDK from u161 onwards)[#393](https://github.com/logstash-plugins/logstash-input-beats/pull/393) + ## 6.0.10 - Added error handling to detect if ssl certificate or key files can't be read [#394](https://github.com/logstash-plugins/logstash-input-beats/pull/394) diff --git a/VERSION b/VERSION index c7d48f04..b619a5bf 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.0.10 +6.0.11 diff --git a/build.gradle b/build.gradle index cd84c799..84cb9211 100644 --- a/build.gradle +++ b/build.gradle @@ -14,7 +14,7 @@ sourceCompatibility = 1.8 targetCompatibility = 1.8 String jacksonVersion = '2.9.10' -String jacksonDatabindVersion = '2.9.10.1' +String jacksonDatabindVersion = '2.9.10.4' repositories { mavenCentral() @@ -24,9 +24,7 @@ dependencies { testCompile 'junit:junit:4.12' testCompile 'org.hamcrest:hamcrest-library:1.3' testCompile 'org.apache.logging.log4j:log4j-core:2.11.1' - - compile 'io.netty:netty-all:4.1.30.Final' - compile 'io.netty:netty-tcnative-boringssl-static:2.0.12.Final' + compile 'io.netty:netty-all:4.1.49.Final' compile 'org.javassist:javassist:3.24.0-GA' compile "com.fasterxml.jackson.core:jackson-core:${jacksonVersion}" compile "com.fasterxml.jackson.core:jackson-annotations:${jacksonVersion}" diff --git a/lib/logstash/inputs/beats.rb b/lib/logstash/inputs/beats.rb index 84f4a135..2ea87340 100644 --- a/lib/logstash/inputs/beats.rb +++ b/lib/logstash/inputs/beats.rb @@ -114,8 +114,7 @@ class LogStash::Inputs::Beats < LogStash::Inputs::Base config :tls_max_version, :validate => :number, :default => TLS.max.version # The list of ciphers suite to use, listed by priorities. - config :cipher_suites, :validate => :array, :default => org.logstash.netty.SslContextBuilder::DEFAULT_CIPHERS - + config :cipher_suites, :validate => :array, :default => org.logstash.netty.SslContextBuilder.getDefaultCiphers # Close Idle clients after X seconds of inactivity. config :client_inactivity_timeout, :validate => :number, :default => 60 diff --git a/spec/integration/filebeat_spec.rb b/spec/integration/filebeat_spec.rb index fdfada6d..64244985 100644 --- a/spec/integration/filebeat_spec.rb +++ b/spec/integration/filebeat_spec.rb @@ -166,8 +166,8 @@ end context "when the cipher is not supported" do - let(:beats_cipher) { "ECDHE-RSA-AES-128-GCM-SHA256" } - let(:logstash_cipher) { "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"} + let(:beats_cipher) { "ECDHE-RSA-AES-256-GCM-SHA384" } + let(:logstash_cipher) { "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"} include_examples "doesn't send events" end diff --git a/src/main/java/org/logstash/netty/SslContextBuilder.java b/src/main/java/org/logstash/netty/SslContextBuilder.java index b0bd945d..92e64bc1 100644 --- a/src/main/java/org/logstash/netty/SslContextBuilder.java +++ b/src/main/java/org/logstash/netty/SslContextBuilder.java @@ -1,16 +1,18 @@ package org.logstash.netty; import io.netty.handler.ssl.ClientAuth; -import io.netty.handler.ssl.OpenSsl; import io.netty.handler.ssl.SslContext; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import javax.crypto.Cipher; +import javax.net.ssl.SSLServerSocketFactory; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; +import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; @@ -40,9 +42,8 @@ public enum SslClientVerifyMode { /* Mordern Ciphers List from https://wiki.mozilla.org/Security/Server_Side_TLS - This list require the OpenSSl engine for netty. */ - public final static String[] DEFAULT_CIPHERS = new String[] { + private final static String[] DEFAULT_CIPHERS = new String[] { "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", @@ -53,6 +54,18 @@ public enum SslClientVerifyMode { "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256" }; + /* + Reduced set of ciphers available when JCE Unlimited Strength Jurisdiction Policy is not installed. + */ + private final static String[] DEFAULT_CIPHERS_LIMITED = new String[] { + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256" + }; + + private String[] supportedCiphers = ((SSLServerSocketFactory)SSLServerSocketFactory + .getDefault()).getSupportedCipherSuites(); private String[] ciphers = DEFAULT_CIPHERS; private String[] protocols = new String[] { "TLSv1.2" }; private String[] certificateAuthorities; @@ -79,10 +92,13 @@ public SslContextBuilder setProtocols(String[] protocols) { public SslContextBuilder setCipherSuites(String[] ciphersSuite) throws IllegalArgumentException { for(String cipher : ciphersSuite) { - if(!OpenSsl.isCipherSuiteAvailable(cipher)) { - throw new IllegalArgumentException("Cipher `" + cipher + "` is not available"); - } else { + if(Arrays.asList(supportedCiphers).contains(cipher)) { logger.debug("Cipher is supported: {}", cipher); + }else{ + if (!isUnlimitedJCEAvailable()) { + logger.warn("JCE Unlimited Strength Jurisdiction Policy not installed"); + } + throw new IllegalArgumentException("Cipher `" + cipher + "` is not available"); } } @@ -90,6 +106,23 @@ public SslContextBuilder setCipherSuites(String[] ciphersSuite) throws IllegalAr return this; } + public static String[] getDefaultCiphers(){ + if (isUnlimitedJCEAvailable()){ + return DEFAULT_CIPHERS; + } else { + logger.warn("JCE Unlimited Strength Jurisdiction Policy not installed - max key length is 128 bits"); + return DEFAULT_CIPHERS_LIMITED; + } + } + + public static boolean isUnlimitedJCEAvailable(){ + try { + return (Cipher.getMaxAllowedKeyLength("AES") > 128); + } catch (NoSuchAlgorithmException e) { + logger.warn("AES not available", e); + return false; + } + } public SslContextBuilder setCertificateAuthorities(String[] cert) { certificateAuthorities = cert; return this; @@ -112,7 +145,7 @@ public SslContext buildContext() throws IOException, CertificateException { io.netty.handler.ssl.SslContextBuilder builder = io.netty.handler.ssl.SslContextBuilder.forServer(sslCertificateFile, sslKeyFile, passPhrase); if (logger.isDebugEnabled()) { - logger.debug("Available ciphers: " + Arrays.toString(OpenSsl.availableOpenSslCipherSuites().toArray())); + logger.debug("Available ciphers: " + Arrays.toString(supportedCiphers)); logger.debug("Ciphers: " + Arrays.toString(ciphers)); }