Allow connections on public and private network interfaces

Hi there!

I'm trying to get my neo4j instance installed on a VM where the public IP is accessible only over TLS, but also accessible over a private VPC. I've followed the great instructions here for setting up Let's Encrypt. I have no problem connecting to my DB instance via https via the public domain (e.g. https://graph.mydomain.com). I also have no problem using cypher-shell against the public neo4j+s address (e.g. neo4j+s://graph.mydomain.com).

This is where the problem starts though. When I try connecting from the instance to itself, or from another VM on the same VPC, I get the following error:

# From another VM on the same VPC:
➜  ~ cypher-shell -a neo4j+s://10.116.0.3:7687
Failed to establish secured connection with the server

# From the instance running neo4j:
➜  ~ cypher-shell -a neo4j+s://localhost:7687
Failed to establish secured connection with the server

Per the instructions, found here, with a 0.0.0.0 default listening address, this should bind to all interfaces.

My config looks like:

dbms.default_listen_address=0.0.0.0
dbms.default_advertised_address=graph.mydomain.com

dbms.connector.bolt.enabled=true
dbms.connector.bolt.tls_level=REQUIRED
dbms.connector.bolt.listen_address=:7687

dbms.connector.http.enabled=false

dbms.connector.https.enabled=true
dbms.connector.https.listen_address=:7473

dbms.ssl.policy.bolt.enabled=true
dbms.ssl.policy.bolt.base_directory=certificates/bolt
dbms.ssl.policy.bolt.private_key=neo4j.key
dbms.ssl.policy.bolt.public_certificate=neo4j.cert
dbms.ssl.policy.bolt.client_auth=NONE

dbms.ssl.policy.https.enabled=true
dbms.ssl.policy.https.base_directory=certificates/https
dbms.ssl.policy.https.private_key=neo4j.key
dbms.ssl.policy.https.public_certificate=neo4j.cert
dbms.ssl.policy.https.client_auth=NONE

What am I missing here?

1 Like

Anyone from neo4j who can help here?

Without visibility into the network and security, it's really hard to guess at what's going on. You could turn on more detailed logs, or set up a reverse proxy middleman so you can see all the traffic.

IMO, if I had to guess, it might be that your machines behind the VPC can't connect to the cert authority, or the VPC is rerouting certs (many company networks do that to maintain control over secure traffic).

Both machines have full access to the public web and have public IPs. The VPC is there so I can transfer data, etc, without incurring egress fees on the other machine. Also, I should say that there are no firewalls installed within this environment (well, not yet).

Which logs should I turn on to be more detailed?

I'm still guessing, so you might want to contract someone with devops, or web-server admin, experience. My best guess, is that in following those instructions, you created a cert for the domain-name, not a generic TLS certificate. Such a cert will not work for requests to that machine other than one to the domain-name the cert is for. A simple way to verify this, would be to only connect via that domain-name, even when on local.

  • Your machine must have a valid DNS address in order to have a valid SSL certificate. Certificates typically aren’t granted for bare IP addresses because it’s a lot harder to prove that you own/control a bare IP address.

If that's the case, then you still should be able to connect just fine:

➜  ~ cypher-shell -a --debug true neo4j+s://graph.mydomain.com:7687

(you may need to add an entry to your hosts file: 10.116.0.3 graph.mydomain.com

If that's not the case, and your cert is not locked to the domain-name:

Since you're connecting via cypher-shell, I'd try it with --debug true:

➜  ~ cypher-shell -a --debug true neo4j+s://10.116.0.3:7687

Next, you'll need to test the TLS handshake:

openssl s_client -crlf -connect 10.116.0.3:7687