A demonstration of IntraCluster SSL Encryption
This document provides a step-by-step demonstration of the process to deploy a Self-Signed SSL Certificate, to member instances of a Causal Cluster, aimed at achieving intra-cluster encryption. The steps can be outlined as:
-
Generate and install cryptographic objects
-
Create an SSL policy
-
Configure Causal Clustering with the SSL policy
-
Validate the secure operation of the cluster
These are further described in the Neo4j operations manual: https://neo4j.com/docs/operations-manual/current/clustering/intra-cluster-encryption/#intra-cluster-encryption-example-deployment
Lets go through the demonstration of creation, deployment and verification of the SSL certificate.
Install OpenSSL
A certificate can be signed by a trusted Certificate Authority (CA) or, as in this case, be a self-signed one. We will create a self-signed certificate using OpenSSL. We’ll first need to install OpenSSL in order to create a self-signed certificate.
Windows
OpenSSL can be installed using a Windows binary. Some sample binaries are available at the below links:
Linux
Many Linux distributions has OpenSSL installed. If this is not the case, use a package manager to install openssl, for example:
$ sudo apt-get install openssl
Mac
On OSX, OpenSSL can be installed using macports, as described here: https://www.macports.org/install.php
Or alternatively via homebrew package manager as below:
$ brew install openssl
Verify Installation
Once installed, the version and installation directory, amongst other installation features, can be checked by running brew info openssl
,
or openssl version -a
:
$ openssl version -a
LibreSSL 2.8.3
built on: date not available
platform: information not available
options: bn(64,64) rc4(16x,int) des(idx,cisc,16,int) blowfish(idx)
compiler: information not available
OPENSSLDIR: "/private/etc/ssl"
Create a Neo4j SSL Framework directory structure
Neo4j SSL Framework requires the following directory structure be created:
<NEO4J_HOME>/certificates
└── cluster
├── revoked
└── trusted
From <NEO4J_HOME> run the following commands to create the above structure:
---
$ mkdir certificates/cluster
$ mkdir certificates/cluster/trusted
$ mkdir certificates/cluster/revoked
---
Create the SSL Certificate and Key
Use the following command to create a certificate cert.pem
and a key key.pem
making sure to change xxx
to the number of days the certificates should be valid for:
$ sudo openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days XXX
or, for a relatively smaller key length:
$ sudo openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days XXX
Below describes each parameter used in the openssl command above:
-
req: PKCS#10 certificate request and certificate generating utility.
-
x509: outputs a self signed certificate instead of a certificate request.
-
newkey: creates a new certificate request and a new private key. Note the rsa:nbits, where nbits is the number of bits, generates an RSA key nbits in size.
-
keyout: gives the filename to write the newly created private key to.
-
out: specifies the output filename to write to or standard output by default.
-
days: when the -x509 option is being used this specifies the number of days to certify the certificate for (default is 30 days).
Below is the output of the executed openssl generation command:
$ sudo openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
Password:
Generating a 4096 bit RSA private key
..................................................................................................................................................++
................................................................................................++
writing new private key to 'key.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
Country Name (2 letter code) [AU]:UK
State or Province Name (full name) [Some-State]:London
Locality Name (eg, city) []:London
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Neo4j
Organizational Unit Name (eg, section) []:CS
Common Name (e.g. server FQDN or YOUR name) []:CS
Email Address []:myemail@email.com
The below commands then generate the public.crt
and private.key
files, using the .pem files created above:
$ sudo openssl x509 -outform pem -in cert.pem -out public.crt
$ openssl rsa -in key.pem -out private.key
DEPLOYING THE SSL CERTIFICATE AND KEY
Place the above created private.key
and public.crt
in $NEO4J_HOME/certificates/cluster
. Then place public.crt
in $NEO4J_HOME/certificates/cluster/trusted:
certificates
└── cluster
├── private.key
├── public.crt
├── revoked
└── trusted
└── public.crt
Then add the following to neo4j.conf of each instance in the cluster, making sure to replace [Absolute_Path_Of_$NEO4J_HOME]
appropriately:
dbms.ssl.policy.cluster.enabled=true
dbms.ssl.policy.cluster.base_directory=<<Absolute_Path_Of_$NEO4J_HOME>>/certificates/cluster
dbms.ssl.policy.default.base_directory=<<Absolute_Path_Of_$NEO4J_HOME>>/certificates/cluster
dbms.ssl.policy.default.trusted_dir=<<Absolute_Path_Of_$NEO4J_HOME>>/certificates/cluster/trusted
dbms.ssl.policy.default.revoked_dir=<<Absolute_Path_Of_$NEO4J_HOME>>/certificates/cluster/revoked
dbms.ssl.policy.cluster.ciphers=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
dbms.ssl.policy.cluster.client_auth=REQUIRE
Validate the Intra-cluster Encryption
We’re now ready to initialise all cluster instances. Once these are initialised and available, we can then verify our SSL encryption by using the nmap tool (sometimes deployed alongside openssl otherwise it will need to be installed separately), to check the available SSL ciphers as below:
$ nmap --script ssl-enum-ciphers -p 5000 localhost
Starting Nmap 7.80 ( https://nmap.org ) at 2022-07-07 14:18 UTC
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000049s latency).
Other addresses for localhost (not scanned): ::1
PORT STATE SERVICE
5000/tcp open upnp
| ssl-enum-ciphers:
| TLSv1.2:
| ciphers:
| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (secp256r1) - A
| compressors:
| NULL
| cipher preference: indeterminate
| cipher preference error: Too few ciphers supported
| warnings:
| Key exchange (secp256r1) of lower strength than certificate key
|_ least strength: A
Nmap done: 1 IP address (1 host up) scanned in 0.31 seconds
Where port 5000
is the default Causal Cluster Discovery Management. The above configuration will also enable SSL on port 6000
and 7000
which are Causal Cluster Transaction and Causal Cluster RAFT ports respectively. Details on Neo4j port usages can be found on the following link:
An additional confirmation would be to find debug messages similar to the following, in the Neo4j debug.log:
2022-07-08 09:30:28.006+0000 INFO [o.n.s.c.SslPolicyLoader] Loaded SSL policy 'CLUSTER' = SslPolicy{keyCertChain=Subject: EMAILADDRESS=myemail@email.com, CN=neo4j.local, OU=Support, O=Neo4j, L=London, ST=London, C=UK, Issuer: EMAILADDRESS=myemail@email.com, CN=neo4j.local, OU=Support, O=Neo4j, L=London, ST=London, C=UK, ciphers=[TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384], tlsVersions=[TLSv1.2], clientAuth=REQUIRE}
References:
Is this page helpful?