Integrating OpenSSL
Hazelcast IMDG Enterprise
NOTE: You cannot integrate OpenSSL into Hazelcast when Hazelcast Encryption is enabled.
NOTE: You currently cannot use OpenSSL integration with Hazelcast when using IBM JDK.
TLS/SSL in Java is normally provided by the JRE. However, the performance overhead can be significant; even with AES intrensics enabled. If you are using Linux, Hazelcast provides OpenSSL integration for TLS/SSL which can provide significant performance improvements.
OpenSSL can be used on clients and/or members. For best performance, it is recommended to install on a client and member, and configure the appropriate cipher suite(s).
Integrating OpenSSL into Hazelcast is achieved with the following steps:
- Installing OpenSSL
- Configuring Hazelcast to use OpenSSL
- Configuring Cipher Suites
Below sections explain these steps.
Installing OpenSSL
Install OpenSSL. Make sure that you are installing 1.0.1 or a newer release. Please refer to its documentation at github.com/openssl.
On the major distributions, OpenSSL is installed by default. Make sure the OpenSSL version is not suffering from the Heartbleed Bug.
Apache Portable Runtime library
Install Apache Portable Runtime library. Please refer to apr.apache.org.
For RHEL:
sudo yum -y install apr
For Ubuntu:
sudo apt-get -y install libapr1
Netty Libraries
For the OpenSSL integration in Java, the Netty library is used.
Make sure the following libraries from the Netty framework are on the classpath:
-
netty-buffer-4.1.8.Final.jar
-
netty-codec-4.1.8.Final.jar
-
netty-common-4.1.8.Final.jar
-
netty-buffer-4.1.8.Final.jar
-
netty-resolver-4.1.8.Final.jar
-
netty-transport-4.1.8.Final.jar
-
netty-tcnative-boringssl-static-1.1.33.Fork26-linux-x86_64.jar
For a Maven based project, the following snippet adds the JARs.
<dependencies>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-tcnative-boringssl-static</artifactId>
<version>1.1.33.Fork26</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-buffer</artifactId>
<version>4.1.8.Final</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-codec</artifactId>
<version>4.1.8.Final</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-common</artifactId>
<version>4.1.8.Final</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-handler</artifactId>
<version>4.1.8.Final</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-resolver</artifactId>
<version>4.1.8.Final</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport</artifactId>
<version>4.1.8.Final</version>
</dependency>
...
</dependencies>
Configuring Hazelcast for OpenSSL
Configuring OpenSSL in Hazelcast is straight forward. On the client and/or member side, the following snippet enables TLS/SSL using OpenSSL:
<network>
...
<ssl enabled="true">
<factory-class-name>com.hazelcast.nio.ssl.OpenSSLEngineFactory</factory-class-name>
<properties>
<property name="keyStore">hazelcast.keystore</property>
<property name="keyStorePassword">123456</property>
<property name="keyManagerAlgorithm">SunX509</property>
<property name="trustManagerAlgorithm">SunX509</property>
<property name="trustStore">hazelcast.truststore</property>
<property name="trustStorePassword">123456</property>
<property name="protocol">TLSv1.2</property>
</properties>
</ssl>
...
</network>
The configuration is almost the same as regular TLS/SSL integration. The main difference is the OpenSSLEngineFactory
factory class.
Here are the descriptions for the properties:
-
keystore
: Path of your keystore file. Note that your keystore's type must beJKS
. -
keyStorePassword
: Password to access the key from your keystore file. -
keyManagerAlgorithm
: Name of the algorithm based on which the authentication keys are provided. -
trustManagerAlgorithm
: Name of the algorithm based on which the trust managers are provided. -
truststore
: Path of your truststore file. The file truststore is a keystore file that contains a collection of certificates trusted by your application. Its type should beJKS
. -
trustStorePassword
: Password to unlock the truststore file. -
protocol
: Name of the algorithm which is used in your TLS/SSL. Its default value isTLS
. Available values are:- SSL
- SSLv2
- SSLv3
- TLS
- TLSv1
- TLSv1.1
- TLSv1.2
All of the above algorithms support Java 6 and higher versions, except the TLSv1.2 supports Java 7 and higher versions. For
the protocol
property, we recommend you to provide SSL or TLS with its version information, e.g., TLSv1.2
. Note that if you
configure only SSL
or TLS
, it will be converted to SSLv3
and TLSv1.2
.
Configuring Cipher Suites
To get the best performance out of OpenSSL, the correct cipher suites need to be configured. Each cipher suite has different performance and security characteristics and depending on the hardware and selected cipher suite, the overhead of TLS can range from dramatic to almost negligible.
The cipher suites are configured using the ciphersuites
property as shown below:
<ssl enabled="true">
<factory-class-name>com.hazelcast.nio.ssl.OpenSSLEngineFactory</factory-class-name>
<properties>
<property name="keyStore">upload/hazelcast.keystore</property>
...
...
...
<property name="ciphersuites">TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA</property>
</properties>
</ssl>
The ciphersuites
property accepts a comma separated list (spaces, enters, tabs are filtered out) of cipher suites in the order
of preference.
You can configure a member and client with different cipher suites; but there should be at least one shared cipher suite.
One of the cipher suites that gave very low overhead but still provides solid security is the 'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256'. However in our measurements this cipher suite only performs well using OpenSSL; using the regular Java TLS integration, it performs badly. So keep that in mind when configuring a client using regular SSL and a member using OpenSSL.
Please check with your security expert to determine which cipher suites are appropriate and run performance tests to see which ones perform well in your environment.
If you don't configure the cipher suites, then both client and/or member will determine a cipher suite by themselves during the TLS/SSL handshake. This can lead to suboptimal performance and lower security than required.
Other Ways of Configuring Properties
You can set all the properties presented in this section using the javax.net.ssl
prefix, e.g., javax.net.ssl.keyStore
and javax.net.ssl.keyStorePassword
.
Also note that these properties can be specified using the related Java system properties and also Java's -D
command line
option. This is very useful if you require a more flexible configuration e.g. when doing performance tests.
See below examples equivalent to each other:
System.setProperty("javax.net.ssl.trustStore", "/user/home/hazelcast.ts");
Or,
-Djavax.net.ssl.trustStore=/user/home/hazelcast.ts
Another two examples equivalent to each other:
System.setProperty("javax.net.ssl.ciphersuites", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA");
Or,
-Djavax.net.ssl.ciphersuites=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA