You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It seems practically every user of the postgres lib is struggling with support sslmode=require|verify-ca|verifu-full per pg ssl docs. I believe this requires these new features, and this lib is probably the best place to add them to because they are mostly postgres specific, and because rustls doesn't want them :(
improve connection string parsing to detect sslmode parameter.
provide a way to skip certificate validation
provide a way to skip host validation
The overall expected behavior for sslmode:
let(verify_ca, verify_hostname) = match ssl_mode {SslMode::Disable | SslMode::Prefer => (false,false),SslMode::Require => match pg_certs.ssl_root_cert{// If a root CA file exists, the behavior of sslmode=require will be the same as// that of verify-ca, meaning the server certificate is validated against the CA.// For more details, check out the note about backwards compatibility in// https://postgresql.org/docs/current/libpq-ssl.html#LIBQ-SSL-CERTIFICATES// See also notes in// https://github.com/sfu-db/connector-x/blob/b26f3b73714259dc55010f2233e663b64d24f1b1/connectorx/src/sources/postgres/connection.rs#L25Some(_) => (true,false),None => (false,false),// no root CA file, so no verification},SslMode::VerifyCa => (true,false),SslMode::VerifyFull => (true,true),};
If verify_ca is false, then we need to provide a way to skip certificate validation. If verify_hostname is false, then we need to provide a way to skip hostname validation.
sslmode parsing
This code works around a current limitation in the postgres SSL parsing, which really should be fixed in sfackler/rust-postgres#988 -- basically the rust-postgres lib should support the additional verify-ca and verify-full values, but without that patch, we can use regex to replace them with required in the connection string. See example in my code
#[derive(Debug,Clone,Copy,PartialEq,Eq)]pubenumSslModeOverride{Unmodified(SslMode),VerifyCa,VerifyFull,}/// Special treatment for sslmode=verify-ca & sslmode=verify-full - if found, replace them with sslmode=requirepubfnparse_conn_str(conn_str:&str) -> Result<(Config,SslModeOverride)>{letmut mode = SslModeOverride::Unmodified(SslMode::Disable);let exp = r"(?P<before>(^|\?|&| )sslmode=)(?P<mode>verify-(ca|full))(?P<after>$|&| )";let re = Regex::new(exp).unwrap();let pg_cfg = ifletSome(captures) = re.captures(conn_str){let captured_value = &captures["mode"];
mode = match captured_value {"verify-ca" => SslModeOverride::VerifyCa,"verify-full" => SslModeOverride::VerifyFull,
_ => unreachable!(),};let conn_str = re.replace(conn_str,"${before}require${after}");Config::from_str(conn_str.as_ref())}else{Config::from_str(conn_str)};let pg_cfg = pg_cfg.map_err(|e| BadConnectionString(e, conn_str.to_string()))?;ifletSslModeOverride::Unmodified(_) = mode {
mode = SslModeOverride::Unmodified(pg_cfg.get_ssl_mode());}Ok((pg_cfg, mode))}
enable ssl but ignore cert verification
In OpenSSL, we can use builder.set_verify(SslVerifyMode::NONE), but unfortunately rustls doesn't want to allow this, hence this workaround. See example usage from maplibre/martin#474 pull request.
if !verify_hostname {
connector.set_callback(|cfg, _domain| {
cfg.set_verify_hostname(false);
Ok(())
});
}
but there is no similar API for rustls. There are some examples in the rustls/rustls#578 issue, but rustls seems not to want to implement/maintain it, so we need a workaround.
The text was updated successfully, but these errors were encountered:
It would indeed be an improvement if you could just set sslmode in the connection string rather than needing to set up the ClientConfig manually with an appropriate verifier for the desired behaviour. The problem is that the tokio-postgres API doesn't provide any information about the sslmode to the MakeTlsConnect / TlsConnect impls, so the TLS connector has no knowledge of the sslmode defined in the connection string.
If tokio-postgres was to extend the API with this information somehow, it would be possible to have automatic handling of the sslmodes in this crate. (ref sfackler/rust-postgres#988 (comment))
We could also possibly add a convenience method alongside new(config: ClientConfig), which takes an SSL mode and sets up the ClientConfig automatically for the desired mode. This however has the problem of potential confusion if a different SSL mode is passed to tokio-postgres-rustls here than is provided in the connection string.
If tokio-postgres plans to eventually pass the SSL mode through, I would be inclined to wait for that, and in the meantime just add examples to the documentation regarding how to set up ClientConfig for each mode.
It seems practically every user of the postgres lib is struggling with support
sslmode=require|verify-ca|verifu-full
per pg ssl docs. I believe this requires these new features, and this lib is probably the best place to add them to because they are mostly postgres specific, and because rustls doesn't want them :(sslmode
parameter.The overall expected behavior for sslmode:
If
verify_ca
isfalse
, then we need to provide a way to skip certificate validation. Ifverify_hostname
isfalse
, then we need to provide a way to skip hostname validation.sslmode
parsingThis code works around a current limitation in the postgres SSL parsing, which really should be fixed in sfackler/rust-postgres#988 -- basically the rust-postgres lib should support the additional
verify-ca
andverify-full
values, but without that patch, we can use regex to replace them withrequired
in the connection string. See example in my codeenable ssl but ignore cert verification
In OpenSSL, we can use
builder.set_verify(SslVerifyMode::NONE)
, but unfortunately rustls doesn't want to allow this, hence this workaround. See example usage from maplibre/martin#474 pull request.allow connections without hostname validation
OpenSSL supports this code:
but there is no similar API for rustls. There are some examples in the rustls/rustls#578 issue, but rustls seems not to want to implement/maintain it, so we need a workaround.
The text was updated successfully, but these errors were encountered: