4

I'm trying to set up Neo4j with TLS enabled for the Bolt Communication on CentOS7. The server is currently installed as a system service. I have generated a self-signed certificate and key:

sudo openssl genrsa -des3 -out /var/ssl/ca.key 4096``
sudo openssl req -new -x509 -days 365 -key /var/ssl/ca.key -out /var/ssl/ca.crt
sudo openssl genrsa -des3 -out /var/ssl/neo4j/serv.key 1024``
sudo openssl req -new -key /var/ssl/neo4j/serv.key -out /var/ssl/neo4j/server.csr
sudo openssl x509 -req -days 365 -in /var/ssl/neo4j/server.csr -CA /var/ssl/ca.crt -CAkey /var/ssl/ca.key -set_serial 01 -out /var/ssl/neo4j/server.crt
sudo openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in /var/ssl/neo4j/serv.key -out /var/ssl/neo4j/server.key

Then, I copied the server.crt file into /var/ssl/trusted/neo4j (per Neo4j documentation) and added the following lines to my neo4j.conf:

dbms.ssl.policy.default.trusted_dir=/var/ssl/trusted/neo4j
dbms.ssl.policy.default.public_certificate=/var/ssl/neo4j/server.crt
dbms.ssl.policy.default.private_key=/var/ssl/neo4j/server.key
dbms.ssl.policy.default.base_directory=/var/ssl/neo4j/
dbms.connector.bolt.enabled=true
dbms.connector.bolt.tls_level=REQUIRED

Finally, I added the ca.crt file to my system trusted certificate chain:

sudo cp /var/ssl/ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust

and re-started the server, which comes up correctly. However, I see the following error when trying to connect to the server with the Python client:

neo4j.exceptions.SecurityError: Failed to establish secure connection to '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:600)'

Python code which yields the error:

from neo4j.v1 import GraphDatabase
from neo4j.v1 import TRUST_SYSTEM_CA_SIGNED_CERTIFICATES
uri = "bolt://localhost:7687"
driver = GraphDatabase.driver(uri, auth=("neo4j", "neo4j"), trust=TRUST_SYSTEM_CA_SIGNED_CERTIFICATES)

The CA Certificate should be added to my system trust chain, and other applications appear to be able to use it, however it appears as though the Neo4j client is unable to utilize it to verify the certificate returned from the server. Does Neo4j only use this CA for the HTTPS endpoint, and not the TLS endpoint? If so, how can I get the CA certificate for the Bolt endpoint into my system's trust chain?

Alex Barry
  • 415
  • 1
  • 9
  • 21

3 Answers3

0

Apparently Neo4j generates separate certificates if they are not already present for the Bolt connection, and they are separate from the HTTPS endpoint certificate configurations.

My certificates were generated into /var/lib/neo4j/certificates/ with the names 'neo4j.cert' and 'neo4j.key'. When I copied the server certificate and key signed by my trusted CA into these folders prior to starting the Neo4j server, it used them to secure the Bolt endpoint and I was able to connect with the secured Python client.

Alex Barry
  • 415
  • 1
  • 9
  • 21
0

I've had a similar problem and for me setting encrypted=False did the trick:

driver = GraphDatabase.driver("bolt://localhost", auth=("neo4j", ""), encrypted=False)

source: https://github.com/neo4j/neo4j/issues/12392#issuecomment-583899597

tschomacker
  • 631
  • 10
  • 18
0

Since Neo4j version 4 the Python driver implements a new set of connection protocols.

  • neo4j+s://: Neo4jDriver with encryption (accepts only certificates signed by a certificate authority), full certificate checks.
  • neo4j+ssc://: Neo4jDriver with encryption (accepts self signed certificates).
  • neo4j://: Neo4jDriver with no encryption.

So you can use the following to allow self-signed certificates. As always, note that this is insecure, so do not use in production!

uri = "neo4j+scc://localhost:7687"
driver = GraphDatabase.driver(uri, auth=("neo4j", "neo4j"))

You also have the option of doing the same with bolt, but neo4j is preferred since it will work on both a cluster (with routing) and a standalone single instance server.

jonatan
  • 9,011
  • 2
  • 30
  • 34