gravitee-io / issues

Gravitee.io - API Platform - Issues
64 stars 26 forks source link

Gateway/Docker: Cannot support TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 with currently installed providers #1399

Closed MehrCurry closed 6 years ago

MehrCurry commented 6 years ago

After upgrading to 1.18.0 calling the an API via the gateway gives me an 504 error.

The gateway log shows: Cannot support TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 with currently installed providers

local_mongodb_1        | 2018-07-19T06:40:24.309+0000 I NETWORK  [conn12] received client metadata from 172.18.0.6:51400 conn12: { driver: { name: "mongo-java-driver", version: "3.6.3" }, os: { type: "Linux", name: "Linux", architecture: "amd64", version: "3.10.0-862.3.2.el7.x86_64" }, platform: "Java/Oracle Corporation/1.8.0_162-b12" }
local_gateway_1        | 06:41:16.638 [vert.x-eventloop-thread-0] [] WARN  io.netty.channel.ChannelInitializer - Failed to initialize a channel. Closing: [id: 0xbf7ebaba]
local_gateway_1        | java.lang.IllegalArgumentException: Cannot support TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 with currently installed providers
local_gateway_1        |    at sun.security.ssl.CipherSuiteList.<init>(CipherSuiteList.java:81)
local_gateway_1        |    at sun.security.ssl.SSLEngineImpl.setEnabledCipherSuites(SSLEngineImpl.java:2038)
local_gateway_1        |    at io.netty.handler.ssl.JdkSslContext.configureAndWrapEngine(JdkSslContext.java:225)

Expected Behavior

With Version 1.15.x i got a normal API response from the backend.

Current Behavior

After #1363 has been fixed i upgraded all containers with docker-compose pull.

When i call my APIs through the gateway i receive an error.

< HTTP/1.1 504 Gateway Timeout
< X-Gravitee-Transaction-Id: b9e4c415-640a-4d85-a4c4-15640acd85f9
< Connection: close
< Content-Length: 0

Possible Solution

The may be caused by the limited JCE version in the oracle JDK. Perhaps you can use OpenJDK for your base image or add the full JCE to the base image with might not be possible due to licence issues.

See: https://support.datastax.com/hc/en-us/articles/204226129-Receiving-error-Caused-by-java-lang-IllegalArgumentException-Cannot-support-TLS-RSA-WITH-AES-256-CBC-SHA-with-currently-installed-providers-on-DSE-startup-after-setting-up-client-to-node-encryption

Steps to Reproduce (for bugs)

  1. Use docker-compose pull to use the latest versions
  2. Create an echo API as in #1363
  3. send a request with curl.

Context

Your Environment

[root@apigw gravitee]# docker images
REPOSITORY                                      TAG                 IMAGE ID            CREATED             SIZE
mongo                                           3.4                 aeb37fe6c489        2 days ago          361MB
graviteeio/management-ui                        latest              d983a7d05a49        7 days ago          82.6MB
graviteeio/management-api                       latest              b987cfa28e74        7 days ago          364MB
graviteeio/gateway                              latest              cbb94b9a6aa9        7 days ago          354MB
graviteeio/management-ui                        <none>              e6c873a817dc        2 weeks ago         81.4MB
graviteeio/management-api                       <none>              c8443b8fb01b        2 weeks ago         353MB
graviteeio/gateway                              <none>              75d18ee96461        2 weeks ago         342MB
mongo                                           <none>              f34ffcaa0056        3 weeks ago         361MB
portainer/portainer                             latest              7afb7abcfe5f        3 weeks ago         57MB
docker.elastic.co/elasticsearch/elasticsearch   5.4.3               2ae8547160a7        12 months ago       548MB
[root@apigw gravitee]# docker version
Client:
 Version:      18.03.1-ce
 API version:  1.37
 Go version:   go1.9.5
 Git commit:   9ee9f40
 Built:        Thu Apr 26 07:20:16 2018
 OS/Arch:      linux/amd64
 Experimental: false
 Orchestrator: swarm

Server:
 Engine:
  Version:      18.03.1-ce
  API version:  1.37 (minimum version 1.12)
  Go version:   go1.9.5
  Git commit:   9ee9f40
  Built:        Thu Apr 26 07:23:58 2018
  OS/Arch:      linux/amd64
  Experimental: false

