[Python] Why does Neo4j connect over TLS using bolt:// when tls_level=REQUIRED?

Discussão em 'Python' iniciado por Stack, Agosto 17, 2025.

  1. Stack

    Stack Membro Participativo

    Neo4j Community is running on an Ubuntu Server in a virtual private network on Azure. The default HTTP for both its browser and bolt are disabled in favour of HTTPS and WSS (through self-signed certificates).

    1. The browser is being proxied with NGINX and has the following configuration:

    server.http.enabled=false
    server.https.enabled=true

    dbms.ssl.policy.https.enabled=true
    dbms.ssl.policy.https.base_directory=certificates/https
    dbms.ssl.policy.https.private_key=sub.domain.key
    dbms.ssl.policy.https.public_certificate=sub.domain.pem
    dbms.ssl.policy.https.client_auth=NONE

    1. Bolt is exposed on port 7687 with the following configuration:

    server.bolt.enabled=true
    server.bolt.tls_level=REQUIRED

    dbms.ssl.policy.bolt.enabled=true
    dbms.ssl.policy.bolt.base_directory=certificates/bolt
    dbms.ssl.policy.bolt.private_key=sub.domain.key
    dbms.ssl.policy.bolt.public_certificate=sub.domain.pem
    dbms.ssl.policy.bolt.client_auth=NONE


    Visiting https://sub.domain.com/neo4j in a browser succeeds and displays bolt+s://sub.domain.com:7687 as the connection to bolt. See Neo4j Python Driver for the URI schemes.

    Connecting to bolt+s://sub.domain.com:7687 using the Python SDK as follows doesn't work and results in a SSLCertVerificationError:

    self.__driver = AsyncGraphDatabase.driver(
    f"bolt+s://{settings.host}:{settings.port}",
    auth=(settings.username, settings.password)
    )


    But connecting to bolt://sub.domain.com:7687 using the same SDK does:

    self.__driver = AsyncGraphDatabase.driver(
    f"bolt://{settings.host}:{settings.port}",
    auth=(settings.username, settings.password),
    trusted_certificates=TrustSystemCAs()
    )


    Does the connection succeed because server.bolt.tls_level=REQUIRED forces the driver to upgrade the connection? i.e., Is it safe to assume that the successful connection being made is over TLS?

    N.B. Connecting to bolt+ssc://sub.domain.com:7687 using the same SDK works but isn't suitable for production:

    self.__driver = AsyncGraphDatabase.driver(
    f"bolt+ssc://{settings.host}:{settings.port}",
    auth=(settings.username, settings.password)
    )

    Continue reading...

Compartilhe esta Página