Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more SSL options to Config #768

Open
uce opened this issue May 11, 2021 · 6 comments
Open

Add more SSL options to Config #768

uce opened this issue May 11, 2021 · 6 comments

Comments

@uce
Copy link

uce commented May 11, 2021

I was wondering whether you would be open to extending Config as follows:

  • Add variants VerifyCa and VerifyFull to SslMode
  • Add options sslcert, sslkey, sslrootcert

For context: We allow users to specify a connection string that we then pass directly to the client and we would like it to behave in a similar way as psql. We currently have to provide the above options "out-of-band".

I would understand if this is rejected since it does not affect the client directly, but only how to configure TLS support (which is the responsibility of the client user and not the client in the current design).

If you don't have any concerns with this, feel free to assign it to me.

cc @sfackler

@sfackler
Copy link
Owner

How would those options actually be consumed?

@uce
Copy link
Author

uce commented May 12, 2021

@sfackler Thanks for asking! The sslcert, sslkey, sslrootcert options will actually have to stay "out-of-band" for us, so I'll ignore those (and update the ticket description).

The goal would be to mimic psql behaviour by configuring the SslConnector accordingly. For instance, we currently disable cert verification, because that's how psql behaves:

let mut builder = SslConnector::builder(SslMethod::tls_client())?;
// Currently supported sslmodes (disable, prefer, require) don't verify peer certificates
builder.set_verify(SslVerifyMode::NONE);
Ok(MakeTlsConnector::new(builder.build()))

If we had the additional modes verify-ca and verify-full, we would use those to decide when to enable cert verification. Within rust-postgres, the new modes would behave like require.

What do you think?

@sfackler
Copy link
Owner

But there is no interface to pass that configuration down to the TLS implementation currently.

@nyurik
Copy link
Contributor

nyurik commented Feb 3, 2023

I was trying to implement same ssl options as available in psql, e.g. verify-full. Is there a path forward with this issue? It seems the issues with #774 were never resolved.

Ideally rust-postgres would handle TLS internally - via rustls by default, or for backward compatibility -- via openssl (feature flags), but at the moment the structure of the lib seems to delegate all TLS configuration to the user, which creates multiple fairly complex and sometimes buggy implementations.

@nyurik
Copy link
Contributor

nyurik commented Feb 4, 2023

I did another, much simpler take on solving this in #988, hopefully this is more palatable to everyone, while it will unblock all those who want to use this functionality.

nyurik added a commit to maplibre/martin that referenced this issue Feb 6, 2023
This is a partial fix for #496

* BREAKING: Now Martin behaves the same way as `psql` -- by default, if
SSL is available on the server, it will be used, even though it will not
verify that the server has a valid SSL certificate
* Martin now understands `PGSSLCERT`, `PGSSLKEY`, and `PGSSLROOTCERT`
env vars (and corresponding config keys) - same as psql.
* Martin can now process `?sslmode=verify-ca` and `verify-full` (just
like psql). The verify modes require root and/or client cert & key.
* remove `danger_accept_invalid_certs` -- turns out that behavior is
expected by default unless ssl mode is set to verify - which upstream
lib [does not
support](sfackler/rust-postgres#768) - PR
[submitted](sfackler/rust-postgres#988).
* added connection_timeout_ms option for postgres and set it to 5
seconds by default. This way it will fail out earlier.
* added error reporting to bb8 - but it is currently [broken
upstream](djc/bb8#151) - not sure we can fix
it easily, so may need to switch to deadpool later.
* added docker-based TLS test (horray!) - wasn't trivial at all, despite
ending up fairly simple.
@WGH-
Copy link

WGH- commented Nov 7, 2023

If we wish to do it the same way as libpq and other libraries do - well I think we do - then in my opinion we should change MakeTlsConnect trait to something roughly like this:

pub trait MakeTlsConnect<S> {
    type Stream: TlsStream + Unpin;
    type TlsConnect: TlsConnect<S, Stream = Self::Stream>;
    type Error: Into<Box<dyn Error + Sync + Send>>;

    // Required method
    fn make_tls_connect(
        &mut self,
        cfg &tokio_postgres::Config,
        domain: &str
    ) -> Result<Self::TlsConnect, Self::Error>;
}

libpq connection strings specify whether TLS is desired/required, where CA lies, what client certificate to use, etc. So we can't really build a connector without the config/connection string.

This would be a breaking change, but I don't see a way to do this without changing the trait.

If this change looks OK, I can try to make a PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants