PostgeSQL require SSL mode in Neon?

That is my first question (the subject).

I’m creating a simple rest api in rust language + actix-web + tokio-postgres and I’m using NoTLS. I know for production, the SSL requirement is great, but for dev and testing I can live without SSL. Is there a way I can bypass it?

Here’s my code in rust.

    let (client, connection) = tokio_postgres::connect(config, NoTls).await.unwrap();
    tokio::spawn(async move {
        if let Err(e) = connection.await {
            eprintln!("error: {}", e);
        }
    });

The config is the DATABASE_URL=
Since I’m not using TLS, I can’t append ?sslmode=require in the Neon database url.

Thanks in advance.

Hi! There’s no way to bypass it, because the Neon proxy that accepts the connection depends on the TLS SNI (Server Name Indication) feature to identify which project to connect to. That requirement could perhaps be relaxed if you use other workarounds to provide the project name, but it’s good security practice to always use TLS over the public Internet anyway.

Enabling TLS with Rust tokio-postgres crate requires an extra dependency for a TLS implementation and a few lines of extra configuration to glue it together. I just opened a PR to add a test program to our client test suite. It’s a self-contained example on how to do that.

1 Like

Thanks @heikki for confirming! An example of Rust tokio-progres will be super helpful. I will wait for it.

Oh almost missed that! I quickly realized I can actually see your PR. That was really helpful.
Thank you so much!

Now I can deploy my rust up in Cloud Run successfully and it is running. But now I’m getting a different error “connection refused”. Here is the full details of the error.

2023/03/06 00:21:42 [error] 6#6: *9 connect() failed (111: Connection refused) while connecting to upstream, client: 169.254.1.1, server: localhost, request: “GET /api/healthcheck HTTP/1.1”, upstream: “http://127.0.0.1:8080/api/healthcheck”, host: “general-ledger-api-zrl7fwpoha-an.a.run.app”

To give more context. My rust application is deployed as docker container. It has nginx proxy server in it, so that my rust app is running in container port 8080, and my nginx is listening on port 80 forwarding request to 8080.

nginx.conf

  server {
    listen 80;
    server_name localhost;
    location / {
      proxy_pass http://127.0.0.1:8080;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
  }

UPDATE: I think I’m missing information. I enabled RUST tracing and this error shows when the application starts. It looks like I need to provide SSL cert?

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error { kind: Tls, cause: Some(Ssl(Error { code: ErrorCode(1), cause: Some(Ssl(ErrorStack([Error { code: 337047686, library: "SSL routines", function: "tls_process_server_certificate", reason: "certificate verify failed", file: "../ssl/statem/statem_clnt.c", line: 1916 }]))) }, X509VerifyResult { code: 20, error: "unable to get local issuer certificate" })) }', src/main.rs:24:85

Here’s my current main.rs, I provided the env var DATABASE_URL correctly.

    let config = &env::var("DATABASE_URL").unwrap_or_else(|_| {
        "postgres://postgres:password@localhost:5432/my-app-db".to_owned()
    });
    // Use the native TLS implementation (Neon requires TLS)
    let tls_connector =
        postgres_native_tls::MakeTlsConnector::new(native_tls::TlsConnector::new().unwrap());
    let (client, connection) = tokio_postgres::connect(config, tls_connector).await.unwrap();
    tokio::spawn(async move {
        if let Err(e) = connection.await {
            eprintln!("error: {}", e);
        }
    });

Yeah, looks like a problem looking up the root certificate. Neon uses certificates issued by Let’s Encrypt, whose root certificates are present in all modern distributions, but perhaps the docker image you’re using doesn’t include a certificate store, or it’s misconfigured. You could probably work around it by disabling certificate validation (see https://docs.rs/native-tls/latest/native_tls/struct.TlsConnectorBuilder.html#method.danger_accept_invalid_hostnames), but I would recommend fixing or installing the root certificate store instead.