Open 9876691 opened 1 year ago
I think I've figured out how SQLx do this.
They set a variable like so
let accept_invalid_certs = !matches!(
options.ssl_mode,
PgSslMode::VerifyCa | PgSslMode::VerifyFull
);
https://github.com/launchbadge/sqlx/blob/main/sqlx-postgres/src/connection/tls.rs#L50
Now when they connect via this code https://github.com/launchbadge/sqlx/blob/main/sqlx-core/src/net/tls/tls_rustls.rs#L99
let config = if tls_config.accept_invalid_certs {
if let Some(user_auth) = user_auth {
config
.with_custom_certificate_verifier(Arc::new(DummyTlsVerifier))
.with_single_cert(user_auth.0, user_auth.1)
.map_err(Error::tls)?
} else {
config
.with_custom_certificate_verifier(Arc::new(DummyTlsVerifier))
.with_no_client_auth()
}
}
They basically ignore the certificates and that's why it works on all the cloud providers.
So I guess cornucopia needs something like this, to stop people searching for a TLS solution.
use std::str::FromStr;
use std::sync::Arc;
pub fn create_pool(database_url: &str) -> deadpool_postgres::Pool {
let config = tokio_postgres::Config::from_str(database_url).unwrap();
let manager = if database_url.contains("sslmode=require") {
let tls_config = rustls::ClientConfig::builder()
.with_safe_defaults()
.with_custom_certificate_verifier(Arc::new(DummyTlsVerifier))
.with_no_client_auth();
let tls = tokio_postgres_rustls::MakeRustlsConnect::new(tls_config);
deadpool_postgres::Manager::new(config, tls)
} else {
deadpool_postgres::Manager::new(config, tokio_postgres::NoTls)
};
deadpool_postgres::Pool::builder(manager).build().unwrap()
}
struct DummyTlsVerifier;
impl ServerCertVerifier for DummyTlsVerifier {
fn verify_server_cert(
&self,
_end_entity: &rustls::Certificate,
_intermediates: &[rustls::Certificate],
_server_name: &ServerName,
_scts: &mut dyn Iterator<Item = &[u8]>,
_ocsp_response: &[u8],
_now: SystemTime,
) -> Result<ServerCertVerified, rustls::Error> {
Ok(ServerCertVerified::assertion())
}
}
When using a cloud provider you always need TLS. That's a good thing.
All the examples for cornucopia use NoTLS, that's OK. All the examples for deadpool use NoTLS. https://github.com/bikeshedder/deadpool/tree/master/examples
OK. So I managed to get TLS working with Azure Postgres and it looks like this.
However it doesn't work with Digital Ocean.
This guy has written a blog post on getting deadpool to work with TLS https://medium.com/ecliptical-software-inc/a-curious-tale-of-rust-tls-and-postgres-in-the-cloud-969a4d2bea9
I can't get that to compile.
Solution
Get a working
create_pool
function and add it to cornucopia client, so we can all use it.If someone has working code for Postgres on Digital Ocean please let me know.
Prior Art
SQLx works with all providers I've tried with no special code.
Thanks.