Closed IndigoCurnick closed 8 months ago
Can you provide literally any detail more specific than "no longer works"?
Ah yes I forgot to include the error!
Tokio postgres is not connecting: Error { kind: Db, cause: Some(DbError { severity: "FATAL", parsed_severity: Some(Fatal), code: SqlState(E28000), message: "no pg_hba.conf entry for host, user \"postgres\", database \"postgres\", no encryption", detail: None, hint: None, position: None, where_: None, schema: None, table: None, column: None, datatype: None, constraint: None, file: Some("auth.c"), line: Some(542), routine: Some("ClientAuthentication") }) }
It sounds like your database now requires that you connect with TLS. You'll need to replace the NoTls
with a TLS implementation like postgres-openssl, postgres-native-tls, or tokio-postgres-rustls.
Could you elaborate on how to do this? I managed to get this compiling where I created a TlsConnector
, using certificates from here
let bytes = fs::read("rds-ca-2029-root.pem").unwrap();
let cert = Certificate::from_pem(&bytes).unwrap();
let connector = TlsConnector::builder()
.add_root_certificate(cert)
.build()
.unwrap();
let connector = MakeTlsConnector::new(connector);
But I get a certificate verify failed
error
Is that the entire text of the error message?
Unfortunately yes, here's the full error output
Tokio postgres is not connecting: Error { kind: Tls, cause: Some(Ssl(Error { code: ErrorCode(1), cause: Some(Ssl(ErrorStack([Error { code: 167772294, library: "SSL routines", function: "tls_post_process_server_certificate", reason: "certificate verify failed", file: "ssl/statem/statem_clnt.c", line: 2091 }]))) }, X509VerifyResult { code: 19, error: "self-signed certificate in certificate chain" })) }
Curiously, trying to connect with Python and this works fine
con = psycopg2.connect(
host=HOST,
user=USER,
password=PASSWORD,
port=5432
)
So now I'm not sure at all what the issue might be
There is definitely more text there than certificate verify failed
.
Does rds-ca-2029-root.pem contain more thatn one certificate? Certificate::from_pem
will only load the first.
psycopg2 doesn't verify certificates by default IIRC.
Here's the entire error
Tokio postgres is not connecting: Error { kind: Tls, cause: Some(Ssl(Error { code: ErrorCode(1), cause: Some(Ssl(ErrorStack([Error { code: 167772294, library: "SSL routines", function: "tls_post_process_server_certificate", reason: "certificate verify failed", file: "ssl/statem/statem_clnt.c", line: 2091 }]))) }, X509VerifyResult { code: 19, error: "self-signed certificate in certificate chain" })) }
I see - it does contain more than one certificate. Is there a convenient way to parse all of them into Vec? If not I can write something to do that. Is there a way to make the tokio-postgres behave like psycopg2 like it used to?
If you use postgres-openssl you can just give it the path to the certs file with set_ca_file
.
tokio-postgres never behaved like psycopg2. Your database used to not require TLS to login.
pub async fn get_pg_client_with_tls(
pg_uri: String,
pg_username: String,
pg_password: String,
pg_db_name: String,
) -> Result<RdsClient, String> {
let pg_connection_str = format!(
"host={} user={} password={} dbname={} sslmode=require",
pg_uri, pg_username, pg_password, pg_db_name
);
let bytes = PEM.as_bytes();
let mut buf = BufReader::new(bytes);
let mut root_store = RootCertStore::empty();
let _no =
root_store.add_parsable_certificates(rustls_pemfile::certs(&mut buf).map(|r| r.unwrap()));
let config = rustls::ClientConfig::builder()
.with_root_certificates(root_store)
.with_no_client_auth();
let tls = MakeRustlsConnect::new(config);
let (client, connection) = tokio_postgres::connect(&pg_connection_str, tls)
.await
.unwrap();
let _connection_handle = tokio::spawn(async move {
if let Err(e) = connection.await {
error!("connection error: {}", e);
panic!("No postgres connection");
}
});
return Ok(client);
}
I was eventually able to piece this function together. I think some more documentation on TLS might be helpful as this was a little hard to figure out - and in the end it required me to find four new crates for dealing with it. I'm not sure if there was an easier way to do it
I use this crate to connect to Postgres in AWS. In Postgres 14 I connected like so
With no issues. However, we recently updated to Postgres 16 and this no longer works. I tried following this article but to no avail, by downloading and using pem files from here
However, I can still connect to the database just fine using software like PgAdmin (though, that is through a bastion using AWS SSM - not sure what they are doing).
Any help would be greatly appreciated! I'm thinking this is some kind of SSL/TLS issue but not sure how to resolve it