This chapter describes how to secure the cluster communication between server instances.
The security solution for cluster communication is based on standard SSL/TLS technology (referred to jointly as SSL). Encryption is in fact just one aspect of security, with the other cornerstones being authentication and integrity. A secure solution will be based on a key infrastructure which is deployed together with a requirement of authentication.
The SSL support in the platform is documented in detail in Section 7.3, “Unified SSL framework”. This section will cover the specifics as they relate to securing a cluster.
Under SSL, an endpoint can authenticate itself using certificates managed by a Public Key Infrastructure (PKI).
Deploying a secure key management infrastructure is beyond the scope of this manual, and should be entrusted to experienced security professionals. The example deployment illustrated below is for reference purposes only, and any particular suggestions should be regarded as advisory.
The following steps will create an example deployment, and each step is expanded in further detail below.
The generation of cryptographic objects is for the most part outside the scope of this manual. It will generally require having a PKI with a Certificate Authority (CA) within the organization and they should be able to advise here. Please note that the information in this manual relating to the PKI is mainly for illustrative purposes.
When the certificates and private keys have been obtained they can be installed on each of the servers.
Each server will have a certificate of its own, signed by a CA, and the corresponding private key.
The certificate of the CA is installed into the
trusted directory, and any certificate signed by the CA will thus be trusted.
This means that the server now has the capability of establishing trust with other servers.
In this example we will deploy a mutual authentication setup, which means that both ends of a channel have to authenticate.
To enable mutual authentication the SSL policy must have
client_auth set to
REQUIRE (which is the default).
Servers are by default required to authenticate themselves, so there is no corresponding server setting.
Neo4j is able to generate self-signed certificates but a deployment using these should generally be regarded as a special case. It can make sense in some circumstances and even a mutual authenticated setup can be created by sharing the self-generated certificates among instances.
If the certificate for a particular server is compromised it is possible to revoke it by installing a Certificate Revocation List (CRL) in the
It is also possible to redeploy using a new CA.
For contingency purposes, it is advised that you have a separate intermediate CA specifically for the cluster which can be
substituted in its entirety should it ever become necessary.
This approach would be much easier than having to handle revocations and ensuring their propagation.
In this example we assume a plan to name the SSL policy
cluster, and that the private key and certificate file are named cluster01.key and cluster01.crt, respectively.
We want to use the default configuration for this server so we create the appropriate directory structure and install the
$neo4j-home> mkdir certificates/cluster $neo4j-home> mkdir certificates/cluster/trusted $neo4j-home> mkdir certificates/cluster/revoked $neo4j-home> cp $some-dir/cluster01.key certificates/cluster $neo4j-home> cp $some-dir/cluster01.crt certificates/cluster
An SSL policy utilizes the installed cryptographic objects and additionally allows parameters to be configured. We will use the following parameters in our configuraion:
Setting this to
We can enforce a particular single strong cipher and remove any doubt about which cipher gets negotiated and chosen. The cipher chosen above offers Perfect Forward Secrecy (PFS) which is generally desirable. It also uses Advanced Encryption Standard (AES) for symmetric encryption which has great support for acceleration in hardware and thus allows performance to generally be negligibly affected.
Since we control the entire cluster we can enforce the latest TLS standard without any concern for backwards compatibility. It has no known security vulnerabilities and uses the most modern algorithms for key exchanges, etc.
In the following example we will create and configure an SSL policy that we will use in our cluster.
In this example we assume that the directory structure has been created, and certificate files have been installed, as per
the previous example.
We wish to create a cluster SSL policy called
We do this by defining the following parameter.
Since our policy is named
cluster the corresponding settings will be available to configure under the
We add the following content to our neo4j.conf file:
dbms.ssl.policy.cluster.tls_versions=TLSv1.2 dbms.ssl.policy.cluster.ciphers=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 dbms.ssl.policy.cluster.client_auth=REQUIRE
Note that the policy must be configured on every server with the same settings. The actual cryptographic objects installed will be mostly different since they do not share the same private keys and corresponding certificates. The trusted CA certificate will be shared however.
By default, the causal cluster will not put any SSL policy into effect, meaning that communication is then unencrypted.
causal_clustering.ssl_policy to the name of a previously created SSL policy we can mandate its use.
In this example we assume that the tasks in the previous two examples have been performed.
We now configure our cluster to use the SSL policy that we have named
Any user data communicated between instances will now be secured. Please note, that an instance which is not correctly setup would not be able to communicate with the others.
To make sure that everything is secured as intended it makes sense to validate using external tooling such as, for example,
the open source assessment tools
In this example we will use the
nmap tool to validate the secure operation of our cluster.
A simple test to perform is a cipher enumeration using the following command:
nmap --script ssl-enum-ciphers -p <port> <hostname>
The hostname and port have to be adjusted according to our configuration. This can prove that TLS is in fact enabled and that the only the intended cipher suites are enabled. All servers and all applicable ports should be tested.
For testing purposes we could also attempt to utilize a separate testing instance of Neo4j which, for example, has an untrusted certificate in place. The expected result of this test is that the test server is not able to participate in replication of user data. The debug logs will generally indicate an issue by printing an SSL or certificate-related exception.
The above example uses strong cryptography which might need to be specifically enabled on your Java platform. See for example: http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html