brianc / node-postgres

PostgreSQL client for node.js.
https://node-postgres.com
MIT License
12.33k stars 1.23k forks source link

Connecting to database with SSL on Cloudflare #3144

Open krakz999 opened 9 months ago

krakz999 commented 9 months ago

Hi,

Thanks for this library. We are using Cloudflare Workers and trying to connect to a database that requires SSL. The application crashes with "Error: Connection terminated unexpectedly".

Is there a way to connect to a db with SSL from CF using this library?

colegottdank commented 7 months ago

Running into the same problem.

krakz999 commented 7 months ago

Running into the same problem.

You will have to use Hyperdrive.

brianc commented 7 months ago

@krakz999 could you elaborate a bit? I don't have much experience with hyperdrive (yet) and would like to be able to respond better to CF related issues. 🙏

colegottdank commented 7 months ago

@brianc, I just got it to work using Hyperdrive: https://developers.cloudflare.com/hyperdrive/

You just create a new Hyperdrive in Cloudflare. Bind it to the worker

[[env.production.hyperdrive]]
binding = "HYPERDRIVE"
id = ""
localConnectionString = "postgresql://postgres:postgres@localhost:54322/postgres"

You can then access in worker as ENV

HYPERDRIVE: Hyperdrive;

Then new up a pg client like this:

this.client = new Client({
      host: env.HYPERDRIVE.host,
      user: env.HYPERDRIVE.user,
      password: env.HYPERDRIVE.password,
      port: Number(env.HYPERDRIVE.port),
      database: env.HYPERDRIVE.database,
    });

It does not require setting the ssl certs.

colegottdank commented 7 months ago

"By maintaining a connection pool to your database within Cloudflare’s network, Hyperdrive reduces seven round-trips to your database before you can even send a query: the TCP handshake (1x), TLS negotiation (3x), and database authentication (3x)."

So, I am connecting to Hyperdrive in my worker essentially:

Screenshot 2024-04-09 at 10 43 59 PM
brianc commented 7 months ago

This is an awesome writeup - I'll write a documentation page about it (linking back to this issue w/ credits) once I'm back from vacation. Thank you so much! I assume this is safe to close at this point?

Daniel-Ash commented 7 months ago

Thought I'd share some context from my own experience here in case it helps anyone else!

I experienced this issue as well connecting to Supabase from a Cloudflare Worker using Kysely with the PG driver - providing any SSL config prevented connections both direct to the DB and via the Supabase pooler. (I've been in touch with Supabase support regarding this but so far haven't gleaned any insights into the issue there).

Hyperdrive works, however if I do try to provide SSL config to a Hyperdrive connection (see screenshot) then it fails - Error: The server does not support SSL connections.

image

I was concerned about connecting with an error message like that, but you can run the following query on your PG connection to verify that you have an SSL connection.

SELECT * FROM pg_stat_ssl WHERE pid = pg_backend_pid();

So basically, it seems like you must not provide any SSL config if you want an SSL connection 🤣🫡

colegottdank commented 7 months ago

@Daniel-Ash, hi yes, from my understanding Hyperdrive maintains an open TLS connection to the Postgres DB. So, you don't need SSL to connect to Hyperdrive as Hyperdrive is already connected to your DB using TLS.

anirudhsama commented 4 months ago

This is an awesome writeup - I'll write a documentation page about it (linking back to this issue w/ credits) once I'm back from vacation. Thank you so much! I assume this is safe to close at this point?

Yes, using Hyperdrive does solve the issue since the worker doesn't use SSL to connect to it, but we should still be able to directly connect to a DB that uses SSL.

zerokarafont commented 2 months ago

hyperdrive is dude! i tried everything to connect pg at digital ocean vps and got failed in cloudflare workers runtime, finally work with hyperdrive. however, hyperdrive local simulation still fail so i have to use local pg connectionString .