Java Version inside Gateway Container:

bash-4.4$ java -version
java version "1.8.0_162"
Java(TM) SE Runtime Environment (build 1.8.0_162-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, mixed mode)
MehrCurry commented 6 years ago

I have written a small program to show with ciphers are supported inside the container, copied from https://stackoverflow.com/questions/48934210/java-ssl-error-cannot-support-tls-ecdhe-rsa-with-aes-256-gcm-sha384

import javax.net.ssl.SSLServerSocketFactory;
import java.util.Map;
import java.util.TreeMap;

public class SecurityListings {
    public static void main(String[] args) {
        SSLServerSocketFactory ssf = (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();

        TreeMap<String, Boolean> ciphers = new TreeMap<>();
        for (String cipher : ssf.getSupportedCipherSuites())
            ciphers.put(cipher, Boolean.FALSE);
        for (String cipher : ssf.getDefaultCipherSuites())
            ciphers.put(cipher, Boolean.TRUE);

        System.out.println("Default Cipher");
        for (Map.Entry<String, Boolean> cipher : ciphers.entrySet())
            System.out.printf("   %-5s%s%n", (cipher.getValue() ? '*' : ' '), cipher.getKey());
    }
}

When executing inside the gateway container:

Default Cipher
   *    SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
        SSL_DHE_DSS_WITH_DES_CBC_SHA
   *    SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
        SSL_DHE_RSA_WITH_DES_CBC_SHA
        SSL_DH_anon_WITH_3DES_EDE_CBC_SHA
        SSL_DH_anon_WITH_DES_CBC_SHA
   *    SSL_RSA_WITH_3DES_EDE_CBC_SHA
        SSL_RSA_WITH_DES_CBC_SHA
        SSL_RSA_WITH_NULL_MD5
        SSL_RSA_WITH_NULL_SHA
   *    TLS_DHE_DSS_WITH_AES_128_CBC_SHA
   *    TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
   *    TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
   *    TLS_DHE_DSS_WITH_AES_256_CBC_SHA
   *    TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
   *    TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
   *    TLS_DHE_RSA_WITH_AES_128_CBC_SHA
   *    TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
   *    TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
   *    TLS_DHE_RSA_WITH_AES_256_CBC_SHA
   *    TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
   *    TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
        TLS_DH_anon_WITH_AES_128_CBC_SHA
        TLS_DH_anon_WITH_AES_128_CBC_SHA256
        TLS_DH_anon_WITH_AES_128_GCM_SHA256
        TLS_DH_anon_WITH_AES_256_CBC_SHA
        TLS_DH_anon_WITH_AES_256_CBC_SHA256
        TLS_DH_anon_WITH_AES_256_GCM_SHA384
   *    TLS_EMPTY_RENEGOTIATION_INFO_SCSV
        TLS_KRB5_WITH_3DES_EDE_CBC_MD5
        TLS_KRB5_WITH_3DES_EDE_CBC_SHA
        TLS_KRB5_WITH_DES_CBC_MD5
        TLS_KRB5_WITH_DES_CBC_SHA
   *    TLS_RSA_WITH_AES_128_CBC_SHA
   *    TLS_RSA_WITH_AES_128_CBC_SHA256
   *    TLS_RSA_WITH_AES_128_GCM_SHA256
   *    TLS_RSA_WITH_AES_256_CBC_SHA
   *    TLS_RSA_WITH_AES_256_CBC_SHA256
   *    TLS_RSA_WITH_AES_256_GCM_SHA384
        TLS_RSA_WITH_NULL_SHA256

But when executing inside openjdk:8 container you will see:

Default Cipher
        SSL_DHE_DSS_WITH_DES_CBC_SHA
        SSL_DHE_RSA_WITH_DES_CBC_SHA
        SSL_DH_anon_WITH_DES_CBC_SHA
        SSL_RSA_WITH_DES_CBC_SHA
        SSL_RSA_WITH_NULL_MD5
        SSL_RSA_WITH_NULL_SHA
   *    TLS_DHE_DSS_WITH_AES_128_CBC_SHA
   *    TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
   *    TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
   *    TLS_DHE_DSS_WITH_AES_256_CBC_SHA
   *    TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
   *    TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
   *    TLS_DHE_RSA_WITH_AES_128_CBC_SHA
   *    TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
   *    TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
   *    TLS_DHE_RSA_WITH_AES_256_CBC_SHA
   *    TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
   *    TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
        TLS_DH_anon_WITH_AES_128_CBC_SHA
        TLS_DH_anon_WITH_AES_128_CBC_SHA256
        TLS_DH_anon_WITH_AES_128_GCM_SHA256
        TLS_DH_anon_WITH_AES_256_CBC_SHA
        TLS_DH_anon_WITH_AES_256_CBC_SHA256
        TLS_DH_anon_WITH_AES_256_GCM_SHA384
   *    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
   *    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
   *    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
   *    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
   *    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
   *    TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
        TLS_ECDHE_ECDSA_WITH_NULL_SHA
   *    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
   *    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
   *    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
   *    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
   *    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
   *    TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
        TLS_ECDHE_RSA_WITH_NULL_SHA
   *    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
   *    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
   *    TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
   *    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
   *    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
   *    TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
        TLS_ECDH_ECDSA_WITH_NULL_SHA
   *    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
   *    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
   *    TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
   *    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
   *    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
   *    TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
        TLS_ECDH_RSA_WITH_NULL_SHA
        TLS_ECDH_anon_WITH_AES_128_CBC_SHA
        TLS_ECDH_anon_WITH_AES_256_CBC_SHA
        TLS_ECDH_anon_WITH_NULL_SHA
   *    TLS_EMPTY_RENEGOTIATION_INFO_SCSV
        TLS_KRB5_WITH_DES_CBC_MD5
        TLS_KRB5_WITH_DES_CBC_SHA
   *    TLS_RSA_WITH_AES_128_CBC_SHA
   *    TLS_RSA_WITH_AES_128_CBC_SHA256
   *    TLS_RSA_WITH_AES_128_GCM_SHA256
   *    TLS_RSA_WITH_AES_256_CBC_SHA
   *    TLS_RSA_WITH_AES_256_CBC_SHA256
   *    TLS_RSA_WITH_AES_256_GCM_SHA384
        TLS_RSA_WITH_NULL_SHA256
MehrCurry commented 6 years ago

After further drilling down the JDK is not causing the problem.

I tried some other versions:

MehrCurry commented 6 years ago

Perhaps caused by #1373 ?

brasseld commented 6 years ago

Yes it is because of #1373

We have to think about a way to include JCE in docker containers.

MehrCurry commented 6 years ago

So perhaps OpenJDK is the best option?

Might be changing the base image to

FROM openjdk:8-jre-alpine
MAINTAINER Gravitee Team <http://gravitee.io>

RUN mkdir /opt

# Define default command.
CMD ["java", "-version"]

will do the trick?

MehrCurry commented 6 years ago

I builded a gateway image based on openjdk and in works!

Even the imagesize is 30% smaller:

graviteeio/gateway                              latest              2216d12663d8        8 minutes ago       262MB
graviteeio/gateway                              openjdk             2216d12663d8        8 minutes ago       262MB
graviteeio/gateway                              1.18.0              cbb94b9a6aa9        7 days ago          354MB
graviteeio/gateway                              1.15.5              75d18ee96461        2 weeks ago         342MB
graviteeio/gateway                              1.17.0              443ea20218af        4 weeks ago         344MB
graviteeio/gateway                              1.16.4              3a80922710f4        5 weeks ago         344MB

Any reason why we should use Oracle JDK?

MehrCurry commented 6 years ago

BTW: The new Oracle licensing policy for the JDK seems another good reasen to go to OpenJDK

https://dev.karakun.com/java/2018/06/25/java-releases.html

brasseld commented 6 years ago

Thanks for sharing @MehrCurry

We really have to consider it asap !

MehrCurry commented 6 years ago

There is a PR for the change in gateway-docker.

brasseld commented 6 years ago

Yes, I see, I'm waiting for approval from other contributors.

brasseld commented 6 years ago

Closed by https://github.com/gravitee-io/gravitee-docker/commit/8cd3a0223349bb3118fc5cf619765f0c374782c0